Added "Repair Drone" template (WIP)
This commit is contained in:
parent
45a13e9458
commit
1167aedbdf
5
TODO
5
TODO
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
64
src/game/actions/DeployDroneAction.spec.ts
Normal file
64
src/game/actions/DeployDroneAction.spec.ts
Normal 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);
|
||||
});
|
||||
});
|
||||
}
|
29
src/game/actions/DeployDroneAction.ts
Normal file
29
src/game/actions/DeployDroneAction.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
18
src/game/effects/AttributeAddEffect.spec.ts
Normal file
18
src/game/effects/AttributeAddEffect.spec.ts
Normal 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);
|
||||
});
|
||||
});
|
||||
}
|
35
src/game/effects/AttributeAddEffect.ts
Normal file
35
src/game/effects/AttributeAddEffect.ts
Normal 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("_", "");
|
||||
}
|
||||
}
|
||||
}
|
48
src/game/equipments/AbstractDrone.spec.ts
Normal file
48
src/game/equipments/AbstractDrone.spec.ts
Normal 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)]);
|
||||
});
|
||||
});
|
||||
}
|
40
src/game/equipments/AbstractDrone.ts
Normal file
40
src/game/equipments/AbstractDrone.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
10
src/game/equipments/RepairDrone.spec.ts
Normal file
10
src/game/equipments/RepairDrone.spec.ts
Normal 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)]);
|
||||
});
|
||||
});
|
||||
}
|
20
src/game/equipments/RepairDrone.ts
Normal file
20
src/game/equipments/RepairDrone.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue