2017-09-24 22:23:22 +00:00
|
|
|
module TK.SpaceTac {
|
2017-03-17 00:07:00 +00:00
|
|
|
/**
|
2018-02-08 15:16:03 +00:00
|
|
|
* Level and experience system for a ship, with enabled upgrades.
|
2017-03-17 00:07:00 +00:00
|
|
|
*/
|
|
|
|
export class ShipLevel {
|
2018-02-08 15:16:03 +00:00
|
|
|
private level = 1
|
|
|
|
private experience = 0
|
|
|
|
private upgrades: string[] = []
|
2017-03-17 00:07:00 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get current level
|
|
|
|
*/
|
|
|
|
get(): number {
|
|
|
|
return this.level;
|
|
|
|
}
|
|
|
|
|
2017-05-09 17:19:26 +00:00
|
|
|
/**
|
|
|
|
* Get the current experience points
|
|
|
|
*/
|
|
|
|
getExperience(): number {
|
|
|
|
return this.experience;
|
|
|
|
}
|
|
|
|
|
2018-02-08 15:16:03 +00:00
|
|
|
/**
|
|
|
|
* Get the activated upgrades
|
|
|
|
*/
|
|
|
|
getUpgrades(): string[] {
|
|
|
|
return acopy(this.upgrades);
|
|
|
|
}
|
|
|
|
|
2017-03-17 00:07:00 +00:00
|
|
|
/**
|
|
|
|
* Get the next experience goal to reach, to gain one level
|
|
|
|
*/
|
|
|
|
getNextGoal(): number {
|
|
|
|
return isum(imap(irange(this.level), i => (i + 1) * 100));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Force experience gain, to reach a given level
|
|
|
|
*/
|
2017-04-18 19:51:23 +00:00
|
|
|
forceLevel(level: number): void {
|
2017-03-17 00:07:00 +00:00
|
|
|
while (this.level < level) {
|
2017-04-18 19:51:23 +00:00
|
|
|
this.forceLevelUp();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Force a level up
|
|
|
|
*/
|
|
|
|
forceLevelUp(): void {
|
|
|
|
let old_level = this.level;
|
|
|
|
|
|
|
|
this.addExperience(this.getNextGoal() - this.experience);
|
|
|
|
this.checkLevelUp();
|
|
|
|
|
|
|
|
if (old_level >= this.level) {
|
|
|
|
// security against infinite loops
|
|
|
|
throw new Error("No effective level up");
|
2017-03-17 00:07:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check for level-up
|
|
|
|
*
|
|
|
|
* Returns true if level changed
|
|
|
|
*/
|
|
|
|
checkLevelUp(): boolean {
|
|
|
|
let changed = false;
|
2017-04-18 19:51:23 +00:00
|
|
|
while (this.experience >= this.getNextGoal()) {
|
2017-03-17 00:07:00 +00:00
|
|
|
this.level++;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add experience points
|
|
|
|
*/
|
2017-04-18 19:51:23 +00:00
|
|
|
addExperience(points: number): void {
|
2017-03-17 00:07:00 +00:00
|
|
|
this.experience += points;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-02-08 15:16:03 +00:00
|
|
|
* Get upgrade points given by current level
|
|
|
|
*
|
|
|
|
* This does not deduce activated upgrades usage
|
2017-03-17 00:07:00 +00:00
|
|
|
*/
|
2018-02-08 15:16:03 +00:00
|
|
|
getUpgradePoints(): number {
|
|
|
|
return this.level > 1 ? (3 * this.level) : 0;
|
2017-03-17 00:07:00 +00:00
|
|
|
}
|
2017-04-18 19:51:23 +00:00
|
|
|
|
|
|
|
/**
|
2018-02-08 15:16:03 +00:00
|
|
|
* (De)Activate an upgrade
|
|
|
|
*
|
|
|
|
* This does not check the upgrade points needed
|
2017-04-18 19:51:23 +00:00
|
|
|
*/
|
2018-03-06 14:39:48 +00:00
|
|
|
activateUpgrade(upgrade: ShipUpgrade, active: boolean): void {
|
2018-02-08 15:16:03 +00:00
|
|
|
if (active) {
|
|
|
|
add(this.upgrades, upgrade.code);
|
|
|
|
} else {
|
|
|
|
remove(this.upgrades, upgrade.code);
|
2017-04-18 19:51:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-02-08 15:16:03 +00:00
|
|
|
* Check if an upgrade is active
|
2017-04-18 19:51:23 +00:00
|
|
|
*/
|
2018-03-06 14:39:48 +00:00
|
|
|
hasUpgrade(upgrade: ShipUpgrade): boolean {
|
2018-02-08 15:16:03 +00:00
|
|
|
return contains(this.upgrades, upgrade.code);
|
2017-04-18 19:51:23 +00:00
|
|
|
}
|
2018-03-20 22:06:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear all activated upgrades
|
|
|
|
*/
|
|
|
|
clearUpgrades(): void {
|
|
|
|
this.upgrades = [];
|
|
|
|
}
|
2017-03-17 00:07:00 +00:00
|
|
|
}
|
|
|
|
}
|