Created
February 22, 2019 07:34
-
-
Save hellos3b/c450ab269bcb551ff922682d68131b6c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @typedef {import('@/ship/systems/Systems').System} System | |
*/ | |
import { StatsType } from '@/ship/Stats' | |
/** @type {System} */ | |
export const BasicShield = { | |
name: "Basic Shield", | |
id : "basic-shield", | |
layout: [ | |
[{ image: 'tiles', frame: 3 }, { image: 'tiles', frame: 3 }] | |
], | |
buffs: [ | |
{ type: 'add', target: StatsType.SHIELD, val: 100 } | |
] | |
} | |
/** @type {System} */ | |
export const MediumShield = { | |
name: "Medium Shield", | |
id : "med-shield", | |
layout: [ | |
[{ image: 'tiles', frame: 3 }, { image: 'tiles', frame: 3 }], | |
[{ image: 'tiles', frame: 3 }, { image: 'tiles', frame: 3 }] | |
], | |
buffs: [ | |
{ type: 'add', target: StatsType.SHIELD, val: 300 } | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @typedef {import('@/ship/TileBase').TileMapBase} TileMapBase | |
* @typedef {import('@/ship/systems/Systems').System} System | |
* @typedef {import('@/utils/Grid').Cell} Cell | |
*/ | |
import * as TileBase from '@/ship/TileBase' | |
import * as Stats from './Stats' | |
import * as Grid from '@/utils/Grid' | |
export class Ship { | |
/** @type {TileMapBase} */ | |
tileMapBase = null | |
/** @type {Stats.Stats} */ | |
stats = Stats.empty() | |
/** @type {System[]} */ | |
systems = [] | |
/** | |
* @param {Object} config | |
* @param {TileMapBase} config.tileMapBase | |
*/ | |
constructor({ tileMapBase }) { | |
this.tileMapBase = tileMapBase | |
} | |
/** | |
* @param {System} system | |
* @param {Game.Position} position | |
* @returns {Cell[]} Affected cells | |
*/ | |
addSystem(system, position) { | |
this.systems.push(system) | |
const tiles = Grid.from2DArray(system.layout) | |
const area = this.tileMapBase.grid.area(position, tiles.size) | |
area.forEach( cell => { | |
cell.value.ref = system | |
}) | |
this.updateStats() | |
return area | |
} | |
updateStats() { | |
this.stats = Stats.fromSystems(this.systems) | |
} | |
} | |
/** | |
* | |
* @param {object} config | |
* @param {number[][]} config.layout | |
*/ | |
export const fromConfig = config => { | |
const base = TileBase.fromConfig(config.layout) | |
const ship = new Ship({ tileMapBase: base }) | |
return ship | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @typedef {import('@/ship/systems/Systems').System} System | |
* @typedef {import('@/ship/systems/Systems').Buff} Buff | |
*/ | |
import { using } from '@/utils/Value' | |
/** | |
* @readonly | |
* @enum {string} | |
*/ | |
export const StatsType = { | |
HEALTH : "health", | |
SHIELD : "shield" | |
} | |
export class Stat { | |
/** @type {number} */ | |
base = 0 | |
/** @type {number} */ | |
bonus = 0 | |
/** | |
* | |
* @param {number=} base | |
* @param {number=} bonus | |
*/ | |
constructor(base=0, bonus=0) { | |
this.base = base | |
this.bonus = bonus | |
} | |
/** | |
* @param {number} val | |
*/ | |
add(val) { | |
this.base += val | |
} | |
/** | |
* @param {number} val | |
*/ | |
perc(val) { | |
this.bonus += val | |
} | |
/** | |
* @returns {number} | |
*/ | |
val() { | |
return this.base | |
} | |
} | |
export class Stats { | |
/** @type {Map<StatsType,Stat>} */ | |
stats = new Map() | |
/** @type {Buff[]} */ | |
buffs=[] | |
/** | |
* | |
* @param {Map<StatsType,Stat>} stats | |
*/ | |
constructor(stats) { | |
this.stats = stats | |
/** Add getters for each stat */ | |
for (const [key, stat] of stats) { | |
this.defineStatProperty(key, stat) | |
} | |
} | |
/** | |
* Define each stat as a property on the stats object | |
* @private | |
* @param {string} key | |
* @param {Stat} stat | |
*/ | |
defineStatProperty(key, stat) { | |
Object.defineProperty(this, key, { | |
get() { | |
return stat.val() | |
} | |
}) | |
} | |
/** | |
* helper getter to make reading console output much easier | |
*/ | |
get _simple() { | |
const json = {} | |
for (const [key, stat] of this.stats) { | |
json[key] = { | |
val : stat.val(), | |
base : stat.base, | |
bonus : stat.bonus | |
} | |
} | |
return json | |
} | |
} | |
/** | |
* @returns {Stats} | |
*/ | |
export const empty = () => new Stats(baseStats()) | |
/** | |
* @returns {Map<StatsType,Stat>} | |
*/ | |
export const baseStats = () => | |
using(StatsType) | |
.mapKeys(_ => [ | |
StatsType[_], | |
new Stat() | |
]) | |
.apply(_ => new Map(_)) | |
.get() | |
/** | |
* | |
* @param {Buff[]} buffs | |
* @returns {Stats} | |
*/ | |
export const withBuffs = buffs => | |
using(buffs) | |
.apply(_ => calcBuffs(_)) | |
.apply(_ => new Stats(_)) | |
.get() | |
/** | |
* | |
* @param {Buff[]} buffs | |
*/ | |
export const calcBuffs = buffs => { | |
const stats = baseStats() | |
buffs.forEach(buff => { | |
const stat = stats.get(buff.target.toString()) | |
stat[buff.type].call(stat, buff.val) | |
}) | |
return stats | |
} | |
/** | |
* @param {System[]} systems | |
* @returns {Stats} | |
*/ | |
export const fromSystems = systems => | |
using(systems) | |
.map(_ => _.buffs || []) | |
.flatten() | |
.apply(_ => withBuffs(_)) | |
.get() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment