diff --git a/README.md b/README.md new file mode 100644 index 0000000..486a5b2 --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# SpaceTac, a space tactical RPG + +## Abilities + +There are six ship abilities that can be levelled up : + +- Material +- Energy +- Electronics +- Human +- Time +- Gravity + +## Equipment + +Equipments can be assigned to slots on a ship. + +Slots are categorized by type: + +- Armor (to fortify the hull) +- Shield (to avoid damages) +- Engine (to move and evade) +- Power (to recover action points) +- Weapon (to do damages) +- Utility (for anything else) + +## Loot + +This section describes how random equipment is generated for looting. + +Equipment generation is based on templates. A template defines: + +- Type of slot this equipment fit in (weapon, shield, armor...) +- Base name (e.g. Terminator Missile) +- Acceptable range for each ability's requirement (e.g. material/1/3, gravity/3/8) +- Targetting flags (self, allied, enemy, space) +- Range for distance to target +- Range for effect area's radius +- Range for duration +- List of effects, with efficacity range +- Action Points usage range +- Level requirements range + +Here is an example of template: + +- slot: weapon +- name: Concussion Missile Salvo +- material: 1/3 +- energy: 2/5 +- time: 1/1 +- target: enemy, space +- range: 50/80 +- effect radius: 2/5 +- duration: 1/1 +- damage shield: 50/80 +- damage hull: 20/60 +- action points: 2/4 +- level: 3/6 + +The weaker weapon this template will generate, will be based on lower value for all ranges: + +- material: 1 +- energy: 2 +- time: 1 +- range: 50 +- effect radius: 2 +- duration: 1 +- damage shield: 50 +- damage hull: 20 +- action points: 2 +- level: 3 + +Conversely, the stronger weapon will be based on higher range values. diff --git a/src/scripts/game/Equipment.ts b/src/scripts/game/Equipment.ts new file mode 100644 index 0000000..e292710 --- /dev/null +++ b/src/scripts/game/Equipment.ts @@ -0,0 +1,30 @@ +module SpaceTac.Game { + "use strict"; + + // Piece of equipment to attach in slots + export class Equipment { + // Type of slot this equipment will fit in + slot: SlotType; + + // Equipment name + name: string; + + // Distance to target + distance: number; + + // Effect area's radius + blast: number; + + // Duration + duration: number; + + // Action Points usage + ap_usage: number; + + // Level requirement + min_level: number; + + constructor() { + } + } +} diff --git a/src/scripts/game/LootTemplate.ts b/src/scripts/game/LootTemplate.ts new file mode 100644 index 0000000..13e237b --- /dev/null +++ b/src/scripts/game/LootTemplate.ts @@ -0,0 +1,87 @@ +module SpaceTac.Game { + "use strict"; + + // Range of values + export class Range { + // Minimal value + private min: number; + + // Maximal value + private max: number; + + // Create a range of values + constructor(min: number, max: number) { + this.min = min; + this.max = max; + } + + // Get a proportional value (give 0.0-1.0 value to obtain a value in range) + getProportional(cursor: number) :number { + return (this.max - this.min) * cursor + this.min; + } + } + + // Template used to generate a loot equipment + export class LootTemplate { + // Type of slot this equipment will fit in + slot: SlotType; + + // Base name, lower cased + name: string; + + // Ability requirement ranges + + // Targetting flags + + // Distance to target + distance: Range; + + // Effect area's radius + blast: Range; + + // Duration + duration: Range; + + // Effects + + // Action Points usage + ap_usage: Range; + + // Level requirement + min_level: Range; + + // Create a loot template + constructor(slot: SlotType, name: string) { + this.slot = slot; + this.name = name; + this.distance = new Range(0, 0); + this.blast = new Range(0, 0); + this.duration = new Range(0, 0); + this.ap_usage = new Range(0, 0); + this.min_level = new Range(0, 0); + } + + // Generate a random equipment with this template + generate(): Equipment { + var random = new RandomGenerator(); + var power = random.throw(); + return this.generateFixed(power); + } + + // Generate a fixed-power equipment with this template + generateFixed(power: number): Equipment { + var result = new Equipment(); + + result.slot = this.slot; + result.name = this.name; + + result.distance = Math.floor(this.distance.getProportional(power)); + result.blast = Math.floor(this.blast.getProportional(power)); + result.duration = Math.floor(this.duration.getProportional(power)); + result.ap_usage = Math.floor(this.ap_usage.getProportional(power)); + result.min_level = Math.floor(this.min_level.getProportional(power)); + + return result; + } + } +} diff --git a/src/scripts/game/RandomGenerator.ts b/src/scripts/game/RandomGenerator.ts index 44c9b20..258ed9b 100644 --- a/src/scripts/game/RandomGenerator.ts +++ b/src/scripts/game/RandomGenerator.ts @@ -12,7 +12,7 @@ module SpaceTac.Game { } // Generate a value, based on an attribute level - throw(level: number): number { + throw(level: number = 1): number { if (this.fake_values.length > 0) { return this.fake_values.shift() * level; } else { diff --git a/src/scripts/game/Slot.ts b/src/scripts/game/Slot.ts new file mode 100644 index 0000000..ff6799d --- /dev/null +++ b/src/scripts/game/Slot.ts @@ -0,0 +1,18 @@ +module SpaceTac.Game { + "use strict"; + + export enum SlotType {Armor, Shield, Engine, Power, Weapon, } + + // Slot to attach an equipment to a ship + export class Slot { + // Link to the ship + ship: Ship; + + // Type of slot + type: SlotType; + + // Currently attached equipment + attached: Equipment; + } + +} diff --git a/src/scripts/game/specs/LootTemplate.specs.ts b/src/scripts/game/specs/LootTemplate.specs.ts new file mode 100644 index 0000000..15315c0 --- /dev/null +++ b/src/scripts/game/specs/LootTemplate.specs.ts @@ -0,0 +1,47 @@ +/// + +module SpaceTac.Game.Specs { + "use strict"; + + describe("LootTemplate", () => { + it("interpolates between weak and strong loot", () => { + var template = new LootTemplate(SlotType.Weapon, "Bulletator"); + + template.distance = new Range(1, 3); + template.blast = new Range(1, 1); + template.duration = new Range(1, 2); + template.ap_usage = new Range(4, 12); + template.min_level = new Range(5, 9); + + var equipment = template.generateFixed(0.0); + + expect(equipment.slot).toEqual(SlotType.Weapon); + expect(equipment.name).toEqual("Bulletator"); + expect(equipment.distance).toEqual(1); + expect(equipment.blast).toEqual(1); + expect(equipment.duration).toEqual(1); + expect(equipment.ap_usage).toEqual(4); + expect(equipment.min_level).toEqual(5); + + var equipment = template.generateFixed(1.0); + + expect(equipment.slot).toEqual(SlotType.Weapon); + expect(equipment.name).toEqual("Bulletator"); + expect(equipment.distance).toEqual(3); + expect(equipment.blast).toEqual(1); + expect(equipment.duration).toEqual(2); + expect(equipment.ap_usage).toEqual(12); + expect(equipment.min_level).toEqual(9); + + var equipment = template.generateFixed(0.5); + + expect(equipment.slot).toEqual(SlotType.Weapon); + expect(equipment.name).toEqual("Bulletator"); + expect(equipment.distance).toEqual(2); + expect(equipment.blast).toEqual(1); + expect(equipment.duration).toEqual(1); + expect(equipment.ap_usage).toEqual(8); + expect(equipment.min_level).toEqual(7); + }); + }); +} \ No newline at end of file