WIP
10
.editorconfig
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
end_of_line = lf
|
||||||
|
max_line_length = off
|
15
.gitignore
vendored
|
@ -1,12 +1,5 @@
|
||||||
.venv
|
.venv
|
||||||
coverage
|
node_modules
|
||||||
/node_modules
|
.rts2_cache_*
|
||||||
/out/assets
|
.coverage
|
||||||
/out/app.*
|
/dist/
|
||||||
/out/tests.*
|
|
||||||
/out/dependencies.js
|
|
||||||
/graphics/**/*.blend?*
|
|
||||||
/graphics/**/output.png
|
|
||||||
/typings/
|
|
||||||
*.log
|
|
||||||
*.tsbuildinfo
|
|
||||||
|
|
11
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
image: node:latest
|
||||||
|
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- node_modules/
|
||||||
|
|
||||||
|
test:
|
||||||
|
before_script:
|
||||||
|
- npm install
|
||||||
|
script:
|
||||||
|
- npm test
|
|
@ -3,7 +3,7 @@
|
||||||
# source activate_node
|
# source activate_node
|
||||||
|
|
||||||
vdir="./.venv"
|
vdir="./.venv"
|
||||||
expected="10.15.3"
|
expected="12.13.0"
|
||||||
|
|
||||||
if [ \! -f "./activate_node" ]
|
if [ \! -f "./activate_node" ]
|
||||||
then
|
then
|
||||||
|
|
BIN
graphics/ships/_base.blend1
Normal file
BIN
graphics/ships/avenger.blend1
Normal file
BIN
graphics/ships/whirlwind.blend1
Normal file
BIN
graphics/title.blend1
Normal file
27
jest.config.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
module.exports = {
|
||||||
|
transform: {
|
||||||
|
"^.+\\.ts$": "ts-jest"
|
||||||
|
},
|
||||||
|
moduleFileExtensions: [
|
||||||
|
"ts",
|
||||||
|
"js",
|
||||||
|
"json",
|
||||||
|
"node"
|
||||||
|
],
|
||||||
|
watchPathIgnorePatterns: [
|
||||||
|
"<rootDir>/dist/",
|
||||||
|
"<rootDir>/node_modules/",
|
||||||
|
],
|
||||||
|
restoreMocks: true,
|
||||||
|
collectCoverage: true,
|
||||||
|
collectCoverageFrom: [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"!src/**/*.test.ts",
|
||||||
|
],
|
||||||
|
coverageDirectory: ".coverage",
|
||||||
|
coverageReporters: [
|
||||||
|
"lcovonly",
|
||||||
|
"html",
|
||||||
|
"text-summary"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,23 +0,0 @@
|
||||||
var handler = {
|
|
||||||
get(target, name) {
|
|
||||||
return new Proxy(function () { }, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var Phaser = new Proxy(function () { }, handler);
|
|
||||||
|
|
||||||
//var debug = console.log;
|
|
||||||
var debug = function () { };
|
|
||||||
|
|
||||||
importScripts("app.js");
|
|
||||||
|
|
||||||
onmessage = function (e) {
|
|
||||||
debug("[AI Worker] Received", e.data.length);
|
|
||||||
var serializer = new TK.Serializer(TK.SpaceTac);
|
|
||||||
var battle = serializer.unserialize(e.data);
|
|
||||||
var processing = new TK.SpaceTac.AIWorker(battle);
|
|
||||||
processing.processHere(function (maneuver) {
|
|
||||||
debug("[AI Worker] Send", maneuver);
|
|
||||||
postMessage(serializer.serialize(maneuver));
|
|
||||||
return maneuver.apply(battle);
|
|
||||||
}).catch(postMessage);
|
|
||||||
}
|
|
Before Width: | Height: | Size: 8 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 8 KiB |
Before Width: | Height: | Size: 3.2 KiB |
BIN
out/favicon.ico
Before Width: | Height: | Size: 7 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 59 KiB |
|
@ -1,54 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title>SpaceTac</title>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
background: #000000;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game {
|
|
||||||
width: 100%;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'SpaceTac';
|
|
||||||
src: url('fonts/daggersquare.regular.otf');
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'SpaceTac';
|
|
||||||
}
|
|
||||||
|
|
||||||
.fontLoader {
|
|
||||||
position: absolute;
|
|
||||||
left: -1000px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="-space-tac" class="game"></div>
|
|
||||||
<div class=".fontLoader">.</div>
|
|
||||||
|
|
||||||
<script src="dependencies.js"></script>
|
|
||||||
<script src="app.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
window.game = new TK.SpaceTac.MainUI();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
BIN
out/play.png
Before Width: | Height: | Size: 6.8 KiB |
68
out/sim.js
|
@ -1,68 +0,0 @@
|
||||||
const Pool = require('process-pool').default;
|
|
||||||
|
|
||||||
const pool = new Pool({ processLimit: 8 });
|
|
||||||
const work = pool.prepare(function () {
|
|
||||||
const App = require("./app").TK.SpaceTac;
|
|
||||||
|
|
||||||
async function doOneBattle(i) {
|
|
||||||
let ai1 = new App.TacticalAI();
|
|
||||||
let ai2 = new App.TacticalAI();
|
|
||||||
|
|
||||||
// Prepare battle
|
|
||||||
let battle = App.Battle.newQuickRandom(true, 1, 2 + i % 4);
|
|
||||||
battle.fleets.forEach((fleet, findex) => {
|
|
||||||
fleet.ships.forEach((ship, sindex) => {
|
|
||||||
ship.name = `F${findex + 1}S${sindex + 1} (${ship.model.name})`;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Run battle
|
|
||||||
while (!battle.ended && battle.cycle < 100) {
|
|
||||||
let playing = battle.playing_ship;
|
|
||||||
if (playing) {
|
|
||||||
let ai = (playing.fleet == battle.fleets[0]) ? ai1 : ai2;
|
|
||||||
ai.ship = playing;
|
|
||||||
await ai.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect results
|
|
||||||
if (battle.outcome && battle.outcome.winner) {
|
|
||||||
let results = {};
|
|
||||||
battle.fleets.forEach(fleet => {
|
|
||||||
fleet.ships.forEach(ship => {
|
|
||||||
let name = `Level ${ship.level.get()} ${ship.model.name}`;
|
|
||||||
results[name] = (results[name] || 0) + (ship.fleet === battle.outcome.winner ? 1 : 0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return results;
|
|
||||||
} else {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (i) => doOneBattle(i);
|
|
||||||
});
|
|
||||||
|
|
||||||
let played = {};
|
|
||||||
let winned = {};
|
|
||||||
let works = Array.from({ length: 1000 }, (v, i) => i).map(i => {
|
|
||||||
return work(i).then(result => {
|
|
||||||
Object.keys(result).forEach(model => {
|
|
||||||
if (result[model]) {
|
|
||||||
winned[model] = (winned[model] || 0) + 1;
|
|
||||||
}
|
|
||||||
played[model] = (played[model] || 0) + 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
console.warn("------------------------------------------------");
|
|
||||||
console.warn(`--- Results after battle ${i}`);
|
|
||||||
Object.keys(played).sort().forEach(model => {
|
|
||||||
let factor = (winned[model] || 0) / played[model];
|
|
||||||
console.warn(`${model} ${Math.round(factor * 100)}%`);
|
|
||||||
});
|
|
||||||
console.warn("------------------------------------------------");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Promise.all(works).then(() => process.exit(0));
|
|
|
@ -1,34 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<title>SpaceTac - Unit tests</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="/jasmine/jasmine.css">
|
|
||||||
<style>
|
|
||||||
canvas {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.jasmine-result-message {
|
|
||||||
white-space: pre-wrap !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div style="display: none; visibility: hidden; height: 0; overflow: hidden;">
|
|
||||||
<div id="-space-tac" class="game"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="/jasmine/jasmine.js"></script>
|
|
||||||
<script src="/jasmine/jasmine-html.js"></script>
|
|
||||||
<script src="/jasmine/boot.js"></script>
|
|
||||||
|
|
||||||
<script src="dependencies.js"></script>
|
|
||||||
<script src="app.js"></script>
|
|
||||||
<script src="tests.js"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
7649
package-lock.json
generated
49
package.json
|
@ -2,21 +2,31 @@
|
||||||
"name": "spacetac",
|
"name": "spacetac",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "A tactical RPG set in space",
|
"description": "A tactical RPG set in space",
|
||||||
"main": "out/build.js",
|
"main": "dist/spacetac.umd.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "run build",
|
"build": "microbundle build -f modern,umd",
|
||||||
"test": "run ci",
|
"test": "jest",
|
||||||
"start": "run continuous"
|
"start": "run continuous",
|
||||||
|
"normalize": "tk-base",
|
||||||
|
"dev": "run-p dev:*",
|
||||||
|
"dev:test": "jest --watchAll",
|
||||||
|
"dev:build": "microbundle watch -f modern,umd",
|
||||||
|
"dev:serve": "live-server --host=localhost --port=5000 --no-browser --ignorePattern='.*\\.d\\.ts' dist",
|
||||||
|
"prepare": "npm run build",
|
||||||
|
"prepublishOnly": "npm test"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://code.thunderk.net/michael/spacetac.git"
|
"url": "https://code.thunderk.net/games/spacetac.git"
|
||||||
},
|
},
|
||||||
"author": "Michael Lemaire",
|
"author": {
|
||||||
"license": "MIT",
|
"name": "Michaël Lemaire",
|
||||||
|
"url": "https://thunderk.net"
|
||||||
|
},
|
||||||
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jasmine": "^3.3.12",
|
"@types/jasmine": "^3.3.12",
|
||||||
"codecov": "^3.4.0",
|
"@types/parse": "^2.9.0",
|
||||||
"gamefroot-texture-packer": "github:Gamefroot/Gamefroot-Texture-Packer#f3687111afc94f80ea8f2877c188fb8e2004e8ff",
|
"gamefroot-texture-packer": "github:Gamefroot/Gamefroot-Texture-Packer#f3687111afc94f80ea8f2877c188fb8e2004e8ff",
|
||||||
"glob": "^7.1.4",
|
"glob": "^7.1.4",
|
||||||
"glob-watcher": "^5.0.3",
|
"glob-watcher": "^5.0.3",
|
||||||
|
@ -27,20 +37,31 @@
|
||||||
"karma-coverage": "^1.1.2",
|
"karma-coverage": "^1.1.2",
|
||||||
"karma-jasmine": "^2.0.1",
|
"karma-jasmine": "^2.0.1",
|
||||||
"karma-spec-reporter": "^0.0.32",
|
"karma-spec-reporter": "^0.0.32",
|
||||||
"live-server": "1.2.1",
|
|
||||||
"process-pool": "^0.3.5",
|
"process-pool": "^0.3.5",
|
||||||
"remap-istanbul": "^0.13.0",
|
|
||||||
"runjs": "^4.4.2",
|
"runjs": "^4.4.2",
|
||||||
"shelljs": "^0.8.3",
|
"shelljs": "^0.8.3",
|
||||||
"terser": "^3.17.0",
|
"tk-base": "^0.2.5"
|
||||||
"typescript": "^3.5.0-rc"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"parse": "^2.4.0",
|
"parse": "^2.4.0",
|
||||||
"phaser": "^3.17.0"
|
"phaser": "^3.20.1"
|
||||||
},
|
},
|
||||||
"dependenciesMap": {
|
"dependenciesMap": {
|
||||||
"parse": "dist/parse.min.js",
|
"parse": "dist/parse.min.js",
|
||||||
"phaser": "dist/phaser.min.js"
|
"phaser": "dist/phaser.min.js"
|
||||||
}
|
},
|
||||||
|
"source": "src/index.ts",
|
||||||
|
"module": "dist/spacetac.modern.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"files": [
|
||||||
|
"/src",
|
||||||
|
"/dist"
|
||||||
|
],
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://gitlab.com/thunderk/spacetac/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://code.thunderk.net/tslib/spacetac",
|
||||||
|
"keywords": [
|
||||||
|
"typescript"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
/// <reference path="../node_modules/phaser/types/phaser.d.ts"/>
|
import { testing } from "./common/Testing";
|
||||||
|
import { bool } from "./common/Tools";
|
||||||
|
import { GameSession } from "./core/GameSession";
|
||||||
|
import { setupEmptyView } from "./ui/TestGame";
|
||||||
|
|
||||||
module TK.SpaceTac.UI.Specs {
|
|
||||||
class FakeStorage {
|
class FakeStorage {
|
||||||
data: any = {}
|
data: any = {}
|
||||||
getItem(name: string) {
|
getItem(name: string) {
|
||||||
|
@ -38,4 +40,3 @@ module TK.SpaceTac.UI.Specs {
|
||||||
check.same(ui.session.universe.starlinks.length, links);
|
check.same(ui.session.universe.starlinks.length, links);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,28 +1,20 @@
|
||||||
/// <reference path="../node_modules/phaser/types/phaser.d.ts"/>
|
/// <reference path="../node_modules/phaser/types/phaser.d.ts"/>
|
||||||
|
|
||||||
declare var global: any;
|
import { RandomGenerator } from "./common/RandomGenerator"
|
||||||
declare var module: any;
|
import { iteritems, keys } from "./common/Tools"
|
||||||
|
import { GameSession } from "./core/GameSession"
|
||||||
|
import { AssetLoading } from "./ui/AssetLoading"
|
||||||
|
import { BaseView } from "./ui/BaseView"
|
||||||
|
import { BattleView } from "./ui/battle/BattleView"
|
||||||
|
import { Boot } from "./ui/Boot"
|
||||||
|
import { FleetCreationView } from "./ui/character/FleetCreationView"
|
||||||
|
import { AudioManager } from "./ui/common/AudioManager"
|
||||||
|
import { IntroView } from "./ui/intro/IntroView"
|
||||||
|
import { UniverseMapView } from "./ui/map/UniverseMapView"
|
||||||
|
import { MainMenu } from "./ui/menu/MainMenu"
|
||||||
|
import { GameOptions } from "./ui/options/GameOptions"
|
||||||
|
import { Router } from "./ui/Router"
|
||||||
|
|
||||||
if (typeof window != "undefined") {
|
|
||||||
// If jasmine is not present, ignore describe
|
|
||||||
(<any>window).describe = (<any>window).describe || function () { };
|
|
||||||
} else {
|
|
||||||
if (typeof global != "undefined") {
|
|
||||||
// In node, does not extend Phaser classes
|
|
||||||
var handler = {
|
|
||||||
get(target: any, name: any): any {
|
|
||||||
return new Proxy(function () { }, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
global.Phaser = new Proxy(function () { }, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof module != "undefined") {
|
|
||||||
module.exports = { TK };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module TK.SpaceTac {
|
|
||||||
/**
|
/**
|
||||||
* Main class to bootstrap the whole game
|
* Main class to bootstrap the whole game
|
||||||
*/
|
*/
|
||||||
|
@ -32,10 +24,10 @@ module TK.SpaceTac {
|
||||||
session_token: string | null
|
session_token: string | null
|
||||||
|
|
||||||
// Audio manager
|
// Audio manager
|
||||||
audio = new UI.Audio(this)
|
audio = new AudioManager(this)
|
||||||
|
|
||||||
// Game options
|
// Game options
|
||||||
options = new UI.GameOptions(this)
|
options = new GameOptions(this)
|
||||||
|
|
||||||
// Storage used
|
// Storage used
|
||||||
storage: Storage
|
storage: Storage
|
||||||
|
@ -73,14 +65,14 @@ module TK.SpaceTac {
|
||||||
this.scene.scenes.forEach(scene => this.scene.resume(scene));
|
this.scene.scenes.forEach(scene => this.scene.resume(scene));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.scene.add('boot', UI.Boot);
|
this.scene.add('boot', Boot);
|
||||||
this.scene.add('loading', UI.AssetLoading);
|
this.scene.add('loading', AssetLoading);
|
||||||
this.scene.add('mainmenu', UI.MainMenu);
|
this.scene.add('mainmenu', MainMenu);
|
||||||
this.scene.add('router', UI.Router);
|
this.scene.add('router', Router);
|
||||||
this.scene.add('battle', UI.BattleView);
|
this.scene.add('battle', BattleView);
|
||||||
this.scene.add('intro', UI.IntroView);
|
this.scene.add('intro', IntroView);
|
||||||
this.scene.add('creation', UI.FleetCreationView);
|
this.scene.add('creation', FleetCreationView);
|
||||||
this.scene.add('universe', UI.UniverseMapView);
|
this.scene.add('universe', UniverseMapView);
|
||||||
|
|
||||||
this.goToScene('boot');
|
this.goToScene('boot');
|
||||||
}
|
}
|
||||||
|
@ -102,7 +94,7 @@ module TK.SpaceTac {
|
||||||
* Display a popup message in current view
|
* Display a popup message in current view
|
||||||
*/
|
*/
|
||||||
displayMessage(message: string) {
|
displayMessage(message: string) {
|
||||||
iteritems(<any>this.scene.keys, (key: string, scene: UI.BaseView) => {
|
iteritems(<any>this.scene.keys, (key: string, scene: BaseView) => {
|
||||||
if (scene.messages && this.scene.isVisible(key)) {
|
if (scene.messages && this.scene.isVisible(key)) {
|
||||||
scene.messages.addMessage(message);
|
scene.messages.addMessage(message);
|
||||||
}
|
}
|
||||||
|
@ -214,4 +206,3 @@ module TK.SpaceTac {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.Specs {
|
|
||||||
class TestState {
|
class TestState {
|
||||||
counter = 0
|
counter = 0
|
||||||
}
|
}
|
||||||
|
@ -227,4 +226,3 @@ module TK.Specs {
|
||||||
check.equals(inter, [5, -1, 2]);
|
check.equals(inter, [5, -1, 2]);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
|
|
@ -1,9 +1,5 @@
|
||||||
/**
|
import { Timer } from "./Timer";
|
||||||
* Framework to maintain a state from a log of changes
|
|
||||||
*
|
|
||||||
* This allows for repeatable, serializable and revertable state modifications.
|
|
||||||
*/
|
|
||||||
module TK {
|
|
||||||
/**
|
/**
|
||||||
* Base class for a single diff.
|
* Base class for a single diff.
|
||||||
*
|
*
|
||||||
|
@ -246,4 +242,3 @@ module TK {
|
||||||
this.log.clear(this.cursor + 1);
|
this.log.clear(this.cursor + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK {
|
|
||||||
testing("Iterators", test => {
|
testing("Iterators", test => {
|
||||||
function checkit<T>(check: TestContext, base_iterator: Iterable<T>, values: T[], infinite = false) {
|
function checkit<T>(check: TestContext, base_iterator: Iterable<T>, values: T[], infinite = false) {
|
||||||
function checker(check: TestContext) {
|
function checker(check: TestContext) {
|
||||||
|
@ -238,4 +237,3 @@ module TK {
|
||||||
check.equals(imax(iarray([3, 8, 2, 4])), 8);
|
check.equals(imax(iarray([3, 8, 2, 4])), 8);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
|
@ -1,14 +1,5 @@
|
||||||
/**
|
import { contains } from "./Tools";
|
||||||
* Lazy iterators to work on dynamic data sets without materializing them.
|
|
||||||
*
|
|
||||||
* They allow to work on infinite streams of values, with limited memory consumption.
|
|
||||||
*
|
|
||||||
* Functions in this file that do not return an Iterable are "materializing", meaning that they
|
|
||||||
* may consume iterators up to the end, and will not work well on infinite iterators.
|
|
||||||
*
|
|
||||||
* These iterators are guaranteed to be repeatable, meaning that calling Symbol.iterator on them will start over.
|
|
||||||
*/
|
|
||||||
module TK {
|
|
||||||
/**
|
/**
|
||||||
* Empty iterator
|
* Empty iterator
|
||||||
*/
|
*/
|
||||||
|
@ -433,4 +424,3 @@ module TK {
|
||||||
export const icat = (iterable: Iterable<string>) => ireduce(iterable, (a, b) => a + b, "");
|
export const icat = (iterable: Iterable<string>) => ireduce(iterable, (a, b) => a + b, "");
|
||||||
export const imin = (iterable: Iterable<number>) => ireduce(iterable, Math.min, Infinity);
|
export const imin = (iterable: Iterable<number>) => ireduce(iterable, Math.min, Infinity);
|
||||||
export const imax = (iterable: Iterable<number>) => ireduce(iterable, Math.max, -Infinity);
|
export const imax = (iterable: Iterable<number>) => ireduce(iterable, Math.max, -Infinity);
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.Specs {
|
|
||||||
export class TestRObject extends RObject {
|
export class TestRObject extends RObject {
|
||||||
x: number
|
x: number
|
||||||
constructor(x = RandomGenerator.global.random()) {
|
constructor(x = RandomGenerator.global.random()) {
|
||||||
|
@ -122,4 +121,3 @@ module TK.Specs {
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
|
|
@ -1,4 +1,6 @@
|
||||||
module TK {
|
import { iarray } from "./Iterators";
|
||||||
|
import { values } from "./Tools";
|
||||||
|
|
||||||
export type RObjectId = number
|
export type RObjectId = number
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,4 +99,3 @@ module TK {
|
||||||
return iarray(this.list());
|
return iarray(this.list());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK {
|
|
||||||
testing("RandomGenerator", test => {
|
testing("RandomGenerator", test => {
|
||||||
test.case("produces floats", check => {
|
test.case("produces floats", check => {
|
||||||
var gen = new RandomGenerator();
|
var gen = new RandomGenerator();
|
||||||
|
@ -89,4 +88,3 @@ module TK {
|
||||||
check.equals(gen.random(), 0.7);
|
check.equals(gen.random(), 0.7);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
module TK {
|
import { range, sum } from "./Tools";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Random generator.
|
* Random generator.
|
||||||
*/
|
*/
|
||||||
|
@ -111,4 +112,3 @@ module TK {
|
||||||
return (typeof result == "undefined") ? Math.random() : result;
|
return (typeof result == "undefined") ? Math.random() : result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.Specs {
|
|
||||||
export class TestSerializerObj1 {
|
export class TestSerializerObj1 {
|
||||||
a: number;
|
a: number;
|
||||||
constructor(a = 0) {
|
constructor(a = 0) {
|
||||||
|
@ -101,4 +100,3 @@ module TK.Specs {
|
||||||
checkReversability(new RandomGenerator());
|
checkReversability(new RandomGenerator());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module TK {
|
import { add, classname, crawl, merge, STOP_CRAWLING } from "./Tools";
|
||||||
|
|
||||||
function isObject(value: any): boolean {
|
function isObject(value: any): boolean {
|
||||||
return value instanceof Object && !Array.isArray(value);
|
return value instanceof Object && !Array.isArray(value);
|
||||||
|
@ -8,10 +8,10 @@ module TK {
|
||||||
* A typescript object serializer.
|
* A typescript object serializer.
|
||||||
*/
|
*/
|
||||||
export class Serializer {
|
export class Serializer {
|
||||||
namespace: any;
|
namespace: { [name: string]: (...args: any) => any };
|
||||||
ignored: string[] = [];
|
ignored: string[] = [];
|
||||||
|
|
||||||
constructor(namespace: any = TK) {
|
constructor(namespace: { [name: string]: (...args: any) => any } = {}) {
|
||||||
this.namespace = namespace;
|
this.namespace = namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,10 +30,6 @@ module TK {
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
let cl = this.namespace[ctype];
|
let cl = this.namespace[ctype];
|
||||||
if (cl) {
|
|
||||||
return Object.create(cl.prototype);
|
|
||||||
} else {
|
|
||||||
cl = (<any>TK)[ctype];
|
|
||||||
if (cl) {
|
if (cl) {
|
||||||
return Object.create(cl.prototype);
|
return Object.create(cl.prototype);
|
||||||
} else {
|
} else {
|
||||||
|
@ -42,7 +38,6 @@ module TK {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize an object to a string
|
* Serialize an object to a string
|
||||||
|
@ -59,7 +54,7 @@ module TK {
|
||||||
add(objects, value);
|
add(objects, value);
|
||||||
return value;
|
return value;
|
||||||
} else {
|
} else {
|
||||||
return TK.STOP_CRAWLING;
|
return STOP_CRAWLING;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return value;
|
return value;
|
||||||
|
@ -108,4 +103,3 @@ module TK {
|
||||||
return objects[0];
|
return objects[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
/**
|
import { Timer } from "./Timer";
|
||||||
* Various testing functions.
|
|
||||||
*/
|
|
||||||
module TK {
|
|
||||||
export type FakeClock = { forward: (milliseconds: number) => void }
|
export type FakeClock = { forward: (milliseconds: number) => void }
|
||||||
export type Mock<F extends Function> = { func: F, getCalls: () => any[][], reset: () => void }
|
export type Mock<F extends Function> = { func: F, getCalls: () => any[][], reset: () => void }
|
||||||
|
|
||||||
|
@ -327,4 +325,3 @@ module TK {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.Specs {
|
|
||||||
testing("Timer", test => {
|
testing("Timer", test => {
|
||||||
let clock = test.clock();
|
let clock = test.clock();
|
||||||
|
|
||||||
|
@ -114,4 +113,3 @@ module TK.Specs {
|
||||||
check.equals(Timer.fromMs(t), 10);
|
check.equals(Timer.fromMs(t), 10);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
module TK {
|
import { add, remove } from "./Tools";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Timing utility.
|
* Timing utility.
|
||||||
*
|
*
|
||||||
|
@ -97,4 +98,3 @@ module TK {
|
||||||
this.scheduled = [];
|
this.scheduled = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.Specs {
|
|
||||||
testing("Toggle", test => {
|
testing("Toggle", test => {
|
||||||
let on_calls = 0;
|
let on_calls = 0;
|
||||||
let off_calls = 0;
|
let off_calls = 0;
|
||||||
|
@ -155,4 +154,3 @@ module TK.Specs {
|
||||||
checkstate(0, 0);
|
checkstate(0, 0);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
|
|
@ -1,4 +1,6 @@
|
||||||
module TK {
|
import { Timer } from "./Timer"
|
||||||
|
import { add, contains, remove } from "./Tools"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client for Toggle object, allowing to manipulate it
|
* Client for Toggle object, allowing to manipulate it
|
||||||
*
|
*
|
||||||
|
@ -90,4 +92,3 @@ module TK {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.Specs {
|
|
||||||
testing("Tools", test => {
|
testing("Tools", test => {
|
||||||
test.case("returns boolean equivalent", check => {
|
test.case("returns boolean equivalent", check => {
|
||||||
check.same(bool(null), false, "null");
|
check.same(bool(null), false, "null");
|
||||||
|
@ -520,4 +519,3 @@ module TK.Specs {
|
||||||
check.equals(disjunctunion([1, 8, 2], [2, 8, 4]), [1, 4]);
|
check.equals(disjunctunion([1, 8, 2], [2, 8, 4]), [1, 4]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
/**
|
import { Serializer } from "./Serializer";
|
||||||
* Various utility functions.
|
|
||||||
*/
|
|
||||||
module TK {
|
|
||||||
/**
|
/**
|
||||||
* Functions that does nothing (useful for default callbacks)
|
* Functions that does nothing (useful for default callbacks)
|
||||||
*/
|
*/
|
||||||
|
@ -131,7 +129,7 @@ module TK {
|
||||||
*
|
*
|
||||||
* Please be aware that contained RObjects will be duplicated, but keep their ID, thus breaking the uniqueness.
|
* Please be aware that contained RObjects will be duplicated, but keep their ID, thus breaking the uniqueness.
|
||||||
*/
|
*/
|
||||||
export function duplicate<T>(obj: T, namespace: Object = TK): T {
|
export function duplicate<T>(obj: T, namespace: { [name: string]: (...args: any) => any } = {}): T {
|
||||||
let serializer = new Serializer(namespace);
|
let serializer = new Serializer(namespace);
|
||||||
let serialized = serializer.serialize({ dat: obj });
|
let serialized = serializer.serialize({ dat: obj });
|
||||||
return serializer.unserialize(serialized).dat;
|
return serializer.unserialize(serialized).dat;
|
||||||
|
@ -637,4 +635,3 @@ module TK {
|
||||||
export function disjunctunion<T>(array1: T[], array2: T[]): T[] {
|
export function disjunctunion<T>(array1: T[], array2: T[]): T[] {
|
||||||
return difference(union(array1, array2), intersection(array1, array2));
|
return difference(union(array1, array2), intersection(array1, array2));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac.Specs {
|
|
||||||
function checkLocation(check: TestContext, got: IArenaLocation, expected_x: number, expected_y: number) {
|
function checkLocation(check: TestContext, got: IArenaLocation, expected_x: number, expected_y: number) {
|
||||||
check.equals(got.x, expected_x, `x differs (${got.x},${got.y}) (${expected_x},${expected_y})`);
|
check.equals(got.x, expected_x, `x differs (${got.x},${got.y}) (${expected_x},${expected_y})`);
|
||||||
check.equals(got.y, expected_y, `y differs (${got.x},${got.y}) (${expected_x},${expected_y})`);
|
check.equals(got.y, expected_y, `y differs (${got.x},${got.y}) (${expected_x},${expected_y})`);
|
||||||
|
@ -26,4 +25,3 @@ module TK.SpaceTac.Specs {
|
||||||
checkLocation(check, grid.snap({ x: 1, y: 6 }), 5, 10 * Math.sqrt(0.75));
|
checkLocation(check, grid.snap({ x: 1, y: 6 }), 5, 10 * Math.sqrt(0.75));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
module TK.SpaceTac {
|
import { ArenaLocation, IArenaLocation } from "./ArenaLocation";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract grid for the arena where the battle takes place
|
* Abstract grid for the arena where the battle takes place
|
||||||
*
|
*
|
||||||
|
@ -31,4 +32,3 @@ module TK.SpaceTac {
|
||||||
return new ArenaLocation((xr * this.unit) || 0, (yr * this.yunit) || 0);
|
return new ArenaLocation((xr * this.unit) || 0, (yr * this.yunit) || 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac.Specs {
|
|
||||||
testing("ArenaLocation", test => {
|
testing("ArenaLocation", test => {
|
||||||
test.case("gets distance and angle between two locations", check => {
|
test.case("gets distance and angle between two locations", check => {
|
||||||
check.nears(arenaDistance({ x: 0, y: 0 }, { x: 1, y: 1 }), Math.sqrt(2));
|
check.nears(arenaDistance({ x: 0, y: 0 }, { x: 1, y: 1 }), Math.sqrt(2));
|
||||||
|
@ -19,4 +18,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.nears(radians(45), Math.PI / 4);
|
check.nears(radians(45), Math.PI / 4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac {
|
|
||||||
/**
|
/**
|
||||||
* Location in the arena (coordinates only)
|
* Location in the arena (coordinates only)
|
||||||
*/
|
*/
|
||||||
|
@ -96,4 +95,3 @@ module TK.SpaceTac {
|
||||||
export function radians(angle: number): number {
|
export function radians(angle: number): number {
|
||||||
return angle * Math.PI / 180;
|
return angle * Math.PI / 180;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac {
|
|
||||||
testing("Battle", test => {
|
testing("Battle", test => {
|
||||||
test.case("defines play order by initiative throws", check => {
|
test.case("defines play order by initiative throws", check => {
|
||||||
var fleet1 = new Fleet();
|
var fleet1 = new Fleet();
|
||||||
|
@ -378,4 +377,3 @@ module TK.SpaceTac {
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
module TK.SpaceTac {
|
import { iarray, ichainit, ifilter, iforeach, imap, imaterialize } from "../common/Iterators"
|
||||||
|
import { RandomGenerator } from "../common/RandomGenerator"
|
||||||
|
import { RObjectContainer, RObjectId } from "../common/RObject"
|
||||||
|
import { bool, flatten } from "../common/Tools"
|
||||||
|
import { EndTurnAction } from "./actions/EndTurnAction"
|
||||||
|
import { AIWorker } from "./ai/AIWorker"
|
||||||
|
import { HexagonalArenaGrid, IArenaGrid } from "./ArenaGrid"
|
||||||
|
import { BattleChecks } from "./BattleChecks"
|
||||||
|
import { BattleLog, BattleLogClient } from "./BattleLog"
|
||||||
|
import { BattleOutcome } from "./BattleOutcome"
|
||||||
|
import { BattleStats } from "./BattleStats"
|
||||||
|
import { BaseBattleDiff } from "./diffs/BaseBattleDiff"
|
||||||
|
import { EndBattleDiff } from "./diffs/EndBattleDiff"
|
||||||
|
import { ShipActionEndedDiff } from "./diffs/ShipActionEndedDiff"
|
||||||
|
import { ShipActionUsedDiff } from "./diffs/ShipActionUsedDiff"
|
||||||
|
import { Drone } from "./Drone"
|
||||||
|
import { BaseEffect } from "./effects/BaseEffect"
|
||||||
|
import { Fleet } from "./Fleet"
|
||||||
|
import { Player } from "./Player"
|
||||||
|
import { Ship } from "./Ship"
|
||||||
|
import { Target } from "./Target"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A turn-based battle between fleets
|
* A turn-based battle between fleets
|
||||||
*/
|
*/
|
||||||
|
@ -413,4 +434,3 @@ module TK.SpaceTac {
|
||||||
client.truncate();
|
client.truncate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac.Specs {
|
|
||||||
testing("BattleCheats", test => {
|
testing("BattleCheats", test => {
|
||||||
test.case("wins a battle", check => {
|
test.case("wins a battle", check => {
|
||||||
let battle = Battle.newQuickRandom();
|
let battle = Battle.newQuickRandom();
|
||||||
|
@ -22,4 +21,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(any(battle.fleets[0].ships, ship => ship.alive), false, "all allies dead");
|
check.equals(any(battle.fleets[0].ships, ship => ship.alive), false, "all allies dead");
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
module TK.SpaceTac {
|
import { iforeach } from "../common/Iterators";
|
||||||
|
import { first } from "../common/Tools";
|
||||||
|
import { Battle } from "./Battle";
|
||||||
|
import { Player } from "./Player";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cheat helpers for current battle
|
* Cheat helpers for current battle
|
||||||
*
|
*
|
||||||
|
@ -37,4 +41,3 @@ module TK.SpaceTac {
|
||||||
this.battle.endBattle(first(this.battle.fleets, fleet => !this.player.is(fleet.player)));
|
this.battle.endBattle(first(this.battle.fleets, fleet => !this.player.is(fleet.player)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac.Specs {
|
|
||||||
testing("BattleChecks", test => {
|
testing("BattleChecks", test => {
|
||||||
test.case("detects victory conditions", check => {
|
test.case("detects victory conditions", check => {
|
||||||
let battle = new Battle();
|
let battle = new Battle();
|
||||||
|
@ -103,4 +102,3 @@ module TK.SpaceTac.Specs {
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
module TK.SpaceTac {
|
import { ifirst, iforeach, imaterialize } from "../common/Iterators";
|
||||||
|
import { RObjectContainer } from "../common/RObject";
|
||||||
|
import { any, first, flatten, keys } from "../common/Tools";
|
||||||
|
import { Battle } from "./Battle";
|
||||||
|
import { BaseBattleDiff } from "./diffs/BaseBattleDiff";
|
||||||
|
import { EndBattleDiff } from "./diffs/EndBattleDiff";
|
||||||
|
import { ShipEffectAddedDiff, ShipEffectRemovedDiff } from "./diffs/ShipEffectAddedDiff";
|
||||||
|
import { ShipValueDiff } from "./diffs/ShipValueDiff";
|
||||||
|
import { StickyEffect } from "./effects/StickyEffect";
|
||||||
|
import { Ship } from "./Ship";
|
||||||
|
import { SHIP_VALUES } from "./ShipValue";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of checks to apply at the end of an action, to ensure a correct battle state
|
* List of checks to apply at the end of an action, to ensure a correct battle state
|
||||||
*
|
*
|
||||||
|
@ -161,4 +172,3 @@ module TK.SpaceTac {
|
||||||
return flatten(ships.map(ship => this.getAreaEffectsDiff(ship)));
|
return flatten(ships.map(ship => this.getAreaEffectsDiff(ship)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/// <reference path="../common/DiffLog.ts" />
|
import { DiffLog, DiffLogClient } from "../common/DiffLog";
|
||||||
|
import { Battle } from "./Battle";
|
||||||
|
|
||||||
module TK.SpaceTac {
|
|
||||||
/**
|
/**
|
||||||
* Log of diffs that change the state of a battle
|
* Log of diffs that change the state of a battle
|
||||||
*/
|
*/
|
||||||
|
@ -12,4 +12,3 @@ module TK.SpaceTac {
|
||||||
*/
|
*/
|
||||||
export class BattleLogClient extends DiffLogClient<Battle> {
|
export class BattleLogClient extends DiffLogClient<Battle> {
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac.Specs {
|
|
||||||
testing("BattleOutcome", test => {
|
testing("BattleOutcome", test => {
|
||||||
test.case("grants experience", check => {
|
test.case("grants experience", check => {
|
||||||
let fleet1 = new Fleet();
|
let fleet1 = new Fleet();
|
||||||
|
@ -33,4 +32,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(ship2b.level.getExperience(), 2818);
|
check.equals(ship2b.level.getExperience(), 2818);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
module TK.SpaceTac {
|
import { RObjectId } from "../common/RObject";
|
||||||
|
import { flatten, sum } from "../common/Tools";
|
||||||
|
import { Fleet } from "./Fleet";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result of an ended battle
|
* Result of an ended battle
|
||||||
*
|
*
|
||||||
|
@ -31,4 +34,3 @@ module TK.SpaceTac {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac.Specs {
|
|
||||||
testing("BattleStats", test => {
|
testing("BattleStats", test => {
|
||||||
test.case("collects stats", check => {
|
test.case("collects stats", check => {
|
||||||
let stats = new BattleStats();
|
let stats = new BattleStats();
|
||||||
|
@ -72,4 +71,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(stats.stats, { "Drones deployed": [1, 1] });
|
check.equals(stats.stats, { "Drones deployed": [1, 1] });
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
module TK.SpaceTac {
|
import { any, iteritems } from "../common/Tools";
|
||||||
|
import { BattleLog } from "./BattleLog";
|
||||||
|
import { BaseBattleShipDiff } from "./diffs/BaseBattleDiff";
|
||||||
|
import { DroneDeployedDiff } from "./diffs/DroneDeployedDiff";
|
||||||
|
import { ShipDamageDiff } from "./diffs/ShipDamageDiff";
|
||||||
|
import { ShipMoveDiff } from "./diffs/ShipMoveDiff";
|
||||||
|
import { Fleet } from "./Fleet";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Statistics collection over a battle
|
* Statistics collection over a battle
|
||||||
*/
|
*/
|
||||||
|
@ -61,4 +68,3 @@ module TK.SpaceTac {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac.Specs {
|
|
||||||
testing("Cooldown", test => {
|
testing("Cooldown", test => {
|
||||||
test.case("applies overheat and cooldown", check => {
|
test.case("applies overheat and cooldown", check => {
|
||||||
let cooldown = new Cooldown();
|
let cooldown = new Cooldown();
|
||||||
|
@ -35,4 +34,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(cooldown.canUse(), true);
|
check.equals(cooldown.canUse(), true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac {
|
|
||||||
/**
|
/**
|
||||||
* Cooldown system for equipments
|
* Cooldown system for equipments
|
||||||
*/
|
*/
|
||||||
|
@ -90,4 +89,3 @@ module TK.SpaceTac {
|
||||||
this.heat = 0;
|
this.heat = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac {
|
|
||||||
testing("Drone", test => {
|
testing("Drone", test => {
|
||||||
test.case("applies area effects when deployed", check => {
|
test.case("applies area effects when deployed", check => {
|
||||||
let battle = TestTools.createBattle();
|
let battle = TestTools.createBattle();
|
||||||
|
@ -59,4 +58,3 @@ module TK.SpaceTac {
|
||||||
check.equals(drone.getDescription(), "While deployed:\n• do 5 damage\n• evasion +1");
|
check.equals(drone.getDescription(), "While deployed:\n• do 5 damage\n• evasion +1");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
module TK.SpaceTac {
|
import { ifilter, imaterialize } from "../common/Iterators"
|
||||||
|
import { RObject, RObjectId } from "../common/RObject"
|
||||||
|
import { DeployDroneAction } from "./actions/DeployDroneAction"
|
||||||
|
import { ArenaLocation } from "./ArenaLocation"
|
||||||
|
import { Battle } from "./Battle"
|
||||||
|
import { BaseEffect } from "./effects/BaseEffect"
|
||||||
|
import { Ship } from "./Ship"
|
||||||
|
import { Target } from "./Target"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drones are static objects that apply effects in a circular zone around themselves.
|
* Drones are static objects that apply effects in a circular zone around themselves.
|
||||||
*/
|
*/
|
||||||
|
@ -60,4 +68,3 @@ module TK.SpaceTac {
|
||||||
return imaterialize(ships);
|
return imaterialize(ships);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -1,4 +1,8 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { testing } from "../common/Testing";
|
||||||
|
import { ArenaLocationAngle } from "./ArenaLocation";
|
||||||
|
import { Battle } from "./Battle";
|
||||||
|
import { ExclusionAreas } from "./ExclusionAreas";
|
||||||
|
|
||||||
testing("ExclusionAreas", test => {
|
testing("ExclusionAreas", test => {
|
||||||
test.case("constructs from a ship or battle", check => {
|
test.case("constructs from a ship or battle", check => {
|
||||||
let battle = new Battle();
|
let battle = new Battle();
|
||||||
|
@ -40,4 +44,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(exclusion.obstacles, [new ArenaLocationAngle(12, 5), new ArenaLocationAngle(43, 89)]);
|
check.equals(exclusion.obstacles, [new ArenaLocationAngle(12, 5), new ArenaLocationAngle(43, 89)]);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
|
|
@ -1,4 +1,10 @@
|
||||||
module TK.SpaceTac {
|
import { ifilter, imap, imaterialize } from "../common/Iterators"
|
||||||
|
import { cmp, contains, sorted } from "../common/Tools"
|
||||||
|
import { arenaDistance, ArenaLocation } from "./ArenaLocation"
|
||||||
|
import { Battle } from "./Battle"
|
||||||
|
import { Ship } from "./Ship"
|
||||||
|
import { Target } from "./Target"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper for working with exclusion areas (areas where a ship cannot go)
|
* Helper for working with exclusion areas (areas where a ship cannot go)
|
||||||
*
|
*
|
||||||
|
@ -93,4 +99,3 @@ module TK.SpaceTac {
|
||||||
return new ArenaLocation(target.x, target.y);
|
return new ArenaLocation(target.x, target.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
module TK.SpaceTac {
|
import { RObjectId } from "../common/RObject";
|
||||||
|
import { testing } from "../common/Testing";
|
||||||
|
import { Battle } from "./Battle";
|
||||||
|
import { Fleet } from "./Fleet";
|
||||||
|
import { Ship } from "./Ship";
|
||||||
|
import { StarLocationType } from "./StarLocation";
|
||||||
|
import { Universe } from "./Universe";
|
||||||
|
|
||||||
testing("Fleet", test => {
|
testing("Fleet", test => {
|
||||||
test.case("get average level", check => {
|
test.case("get average level", check => {
|
||||||
var fleet = new Fleet();
|
var fleet = new Fleet();
|
||||||
|
@ -165,4 +172,3 @@ module TK.SpaceTac {
|
||||||
check.equals(fleet.isAlive(), false);
|
check.equals(fleet.isAlive(), false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
module TK.SpaceTac {
|
import { RObject, RObjectId } from "../common/RObject"
|
||||||
|
import { add, any, remove } from "../common/Tools"
|
||||||
|
import { Battle } from "./Battle"
|
||||||
|
import { Player } from "./Player"
|
||||||
|
import { Ship } from "./Ship"
|
||||||
|
import { StarLocation, StarLocationType } from "./StarLocation"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fleet of ships, all belonging to the same player
|
* A fleet of ships, all belonging to the same player
|
||||||
*/
|
*/
|
||||||
|
@ -148,4 +154,3 @@ module TK.SpaceTac {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
module TK.SpaceTac {
|
import { RandomGenerator } from "../common/RandomGenerator";
|
||||||
|
import { range } from "../common/Tools";
|
||||||
|
import { Fleet } from "./Fleet";
|
||||||
|
import { ShipModel } from "./models/ShipModel";
|
||||||
|
import { Player } from "./Player";
|
||||||
|
import { ShipGenerator } from "./ShipGenerator";
|
||||||
|
|
||||||
// Generator of balanced ships to form a fleet
|
// Generator of balanced ships to form a fleet
|
||||||
export class FleetGenerator {
|
export class FleetGenerator {
|
||||||
// Random generator to use
|
// Random generator to use
|
||||||
|
@ -26,4 +32,3 @@ module TK.SpaceTac {
|
||||||
return fleet;
|
return fleet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { SkewedRandomGenerator } from "../common/RandomGenerator";
|
||||||
|
import { RObjectContainer } from "../common/RObject";
|
||||||
|
import { testing } from "../common/Testing";
|
||||||
|
import { nn } from "../common/Tools";
|
||||||
|
import { Fleet } from "./Fleet";
|
||||||
|
import { GameSession } from "./GameSession";
|
||||||
|
import { StarLocation, StarLocationType } from "./StarLocation";
|
||||||
|
|
||||||
testing("GameSession", test => {
|
testing("GameSession", test => {
|
||||||
/**
|
/**
|
||||||
* Compare two sessions
|
* Compare two sessions
|
||||||
|
@ -145,4 +152,3 @@ module TK.SpaceTac.Specs {
|
||||||
});
|
});
|
||||||
});*/
|
});*/
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
module TK.SpaceTac {
|
import { NAMESPACE } from ".."
|
||||||
|
import { iforeach } from "../common/Iterators"
|
||||||
|
import { RandomGenerator } from "../common/RandomGenerator"
|
||||||
|
import { Serializer } from "../common/Serializer"
|
||||||
|
import { Battle } from "./Battle"
|
||||||
|
import { Fleet } from "./Fleet"
|
||||||
|
import { FleetGenerator } from "./FleetGenerator"
|
||||||
|
import { PersonalityReactions } from "./PersonalityReactions"
|
||||||
|
import { Player } from "./Player"
|
||||||
|
import { StarLocation } from "./StarLocation"
|
||||||
|
import { Universe } from "./Universe"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A game session, binding a universe and a player
|
* A game session, binding a universe and a player
|
||||||
*
|
*
|
||||||
|
@ -55,13 +66,13 @@ module TK.SpaceTac {
|
||||||
|
|
||||||
// Load a game state from a string
|
// Load a game state from a string
|
||||||
static loadFromString(serialized: string): GameSession {
|
static loadFromString(serialized: string): GameSession {
|
||||||
var serializer = new Serializer(TK.SpaceTac);
|
var serializer = new Serializer(NAMESPACE);
|
||||||
return <GameSession>serializer.unserialize(serialized);
|
return <GameSession>serializer.unserialize(serialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serializes the game state to a string
|
// Serializes the game state to a string
|
||||||
saveToString(): string {
|
saveToString(): string {
|
||||||
var serializer = new Serializer(TK.SpaceTac);
|
var serializer = new Serializer(NAMESPACE);
|
||||||
return serializer.serialize(this);
|
return serializer.serialize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,4 +213,3 @@ module TK.SpaceTac {
|
||||||
return this.introduced;
|
return this.introduced;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,23 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { iarray, imaterialize } from "../common/Iterators";
|
||||||
|
import { testing } from "../common/Testing";
|
||||||
|
import { nn } from "../common/Tools";
|
||||||
|
import { BaseAction } from "./actions/BaseAction";
|
||||||
|
import { MoveAction } from "./actions/MoveAction";
|
||||||
|
import { TriggerAction } from "./actions/TriggerAction";
|
||||||
|
import { ArenaLocationAngle } from "./ArenaLocation";
|
||||||
|
import { Battle } from "./Battle";
|
||||||
|
import { EndBattleDiff } from "./diffs/EndBattleDiff";
|
||||||
|
import { ProjectileFiredDiff } from "./diffs/ProjectileFiredDiff";
|
||||||
|
import { ShipActionUsedDiff } from "./diffs/ShipActionUsedDiff";
|
||||||
|
import { ShipDamageDiff } from "./diffs/ShipDamageDiff";
|
||||||
|
import { ShipDeathDiff } from "./diffs/ShipDeathDiff";
|
||||||
|
import { ShipMoveDiff } from "./diffs/ShipMoveDiff";
|
||||||
|
import { ShipValueDiff } from "./diffs/ShipValueDiff";
|
||||||
|
import { ApproachSimulationError, MoveFireSimulator } from "./MoveFireSimulator";
|
||||||
|
import { Ship } from "./Ship";
|
||||||
|
import { Target } from "./Target";
|
||||||
|
import { TestTools } from "./TestTools";
|
||||||
|
|
||||||
testing("MoveFireSimulator", test => {
|
testing("MoveFireSimulator", test => {
|
||||||
|
|
||||||
function simpleWeaponCase(distance = 10, ship_ap = 5, weapon_ap = 3, engine_distance = 5): [Ship, MoveFireSimulator, BaseAction] {
|
function simpleWeaponCase(distance = 10, ship_ap = 5, weapon_ap = 3, engine_distance = 5): [Ship, MoveFireSimulator, BaseAction] {
|
||||||
|
@ -204,4 +223,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(enemy.getValue("hull"), 2);
|
check.equals(enemy.getValue("hull"), 2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,14 @@
|
||||||
module TK.SpaceTac {
|
import { NAMESPACE } from ".."
|
||||||
|
import { ichainit, iforeach, imap, irepeat, istep } from "../common/Iterators"
|
||||||
|
import { cfilter, duplicate, first, minBy, nn } from "../common/Tools"
|
||||||
|
import { BaseAction } from "./actions/BaseAction"
|
||||||
|
import { MoveAction } from "./actions/MoveAction"
|
||||||
|
import { arenaDistance } from "./ArenaLocation"
|
||||||
|
import { Battle } from "./Battle"
|
||||||
|
import { BaseBattleDiff } from "./diffs/BaseBattleDiff"
|
||||||
|
import { Ship } from "./Ship"
|
||||||
|
import { Target } from "./Target"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error codes for approach simulation
|
* Error codes for approach simulation
|
||||||
*/
|
*/
|
||||||
|
@ -194,7 +204,7 @@ module TK.SpaceTac {
|
||||||
* The original battle passed as parameter will be duplicated, and not altered
|
* The original battle passed as parameter will be duplicated, and not altered
|
||||||
*/
|
*/
|
||||||
getExpectedDiffs(battle: Battle, simulation: MoveFireResult): BaseBattleDiff[] {
|
getExpectedDiffs(battle: Battle, simulation: MoveFireResult): BaseBattleDiff[] {
|
||||||
let sim_battle = duplicate(battle, TK.SpaceTac);
|
let sim_battle = duplicate(battle, NAMESPACE);
|
||||||
let sim_ship = nn(sim_battle.getShip(this.ship.id));
|
let sim_ship = nn(sim_battle.getShip(this.ship.id));
|
||||||
let results: BaseBattleDiff[] = [];
|
let results: BaseBattleDiff[] = [];
|
||||||
simulation.parts.forEach(part => {
|
simulation.parts.forEach(part => {
|
||||||
|
@ -208,4 +218,3 @@ module TK.SpaceTac {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { SkewedRandomGenerator } from "../common/RandomGenerator";
|
||||||
|
import { testing } from "../common/Testing";
|
||||||
|
import { NameGenerator } from "./NameGenerator";
|
||||||
|
|
||||||
testing("NameGenerator", test => {
|
testing("NameGenerator", test => {
|
||||||
test.case("generates unique names", check => {
|
test.case("generates unique names", check => {
|
||||||
var random = new SkewedRandomGenerator([0.48, 0.9, 0.1]);
|
var random = new SkewedRandomGenerator([0.48, 0.9, 0.1]);
|
||||||
|
@ -10,4 +13,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(gen.getName(), null);
|
check.equals(gen.getName(), null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
module TK.SpaceTac {
|
import { RandomGenerator } from "../common/RandomGenerator";
|
||||||
|
import { acopy } from "../common/Tools";
|
||||||
|
|
||||||
// A unique name generator
|
// A unique name generator
|
||||||
export class NameGenerator {
|
export class NameGenerator {
|
||||||
// List of available choices
|
// List of available choices
|
||||||
|
@ -24,4 +26,3 @@ module TK.SpaceTac {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac {
|
|
||||||
/**
|
/**
|
||||||
* List of personality traits (may be used with "keyof").
|
* List of personality traits (may be used with "keyof").
|
||||||
*/
|
*/
|
||||||
|
@ -33,4 +32,3 @@ module TK.SpaceTac {
|
||||||
// Optimistic 1 / Pessimistic -1
|
// Optimistic 1 / Pessimistic -1
|
||||||
optimistic = 0
|
optimistic = 0
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { testing } from "../common/Testing";
|
||||||
|
import { Battle } from "./Battle";
|
||||||
|
import { ShipDamageDiff } from "./diffs/ShipDamageDiff";
|
||||||
|
import { BUILTIN_REACTION_POOL, PersonalityReaction, PersonalityReactionConversation, PersonalityReactions, ReactionPool } from "./PersonalityReactions";
|
||||||
|
import { Player } from "./Player";
|
||||||
|
import { Ship } from "./Ship";
|
||||||
|
|
||||||
testing("PersonalityReactions", test => {
|
testing("PersonalityReactions", test => {
|
||||||
function apply(pool: ReactionPool): PersonalityReaction | null {
|
function apply(pool: ReactionPool): PersonalityReaction | null {
|
||||||
let reactions = new PersonalityReactions();
|
let reactions = new PersonalityReactions();
|
||||||
|
@ -62,4 +68,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(condition(player, battle, ship2a, new ShipDamageDiff(ship2a, 50, 10)), [], "other player event");
|
check.equals(condition(player, battle, ship2a, new ShipDamageDiff(ship2a, 50, 10)), [], "other player event");
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
module TK.SpaceTac {
|
import { RandomGenerator } from "../common/RandomGenerator"
|
||||||
|
import { difference, keys, nna } from "../common/Tools"
|
||||||
|
import { Battle } from "./Battle"
|
||||||
|
import { BaseBattleDiff } from "./diffs/BaseBattleDiff"
|
||||||
|
import { ShipDamageDiff } from "./diffs/ShipDamageDiff"
|
||||||
|
import { IPersonalityTraits } from "./Personality"
|
||||||
|
import { Player } from "./Player"
|
||||||
|
import { Ship } from "./Ship"
|
||||||
|
|
||||||
// Reaction triggered
|
// Reaction triggered
|
||||||
export type PersonalityReaction = PersonalityReactionConversation
|
export type PersonalityReaction = PersonalityReactionConversation
|
||||||
|
|
||||||
|
@ -103,4 +111,3 @@ module TK.SpaceTac {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
module TK.SpaceTac {
|
import { testing } from "../common/Testing";
|
||||||
|
import { Player } from "./Player";
|
||||||
|
import { StarLocationType } from "./StarLocation";
|
||||||
|
import { Universe } from "./Universe";
|
||||||
|
|
||||||
testing("Player", test => {
|
testing("Player", test => {
|
||||||
test.case("keeps track of visited locations", check => {
|
test.case("keeps track of visited locations", check => {
|
||||||
let player = new Player();
|
let player = new Player();
|
||||||
|
@ -35,4 +39,3 @@ module TK.SpaceTac {
|
||||||
checkVisited(true, true, true, true, true, false);
|
checkVisited(true, true, true, true, true, false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
|
@ -1,6 +1,13 @@
|
||||||
/// <reference path="../common/RObject.ts" />
|
import { RObject } from "../common/RObject";
|
||||||
|
import { contains, intersection } from "../common/Tools";
|
||||||
|
import { Battle } from "./Battle";
|
||||||
|
import { BattleCheats } from "./BattleCheats";
|
||||||
|
import { Fleet } from "./Fleet";
|
||||||
|
import { FleetGenerator } from "./FleetGenerator";
|
||||||
|
import { ActiveMissions } from "./missions/ActiveMissions";
|
||||||
|
import { Star } from "./Star";
|
||||||
|
import { StarLocation } from "./StarLocation";
|
||||||
|
|
||||||
module TK.SpaceTac {
|
|
||||||
/**
|
/**
|
||||||
* One player (human or IA)
|
* One player (human or IA)
|
||||||
*/
|
*/
|
||||||
|
@ -75,4 +82,3 @@ module TK.SpaceTac {
|
||||||
this.missions.checkStatus();
|
this.missions.checkStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { testing } from "../common/Testing";
|
||||||
|
import { IntegerRange } from "./Range";
|
||||||
|
|
||||||
testing("Range", test => {
|
testing("Range", test => {
|
||||||
test.case("can work with proportional values", check => {
|
test.case("can work with proportional values", check => {
|
||||||
var range = new Range(1, 5);
|
var range = new Range(1, 5);
|
||||||
|
@ -42,4 +44,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(range.getReverseProportional(5), 0.8);
|
check.equals(range.getReverseProportional(5), 0.8);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
module TK.SpaceTac {
|
|
||||||
// Range of number values
|
// Range of number values
|
||||||
export class Range {
|
export class Range {
|
||||||
// Minimal value
|
// Minimal value
|
||||||
|
@ -79,4 +78,3 @@ module TK.SpaceTac {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,20 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { testing } from "../common/Testing";
|
||||||
|
import { nn } from "../common/Tools";
|
||||||
|
import { BaseAction } from "./actions/BaseAction";
|
||||||
|
import { ToggleAction } from "./actions/ToggleAction";
|
||||||
|
import { Battle } from "./Battle";
|
||||||
|
import { ShipActionToggleDiff } from "./diffs/ShipActionToggleDiff";
|
||||||
|
import { ShipAttributeDiff } from "./diffs/ShipAttributeDiff";
|
||||||
|
import { ShipDeathDiff } from "./diffs/ShipDeathDiff";
|
||||||
|
import { ShipEffectRemovedDiff } from "./diffs/ShipEffectAddedDiff";
|
||||||
|
import { ShipValueDiff } from "./diffs/ShipValueDiff";
|
||||||
|
import { AttributeEffect } from "./effects/AttributeEffect";
|
||||||
|
import { AttributeLimitEffect } from "./effects/AttributeLimitEffect";
|
||||||
|
import { StickyEffect } from "./effects/StickyEffect";
|
||||||
|
import { ShipModel } from "./models/ShipModel";
|
||||||
|
import { Ship } from "./Ship";
|
||||||
|
import { TestTools } from "./TestTools";
|
||||||
|
|
||||||
testing("Ship", test => {
|
testing("Ship", test => {
|
||||||
test.case("creates a full name", check => {
|
test.case("creates a full name", check => {
|
||||||
let ship = new Ship();
|
let ship = new Ship();
|
||||||
|
@ -192,4 +208,3 @@ module TK.SpaceTac.Specs {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,28 @@
|
||||||
/// <reference path="../common/RObject.ts" />
|
import { RandomGenerator } from "../common/RandomGenerator"
|
||||||
|
import { RObject, RObjectContainer } from "../common/RObject"
|
||||||
|
import { bool, cfilter, flatten, keys, sum } from "../common/Tools"
|
||||||
|
import { ActionList } from "./actions/ActionList"
|
||||||
|
import { BaseAction } from "./actions/BaseAction"
|
||||||
|
import { ToggleAction } from "./actions/ToggleAction"
|
||||||
|
import { ArenaLocationAngle } from "./ArenaLocation"
|
||||||
|
import { Battle } from "./Battle"
|
||||||
|
import { BaseBattleDiff } from "./diffs/BaseBattleDiff"
|
||||||
|
import { ShipDeathDiff } from "./diffs/ShipDeathDiff"
|
||||||
|
import { ShipEffectRemovedDiff } from "./diffs/ShipEffectAddedDiff"
|
||||||
|
import { ShipValueDiff } from "./diffs/ShipValueDiff"
|
||||||
|
import { AttributeEffect } from "./effects/AttributeEffect"
|
||||||
|
import { AttributeLimitEffect } from "./effects/AttributeLimitEffect"
|
||||||
|
import { AttributeMultiplyEffect } from "./effects/AttributeMultiplyEffect"
|
||||||
|
import { BaseEffect } from "./effects/BaseEffect"
|
||||||
|
import { StickyEffect } from "./effects/StickyEffect"
|
||||||
|
import { Fleet } from "./Fleet"
|
||||||
|
import { ShipModel, ShipUpgrade } from "./models/ShipModel"
|
||||||
|
import { Personality } from "./Personality"
|
||||||
|
import { Player } from "./Player"
|
||||||
|
import { ShipLevel } from "./ShipLevel"
|
||||||
|
import { ShipAttributes, ShipValues, SHIP_VALUES, SHIP_VALUES_DESCRIPTIONS } from "./ShipValue"
|
||||||
|
import { Target } from "./Target"
|
||||||
|
|
||||||
module TK.SpaceTac {
|
|
||||||
/**
|
/**
|
||||||
* A single ship in a fleet
|
* A single ship in a fleet
|
||||||
*/
|
*/
|
||||||
|
@ -438,4 +460,3 @@ module TK.SpaceTac {
|
||||||
return sources ? (result + "\n\n" + sources) : result;
|
return sources ? (result + "\n\n" + sources) : result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { testing } from "../common/Testing";
|
||||||
|
import { ShipModel } from "./models/ShipModel";
|
||||||
|
import { ShipGenerator } from "./ShipGenerator";
|
||||||
|
|
||||||
testing("ShipGenerator", test => {
|
testing("ShipGenerator", test => {
|
||||||
test.case("can use ship model", check => {
|
test.case("can use ship model", check => {
|
||||||
var gen = new ShipGenerator();
|
var gen = new ShipGenerator();
|
||||||
|
@ -8,4 +11,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.same(ship.level.get(), 3);
|
check.same(ship.level.get(), 3);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
module TK.SpaceTac {
|
import { RandomGenerator } from "../common/RandomGenerator";
|
||||||
|
import { ShipModel } from "./models/ShipModel";
|
||||||
|
import { Ship } from "./Ship";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generator of random ship
|
* Generator of random ship
|
||||||
*/
|
*/
|
||||||
|
@ -46,4 +49,3 @@ module TK.SpaceTac {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { testing } from "../common/Testing";
|
||||||
|
import { ShipLevel } from "./ShipLevel";
|
||||||
|
|
||||||
testing("ShipLevel", test => {
|
testing("ShipLevel", test => {
|
||||||
test.case("level up from experience points", check => {
|
test.case("level up from experience points", check => {
|
||||||
let level = new ShipLevel();
|
let level = new ShipLevel();
|
||||||
|
@ -67,4 +69,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(level.getUpgrades(), []);
|
check.equals(level.getUpgrades(), []);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
module TK.SpaceTac {
|
import { imap, irange, isum } from "../common/Iterators";
|
||||||
|
import { acopy, add, contains, remove } from "../common/Tools";
|
||||||
|
import { ShipUpgrade } from "./models/ShipModel";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Level and experience system for a ship, with enabled upgrades.
|
* Level and experience system for a ship, with enabled upgrades.
|
||||||
*/
|
*/
|
||||||
|
@ -116,4 +119,3 @@ module TK.SpaceTac {
|
||||||
this.upgrades = [];
|
this.upgrades = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
module TK.SpaceTac {
|
import { testing } from "../common/Testing";
|
||||||
|
import { ShipAttribute } from "./ShipValue";
|
||||||
|
|
||||||
testing("ShipAttribute", test => {
|
testing("ShipAttribute", test => {
|
||||||
test.case("applies cumulative, multiplier and limit", check => {
|
test.case("applies cumulative, multiplier and limit", check => {
|
||||||
let attribute = new ShipAttribute();
|
let attribute = new ShipAttribute();
|
||||||
|
@ -44,4 +46,3 @@ module TK.SpaceTac {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
module TK.SpaceTac {
|
import { min, remove, sum } from "../common/Tools"
|
||||||
|
|
||||||
type ShipValuesMapping = {
|
type ShipValuesMapping = {
|
||||||
[P in (keyof ShipValues | keyof ShipAttributes)]: string
|
[P in (keyof ShipValues | keyof ShipAttributes)]: string
|
||||||
}
|
}
|
||||||
|
@ -152,4 +153,3 @@ module TK.SpaceTac {
|
||||||
export function isShipAttribute(key: string): key is keyof ShipAttributes {
|
export function isShipAttribute(key: string): key is keyof ShipAttributes {
|
||||||
return SHIP_ATTRIBUTES.hasOwnProperty(key);
|
return SHIP_ATTRIBUTES.hasOwnProperty(key);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { testing } from "../common/Testing";
|
||||||
|
import { Mission } from "./missions/Mission";
|
||||||
|
import { Player } from "./Player";
|
||||||
|
import { Shop } from "./Shop";
|
||||||
|
import { StarLocation } from "./StarLocation";
|
||||||
|
import { Universe } from "./Universe";
|
||||||
|
|
||||||
testing("Shop", test => {
|
testing("Shop", test => {
|
||||||
test.case("generates secondary missions", check => {
|
test.case("generates secondary missions", check => {
|
||||||
let universe = new Universe();
|
let universe = new Universe();
|
||||||
|
@ -36,4 +42,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.same(mission.fleet, player.fleet);
|
check.same(mission.fleet, player.fleet);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
module TK.SpaceTac {
|
import { RandomGenerator } from "../common/RandomGenerator";
|
||||||
|
import { contains, remove } from "../common/Tools";
|
||||||
|
import { Mission } from "./missions/Mission";
|
||||||
|
import { MissionGenerator } from "./missions/MissionGenerator";
|
||||||
|
import { Player } from "./Player";
|
||||||
|
import { StarLocation } from "./StarLocation";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A shop is a place to buy/sell equipments
|
* A shop is a place to buy/sell equipments
|
||||||
*/
|
*/
|
||||||
|
@ -48,4 +54,3 @@ module TK.SpaceTac {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -1,4 +1,8 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { testing } from "../common/Testing";
|
||||||
|
import { Star } from "./Star";
|
||||||
|
import { StarLink } from "./StarLink";
|
||||||
|
import { Universe } from "./Universe";
|
||||||
|
|
||||||
testing("Star", test => {
|
testing("Star", test => {
|
||||||
test.case("lists links to other stars", check => {
|
test.case("lists links to other stars", check => {
|
||||||
var universe = new Universe();
|
var universe = new Universe();
|
||||||
|
@ -33,4 +37,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.contains(neighbors, universe.stars[3]);
|
check.contains(neighbors, universe.stars[3]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
module TK.SpaceTac {
|
import { RandomGenerator } from "../common/RandomGenerator";
|
||||||
|
import { nna } from "../common/Tools";
|
||||||
|
import { StarLink } from "./StarLink";
|
||||||
|
import { StarLocation, StarLocationType } from "./StarLocation";
|
||||||
|
import { Universe } from "./Universe";
|
||||||
|
|
||||||
// A star system
|
// A star system
|
||||||
export class Star {
|
export class Star {
|
||||||
|
|
||||||
|
@ -195,4 +200,3 @@ module TK.SpaceTac {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { testing } from "../common/Testing";
|
||||||
|
import { Star } from "./Star";
|
||||||
|
import { StarLink } from "./StarLink";
|
||||||
|
|
||||||
testing("StarLink", test => {
|
testing("StarLink", test => {
|
||||||
test.case("checks link intersection", check => {
|
test.case("checks link intersection", check => {
|
||||||
var star1 = new Star(null, 0, 0);
|
var star1 = new Star(null, 0, 0);
|
||||||
|
@ -35,4 +38,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.equals(link1.getPeer(star3), null);
|
check.equals(link1.getPeer(star3), null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
module TK.SpaceTac {
|
import { Star } from "./Star";
|
||||||
|
|
||||||
// An hyperspace link between two star systems
|
// An hyperspace link between two star systems
|
||||||
export class StarLink {
|
export class StarLink {
|
||||||
// Stars
|
// Stars
|
||||||
|
@ -46,4 +47,3 @@ module TK.SpaceTac {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
module TK.SpaceTac.Specs {
|
import { SkewedRandomGenerator } from "../common/RandomGenerator";
|
||||||
|
import { testing } from "../common/Testing";
|
||||||
|
import { nn } from "../common/Tools";
|
||||||
|
import { Fleet } from "./Fleet";
|
||||||
|
import { StarLocation, StarLocationType } from "./StarLocation";
|
||||||
|
|
||||||
testing("StarLocation", test => {
|
testing("StarLocation", test => {
|
||||||
test.case("removes generated encounters that lose", check => {
|
test.case("removes generated encounters that lose", check => {
|
||||||
var location = new StarLocation(undefined, StarLocationType.PLANET, 0, 0);
|
var location = new StarLocation(undefined, StarLocationType.PLANET, 0, 0);
|
||||||
|
@ -34,4 +39,3 @@ module TK.SpaceTac.Specs {
|
||||||
check.notequals(location.encounter, null);
|
check.notequals(location.encounter, null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
/// <reference path="../common/RObject.ts" />
|
import { RandomGenerator } from "../common/RandomGenerator"
|
||||||
|
import { RObject } from "../common/RObject"
|
||||||
|
import { add, remove } from "../common/Tools"
|
||||||
|
import { Battle } from "./Battle"
|
||||||
|
import { BattleOutcome } from "./BattleOutcome"
|
||||||
|
import { Fleet } from "./Fleet"
|
||||||
|
import { FleetGenerator } from "./FleetGenerator"
|
||||||
|
import { Player } from "./Player"
|
||||||
|
import { Shop } from "./Shop"
|
||||||
|
import { Star } from "./Star"
|
||||||
|
import { Universe } from "./Universe"
|
||||||
|
|
||||||
module TK.SpaceTac {
|
|
||||||
export enum StarLocationType {
|
export enum StarLocationType {
|
||||||
STAR,
|
STAR,
|
||||||
WARP,
|
WARP,
|
||||||
|
@ -178,4 +187,3 @@ module TK.SpaceTac {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|