diff --git a/DEV README.md b/DEV README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/README.md b/README.md
index 2ca4843a..cd603247 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,17 @@
+About
+
+License
+
+Development
+
+
+
+#Ship and Component Database
+
+See Data Readme for details on structure, etc.
+
+Please submit issues, or better yet pull requests for any corrections or additions to the database.
+
+Feature Requests and To Do List
-To do
\ No newline at end of file
diff --git a/app/fonts/eurocaps-webfont.eot b/app/fonts/eurocaps-webfont.eot
new file mode 100755
index 00000000..2b3d2316
Binary files /dev/null and b/app/fonts/eurocaps-webfont.eot differ
diff --git a/app/fonts/eurocaps-webfont.svg b/app/fonts/eurocaps-webfont.svg
new file mode 100755
index 00000000..a78ee3da
--- /dev/null
+++ b/app/fonts/eurocaps-webfont.svg
@@ -0,0 +1,913 @@
+
+
+
\ No newline at end of file
diff --git a/app/fonts/eurocaps-webfont.ttf b/app/fonts/eurocaps-webfont.ttf
new file mode 100755
index 00000000..e3655504
Binary files /dev/null and b/app/fonts/eurocaps-webfont.ttf differ
diff --git a/app/fonts/eurocaps-webfont.woff b/app/fonts/eurocaps-webfont.woff
new file mode 100755
index 00000000..02d19df9
Binary files /dev/null and b/app/fonts/eurocaps-webfont.woff differ
diff --git a/app/fonts/eurocaps-webfont.woff2 b/app/fonts/eurocaps-webfont.woff2
new file mode 100755
index 00000000..a1ab7f50
Binary files /dev/null and b/app/fonts/eurocaps-webfont.woff2 differ
diff --git a/app/fonts/sintony-bold-webfont.eot b/app/fonts/sintony-bold-webfont.eot
new file mode 100755
index 00000000..920e5d7c
Binary files /dev/null and b/app/fonts/sintony-bold-webfont.eot differ
diff --git a/app/fonts/sintony-bold-webfont.svg b/app/fonts/sintony-bold-webfont.svg
new file mode 100755
index 00000000..3b2cf998
--- /dev/null
+++ b/app/fonts/sintony-bold-webfont.svg
@@ -0,0 +1,408 @@
+
+
+
\ No newline at end of file
diff --git a/app/fonts/sintony-bold-webfont.ttf b/app/fonts/sintony-bold-webfont.ttf
new file mode 100755
index 00000000..ed1ab017
Binary files /dev/null and b/app/fonts/sintony-bold-webfont.ttf differ
diff --git a/app/fonts/sintony-bold-webfont.woff b/app/fonts/sintony-bold-webfont.woff
new file mode 100755
index 00000000..b1e7cbfe
Binary files /dev/null and b/app/fonts/sintony-bold-webfont.woff differ
diff --git a/app/fonts/sintony-bold-webfont.woff2 b/app/fonts/sintony-bold-webfont.woff2
new file mode 100755
index 00000000..dfed6ffb
Binary files /dev/null and b/app/fonts/sintony-bold-webfont.woff2 differ
diff --git a/app/fonts/sintony-regular-webfont.eot b/app/fonts/sintony-regular-webfont.eot
new file mode 100755
index 00000000..185fbec3
Binary files /dev/null and b/app/fonts/sintony-regular-webfont.eot differ
diff --git a/app/fonts/sintony-regular-webfont.svg b/app/fonts/sintony-regular-webfont.svg
new file mode 100755
index 00000000..b0e70197
--- /dev/null
+++ b/app/fonts/sintony-regular-webfont.svg
@@ -0,0 +1,411 @@
+
+
+
\ No newline at end of file
diff --git a/app/fonts/sintony-regular-webfont.ttf b/app/fonts/sintony-regular-webfont.ttf
new file mode 100755
index 00000000..187a1f87
Binary files /dev/null and b/app/fonts/sintony-regular-webfont.ttf differ
diff --git a/app/fonts/sintony-regular-webfont.woff b/app/fonts/sintony-regular-webfont.woff
new file mode 100755
index 00000000..661e19df
Binary files /dev/null and b/app/fonts/sintony-regular-webfont.woff differ
diff --git a/app/fonts/sintony-regular-webfont.woff2 b/app/fonts/sintony-regular-webfont.woff2
new file mode 100755
index 00000000..4ff7b7ee
Binary files /dev/null and b/app/fonts/sintony-regular-webfont.woff2 differ
diff --git a/app/images/crosshairs.svg b/app/images/crosshairs.svg
deleted file mode 100644
index 404d66f2..00000000
--- a/app/images/crosshairs.svg
+++ /dev/null
@@ -1,148 +0,0 @@
-
-
-
diff --git a/app/images/docking-bay.jpg b/app/images/docking-bay.jpg
new file mode 100644
index 00000000..a6aea6a9
Binary files /dev/null and b/app/images/docking-bay.jpg differ
diff --git a/app/images/github-mark.svg b/app/images/icons/github-mark.svg
similarity index 100%
rename from app/images/github-mark.svg
rename to app/images/icons/github-mark.svg
diff --git a/app/images/icons/logo.svg b/app/images/icons/logo.svg
new file mode 100644
index 00000000..891daf63
--- /dev/null
+++ b/app/images/icons/logo.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/app/images/icons/mount-f.svg b/app/images/icons/mount-f.svg
new file mode 100644
index 00000000..e0f58cf8
--- /dev/null
+++ b/app/images/icons/mount-f.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/app/images/icons/mount-g.svg b/app/images/icons/mount-g.svg
new file mode 100644
index 00000000..d77e4129
--- /dev/null
+++ b/app/images/icons/mount-g.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/app/images/icons/mount-t.svg b/app/images/icons/mount-t.svg
new file mode 100644
index 00000000..1daf2b89
--- /dev/null
+++ b/app/images/icons/mount-t.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/app/images/reddit.svg b/app/images/icons/reddit.svg
similarity index 100%
rename from app/images/reddit.svg
rename to app/images/icons/reddit.svg
diff --git a/app/images/logo/android-chrome-144x144.png b/app/images/logo/android-chrome-144x144.png
new file mode 100644
index 00000000..e1862dcd
Binary files /dev/null and b/app/images/logo/android-chrome-144x144.png differ
diff --git a/app/images/logo/android-chrome-192x192.png b/app/images/logo/android-chrome-192x192.png
new file mode 100644
index 00000000..7064713b
Binary files /dev/null and b/app/images/logo/android-chrome-192x192.png differ
diff --git a/app/images/logo/android-chrome-72x72.png b/app/images/logo/android-chrome-72x72.png
new file mode 100644
index 00000000..6a25c5d1
Binary files /dev/null and b/app/images/logo/android-chrome-72x72.png differ
diff --git a/app/images/logo/android-chrome-96x96.png b/app/images/logo/android-chrome-96x96.png
new file mode 100644
index 00000000..d1242e9f
Binary files /dev/null and b/app/images/logo/android-chrome-96x96.png differ
diff --git a/app/images/logo/apple-touch-icon-114x114.png b/app/images/logo/apple-touch-icon-114x114.png
new file mode 100644
index 00000000..27b67606
Binary files /dev/null and b/app/images/logo/apple-touch-icon-114x114.png differ
diff --git a/app/images/logo/apple-touch-icon-120x120.png b/app/images/logo/apple-touch-icon-120x120.png
new file mode 100644
index 00000000..ddf4300e
Binary files /dev/null and b/app/images/logo/apple-touch-icon-120x120.png differ
diff --git a/app/images/logo/apple-touch-icon-144x144.png b/app/images/logo/apple-touch-icon-144x144.png
new file mode 100644
index 00000000..0b81c09a
Binary files /dev/null and b/app/images/logo/apple-touch-icon-144x144.png differ
diff --git a/app/images/logo/apple-touch-icon-152x152.png b/app/images/logo/apple-touch-icon-152x152.png
new file mode 100644
index 00000000..90177df4
Binary files /dev/null and b/app/images/logo/apple-touch-icon-152x152.png differ
diff --git a/app/images/logo/apple-touch-icon-180x180.png b/app/images/logo/apple-touch-icon-180x180.png
new file mode 100644
index 00000000..dfd4f3d7
Binary files /dev/null and b/app/images/logo/apple-touch-icon-180x180.png differ
diff --git a/app/images/logo/apple-touch-icon-76x76.png b/app/images/logo/apple-touch-icon-76x76.png
new file mode 100644
index 00000000..42f75610
Binary files /dev/null and b/app/images/logo/apple-touch-icon-76x76.png differ
diff --git a/app/images/logo/apple-touch-icon-precomposed.png b/app/images/logo/apple-touch-icon-precomposed.png
new file mode 100644
index 00000000..e7c8e768
Binary files /dev/null and b/app/images/logo/apple-touch-icon-precomposed.png differ
diff --git a/app/images/logo/apple-touch-icon.png b/app/images/logo/apple-touch-icon.png
new file mode 100644
index 00000000..dfd4f3d7
Binary files /dev/null and b/app/images/logo/apple-touch-icon.png differ
diff --git a/app/images/logo/browserconfig.xml b/app/images/logo/browserconfig.xml
new file mode 100644
index 00000000..affe1f0d
--- /dev/null
+++ b/app/images/logo/browserconfig.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+ #da532c
+
+
+
diff --git a/app/images/logo/favicon-194x194.png b/app/images/logo/favicon-194x194.png
new file mode 100644
index 00000000..abf49469
Binary files /dev/null and b/app/images/logo/favicon-194x194.png differ
diff --git a/app/images/logo/favicon-96x96.png b/app/images/logo/favicon-96x96.png
new file mode 100644
index 00000000..125a80ab
Binary files /dev/null and b/app/images/logo/favicon-96x96.png differ
diff --git a/app/images/logo/favicon.ico b/app/images/logo/favicon.ico
new file mode 100644
index 00000000..3ca02f2c
Binary files /dev/null and b/app/images/logo/favicon.ico differ
diff --git a/app/images/logo/manifest.json b/app/images/logo/manifest.json
new file mode 100644
index 00000000..6cc4d886
--- /dev/null
+++ b/app/images/logo/manifest.json
@@ -0,0 +1,44 @@
+{
+ "name": "Shipyard",
+ "icons": [
+ {
+ "src": "images\/logo\/android-chrome-36x36.png",
+ "sizes": "36x36",
+ "type": "image\/png",
+ "density": "0.75"
+ },
+ {
+ "src": "images\/logo\/android-chrome-48x48.png",
+ "sizes": "48x48",
+ "type": "image\/png",
+ "density": "1.0"
+ },
+ {
+ "src": "images\/logo\/android-chrome-72x72.png",
+ "sizes": "72x72",
+ "type": "image\/png",
+ "density": "1.5"
+ },
+ {
+ "src": "images\/logo\/android-chrome-96x96.png",
+ "sizes": "96x96",
+ "type": "image\/png",
+ "density": "2.0"
+ },
+ {
+ "src": "images\/logo\/android-chrome-144x144.png",
+ "sizes": "144x144",
+ "type": "image\/png",
+ "density": "3.0"
+ },
+ {
+ "src": "images\/logo\/android-chrome-192x192.png",
+ "sizes": "192x192",
+ "type": "image\/png",
+ "density": "4.0"
+ }
+ ],
+ "start_url": "http:\/\/coriolis.io",
+ "display": "standalone",
+ "orientation": "portrait"
+}
diff --git a/app/images/logo/mstile-144x144.png b/app/images/logo/mstile-144x144.png
new file mode 100644
index 00000000..6915f3b4
Binary files /dev/null and b/app/images/logo/mstile-144x144.png differ
diff --git a/app/images/logo/mstile-150x150.png b/app/images/logo/mstile-150x150.png
new file mode 100644
index 00000000..309891bc
Binary files /dev/null and b/app/images/logo/mstile-150x150.png differ
diff --git a/app/images/logo/mstile-310x150.png b/app/images/logo/mstile-310x150.png
new file mode 100644
index 00000000..b0e7a968
Binary files /dev/null and b/app/images/logo/mstile-310x150.png differ
diff --git a/app/images/logo/mstile-310x310.png b/app/images/logo/mstile-310x310.png
new file mode 100644
index 00000000..f4c7877c
Binary files /dev/null and b/app/images/logo/mstile-310x310.png differ
diff --git a/app/images/logo/mstile-70x70.png b/app/images/logo/mstile-70x70.png
new file mode 100644
index 00000000..4df3eb02
Binary files /dev/null and b/app/images/logo/mstile-70x70.png differ
diff --git a/app/index.html b/app/index.html
index aa5d8db2..85108a4d 100644
--- a/app/index.html
+++ b/app/index.html
@@ -2,25 +2,38 @@
- Shipyard
-
+
+ Coriolis Shipyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/app/js/app.js b/app/js/app.js
index a57c80d8..bf1be2f5 100644
--- a/app/js/app.js
+++ b/app/js/app.js
@@ -1,12 +1,25 @@
-angular.module('app', ['ngRoute','shipyard','ngLodash','app.templates'])
-.config(['$routeProvider', function($routeProvider) {
- //$locationProvider.html5Mode(true);
+angular.module('app', ['ngRoute', 'shipyard', 'ngLodash', 'n3-line-chart', 'app.templates'])
+.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
+ $locationProvider.html5Mode(true);
$routeProvider
.when('/:ship', { templateUrl: 'views/ship.html', controller: 'ShipController' })
+ .when('/:ship/:code', { templateUrl: 'views/ship.html', controller: 'ShipController' })
.when('/', { templateUrl: 'views/ships.html', controller: 'ShipyardController' });
}])
-.run(['$rootScope','commonArray','shipPurpose', 'shipSize', 'hardPointClass', 'internalGroupMap', function ($rootScope, CArr, shipPurpose, sz, hpc, igMap) {
+.run(['$rootScope','$document','$location','$route','commonArray','shipPurpose','shipSize','hardPointClass','internalGroupMap', function ($rootScope, $doc, $loc, $route, CArr, shipPurpose, sz, hpc, igMap) {
+ // Allow URL changes without reloading controllers/view
+ var original = $loc.path;
+ $loc.path = function (path, reload) {
+ if (reload === false) {
+ var lastRoute = $route.current;
+ var un = $rootScope.$on('$locationChangeSuccess', function () {
+ $route.current = lastRoute;
+ un();
+ });
+ }
+ return original.apply($loc, [path]);
+ };
// Global Reference variables
$rootScope.CArr = CArr;
@@ -19,19 +32,18 @@ angular.module('app', ['ngRoute','shipyard','ngLodash','app.templates'])
// Formatters
$rootScope.fCrd = d3.format(',.0f');
$rootScope.fPwr = d3.format(',.2f');
- $rootScope.fMass = d3.format(',.2r');
- $rootScope.fPct = d3.format(',.2%');
+ $rootScope.fRound = function(d) { return d3.round(d, 2) };
+ $rootScope.fPct = d3.format('.2%');
+ $rootScope.fRPct = d3.format('%');
+ $rootScope.fTime = function(d) { return Math.floor(d/60) + ":" + ("00" + (d%60)).substr(-2,2); };
- $rootScope.calcJumpRange = function(mass, fsd, fuel) {
- return Math.pow( (fuel || fsd.maxfuel) / fsd.fuelmul, 1 / fsd.fuelpower ) * fsd.optmass / mass;
- };
+ // Global Event Listeners
+ $doc.bind('keyup', function (e) {
+ $rootScope.$broadcast('keyup', e);
+ });
- // TODO: Load Saved Ships List from Local Storage
-
- // TODO: Save Ship
-
- // TODO: Load Ship
-
- // TODO: Generate Link for Ship
+ $rootScope.bgClicked = function (e) {
+ $rootScope.$broadcast('bgClicked', e);
+ }
}]);
diff --git a/app/js/controllers/controller-ship.js b/app/js/controllers/controller-ship.js
index e7055bb5..268f0e56 100644
--- a/app/js/controllers/controller-ship.js
+++ b/app/js/controllers/controller-ship.js
@@ -1,10 +1,61 @@
angular.module('app')
-.controller('ShipController', ['$scope', '$routeParams','ShipFactory', 'components', function ($scope, $p, ShipFactory, Components) {
+.controller('ShipController', ['$rootScope','$scope', '$routeParams', '$location', 'ShipFactory', 'components', function ($rootScope, $scope, $p, $loc, ShipFactory, Components) {
$scope.shipId = $p.ship;
- $scope.ship = ShipFactory($scope.shipId, DB.ships[$scope.shipId]);
- $scope.availCS = Components.forShip($scope.shipId);
+ // TODO: show 404 if ship not found.
+ var ship = ShipFactory($scope.shipId, DB.ships[$scope.shipId], $p.code);
+ $scope.ship = ship;
+ $scope.pp = ship.common[0]; // Power Plant
+ $scope.th = ship.common[1]; // Thruster
+ $scope.fsd = ship.common[2]; // Frame Shrift Drive
+ $scope.ls = ship.common[3]; // Life Support
+ $scope.pd = ship.common[4]; // Power Distributor
+ $scope.ss = ship.common[5]; // Sensors
+ $scope.ft = ship.common[6]; // Fuel Tank
+ $scope.hps = ship.hardpoints;
+ $scope.internal = ship.internal;
+ $scope.availCS = Components.forShip($scope.shipId);
+ $scope.selectedSlot = null;
// for debugging
- //window.ship = $scope.ship;
- //window.availcs = $scope.availCS;
-}]);
\ No newline at end of file
+ window.ship = ship;
+ window.availcs = $scope.availCS;
+
+ $scope.selectSlot = function(e, slot) {
+ e.stopPropagation();
+ if ($scope.selectedSlot == slot) {
+ $scope.selectedSlot = null;
+ } else {
+ $scope.selectedSlot = slot;
+ }
+ };
+
+ $scope.selectComponent = function(slot, id, component) {
+ ship.use(slot, id, component);
+ $scope.selectedSlot = null;
+ $loc.path(ship.id + '/' + ship.code, false).replace();
+ }
+
+ $scope.hideMenus = function() {
+ $scope.selectedSlot = null;
+ }
+
+ $rootScope.$on('keyup', function (e, keyEvent) {
+ if(keyEvent.keyCode == 27) { // on Escape
+ $scope.hideMenus();
+ $scope.$apply();
+ }
+ // TODO: CTRL+S -> Save
+ });
+
+ $rootScope.$on('bgClicked', function (e, keyEvent) {
+ $scope.hideMenus();
+ });
+
+ // TODO: Save build
+ // TODO: name build + save
+ // Push new url history in this case
+ // TODO: delete build
+ // TODO: reset to ship defaults
+ // TODO: revert to last save
+
+}]);
diff --git a/app/js/directives/directive-component-select.js b/app/js/directives/directive-component-select.js
index fcb2e0af..e6abb4c9 100644
--- a/app/js/directives/directive-component-select.js
+++ b/app/js/directives/directive-component-select.js
@@ -2,15 +2,14 @@ angular.module('app').directive('componentSelect', [ function() {
return {
restrict: 'A',
scope:{
- opts: '=',
- c: '=',
- ship: '='
+ opts: '=', // Component Options object
+ slot: '=', // Slot Object
+ selectComponent: '&sc' // Select Component function
},
templateUrl: 'views/component_select.html',
link: function (scope) {
- scope.use = function(id, componentData) {
- scope.ship.use(scope.c, id, componentData);
- // hide this shit;
+ scope.use = function(id, component) {
+ scope.selectComponent({s: scope.slot, id: id, c: component});
};
}
};
diff --git a/app/js/directives/directive-hardpoint.js b/app/js/directives/directive-hardpoint.js
new file mode 100644
index 00000000..dfc6011e
--- /dev/null
+++ b/app/js/directives/directive-hardpoint.js
@@ -0,0 +1,14 @@
+angular.module('app').directive('hardpoint', ['$rootScope', function ($r) {
+ return {
+ restrict: 'A',
+ scope:{
+ hp: '=',
+ size: '=',
+ opts: '='
+ },
+ templateUrl: 'views/hardpoint.html',
+ link: function (scope) {
+ scope.$r = $r;
+ }
+ };
+}]);
\ No newline at end of file
diff --git a/app/js/directives/directive-list-cost.js b/app/js/directives/directive-list-cost.js
index e2c23ae2..5f89474b 100644
--- a/app/js/directives/directive-list-cost.js
+++ b/app/js/directives/directive-list-cost.js
@@ -6,6 +6,7 @@ angular.module('app').directive('costList', ['$rootScope', function ($r) {
},
templateUrl: 'views/costs.html',
link: function (scope) {
+ scope.expanded = false;
scope.$r = $r;
scope.insuranceOptions = {
Alpha: 0.975,
@@ -14,6 +15,10 @@ angular.module('app').directive('costList', ['$rootScope', function ($r) {
};
scope.insurance = scope.insuranceOptions.Standard;
+ scope.toggleExpand = function() {
+ scope.expanded = !scope.expanded;
+ }
+
scope.toggle = function(item) {
item.incCost = !item.incCost;
scope.ship.updateTotals();
diff --git a/app/js/directives/directive-list-power.js b/app/js/directives/directive-list-power.js
index 00721158..11b74ee5 100644
--- a/app/js/directives/directive-list-power.js
+++ b/app/js/directives/directive-list-power.js
@@ -7,8 +7,13 @@ angular.module('app')
},
templateUrl: 'views/power.html',
link: function (scope) {
+ scope.expanded = false;
scope.$r = $r;
+ scope.toggleExpand = function() {
+ scope.expanded = !scope.expanded;
+ }
+
scope.toggle = function(slot) {
slot.enabled = !slot.enabled;
scope.ship.updateTotals();
diff --git a/app/js/directives/directive-meter.js b/app/js/directives/directive-meter.js
new file mode 100644
index 00000000..395b59f6
--- /dev/null
+++ b/app/js/directives/directive-meter.js
@@ -0,0 +1,77 @@
+angular.module('app').directive('meter', function () {
+ return {
+ restrict: 'A',
+ scope: {
+ labels: '=',
+ keys: '=',
+ obj: '=',
+ max: '='
+ },
+ link: function (scope, element) {
+ var max = scope.max,
+ w = 90,
+ pLeft = 1,
+ pBottom = 2,
+ labelWidth = 45,
+ bHeight = 16,
+ bWidth = ((w - labelWidth) / max) - pLeft,
+ h = bHeight * scope.keys.length;
+
+ var data = [];
+
+ for(var i = 0; i < scope.keys.length; i++) {
+ data.push({name:scope.labels[i], val: scope.obj[scope.keys[i]]});
+ }
+
+ var svg = d3.select(element[0])
+ .append('svg')
+ .attr('width', w)
+ .attr('height', h)
+ .attr('viewBox', '0 0 ' + w + ' ' + h)
+ .attr('class', 'meter')
+ .attr('preserveAspectRatio', 'xMinYMin');
+
+ svg.selectAll("g").data(data)
+ .enter()
+ .append("g")
+ .attr('transform', function(d, i) {
+ return 'translate(' + labelWidth + ' ' + (i * bHeight) + ')';
+ })
+ .each(function(d, k) {
+ var g = d3.select(this);
+ for (var i = 0; i < max; i++) {
+ g.append('rect')
+ .attr("x", i * (bWidth + pLeft))
+ .attr("y", 0)
+ .attr("width", bWidth)
+ .attr("height", bHeight - pBottom);
+ }
+ });
+
+ svg.selectAll("text").data(data)
+ .enter()
+ .append('text')
+ .text(function(d) {
+ return d.name;
+ })
+ .attr("text-anchor", "end")
+ .attr("x", labelWidth - 3)
+ .attr("y", function(d, i) {
+ return (i * bHeight) + (bHeight) / 2;
+ });
+
+ function update() {
+ for(var i = 0; i < data.length; i++) {
+ data[i].val = scope.obj[scope.keys[i]];
+ }
+
+ svg.selectAll("g").data(data)
+ .selectAll('rect').attr('class', function(d, i) {
+ return (i + 1 <= d.val) ? 'active' : '';
+ });
+ }
+
+ scope.$watch('obj',update);
+ }
+ };
+});
\ No newline at end of file
diff --git a/app/js/directives/directive-ship-range.js b/app/js/directives/directive-ship-range.js
new file mode 100644
index 00000000..3be79cdd
--- /dev/null
+++ b/app/js/directives/directive-ship-range.js
@@ -0,0 +1,52 @@
+angular.module('app').directive('shipRange', ['$rootScope','CalcJumpRange', function ($r, calcJumpRange) {
+
+ return {
+ restrict: 'A',
+ scope:{
+ ship: '='
+ },
+ templateUrl: 'views/ship-range.html',
+ link: function(scope, element) {
+ scope.$r = $r;
+ scope.expanded = false;
+ var fsd = scope.ship.common[2].c;
+
+ scope.toggleExpand = function() {
+ scope.expanded = !scope.expanded;
+ }
+
+ function ranges(fsd, unladenMass, ladenMass) {
+ var ranges = [];
+ for(var m = unladenMass; m <= ladenMass; m++) {
+ ranges.push({x:m, y: calcJumpRange(m, fsd)});
+ }
+ return ranges;
+ }
+
+ //var fDist = d3.format(',.2f');
+
+ //scope.data = ranges(fsd, scope.ship.unladenMass, scope.ship.ladenMass);
+ /*scope.options = {
+ axes: {
+ x: {key: 'x', type: 'linear', ticks: 10},
+ y: {type: 'linear', ticks: 5, }
+ },
+ series: [
+ {y: 'y', color: '#FF8C0D', thickness: '2px', type: 'area', striped: false, label: 'Range'}
+ ],
+ lineMode: 'basis',
+ tension: 0.7,
+ tooltip: {
+ mode: 'scrubber',
+
+ formatter: function(x, y, series) {
+ return fDist(y) + ' Light Years';
+ }
+ },
+ drawLegend: false,
+ drawDots: false,
+ columnsHGap: 5
+ };*/
+ }
+ };
+}]);
diff --git a/app/js/directives/directive-slot-details.js b/app/js/directives/directive-slot-details.js
index 5759c0c3..5e8c39f5 100644
--- a/app/js/directives/directive-slot-details.js
+++ b/app/js/directives/directive-slot-details.js
@@ -1,4 +1,4 @@
-angular.module('app').directive('slotDetails', function () {
+angular.module('app').directive('slotDetails', ['$rootScope', function ($r) {
return {
restrict: 'A',
scope:{
@@ -6,6 +6,9 @@ angular.module('app').directive('slotDetails', function () {
lbl: '=',
opts: '='
},
- templateUrl: 'views/slot.html'
+ templateUrl: 'views/slot.html',
+ link: function(scope) {
+ scope.$r = $r;
+ }
};
-});
\ No newline at end of file
+}]);
\ No newline at end of file
diff --git a/app/js/shipyard/factory-components.js b/app/js/shipyard/factory-components.js
index 1415bd61..33b68517 100644
--- a/app/js/shipyard/factory-components.js
+++ b/app/js/shipyard/factory-components.js
@@ -65,6 +65,12 @@ angular.module('shipyard').factory('components', ['lodash', function (_) {
return {
forShip: function (shipId) {
return new ComponentSet(shipId);
+ },
+ findInternal: function(id) {
+ var c = _.find(C.internal, function(o) {
+ return o[id];
+ })
+ return c[id];
}
};
diff --git a/app/js/shipyard/factory-ship.js b/app/js/shipyard/factory-ship.js
index 9606e960..638b5428 100644
--- a/app/js/shipyard/factory-ship.js
+++ b/app/js/shipyard/factory-ship.js
@@ -1,4 +1,4 @@
-angular.module('shipyard').factory('ShipFactory', ['components', 'lodash', function (Components, _) {
+angular.module('shipyard').factory('ShipFactory', ['components', 'CalcShieldStrength', 'CalcJumpRange', 'lodash', function (Components, calcShieldStrength, calcJumpRange, _) {
/**
* Ship model used to track all ship components and properties.
@@ -13,26 +13,23 @@ angular.module('shipyard').factory('ShipFactory', ['components', 'lodash', funct
this.cargoScoop = { enabled: true, c: { name: 'Cargo Scoop', class: 1, rating: 'H', power: 0.6} };
this.sgSI = null; // Shield Generator Slot Index
+ // Copy all base properties from shipData
angular.forEach(shipData,function(o,k){
if(typeof o != 'object') {
this[k] = o;
- } else if (k == 'slotCap') {
- angular.forEach(o,function(arr,g){
- this[g] = [];
- for(var i = 0; i < arr.length; i++){
- this[g].push({
- enabled: true,
- incCost: true,
- maxClass: arr[i]
- });
- }
- }.bind(this));
+ }
+ }.bind(this));
+
+ angular.forEach(shipData.slotCap, function (slots, slotGroup) { // Initialize all slots
+ this[slotGroup] = []; // Initialize Slot group (Common, Hardpoints, Internal)
+ for(var i = 0; i < slots.length; i++){
+ this[slotGroup].push({id: null, c: null, enabled: true, incCost: true, maxClass: slots[i]});
}
}.bind(this));
}
/**
- * Reset the ship to the original purchase defaults.
+ * Reset the ship to the original 'manufacturer' defaults.
*/
Ship.prototype.clear = function() {
this.buildWith(DB.ships[this.id].defaultComponents);
@@ -58,7 +55,7 @@ angular.module('shipyard').factory('ShipFactory', ['components', 'lodash', funct
var availInternal = DB.components.internal;
var i,l;
- this.bulkheads = { incCost: true, id: comps.bulkheads || 0, c: DB.components.bulkheads[this.id][comps.bulkheads || 0] };
+ this.bulkheads = { incCost: true, maxClass: 8, id: comps.bulkheads || 0, c: DB.components.bulkheads[this.id][comps.bulkheads || 0] };
for(i = 0, l = comps.common.length; i < l; i++) {
common[i].id = comps.common[i];
@@ -75,9 +72,13 @@ angular.module('shipyard').factory('ShipFactory', ['components', 'lodash', funct
for(i = 0, l = comps.internal.length; i < l; i++) {
if(comps.internal[i] !== 0) {
internal[i].id = comps.internal[i];
- internal[i].c = availInternal[comps.internal[i]];
+ internal[i].c = Components.findInternal(comps.internal[i]);
+ if(internal[i].c.group == 'sg') {
+ this.sgSI = i;
+ }
}
}
+ this.code = this.toCode();
this.updateTotals();
};
@@ -105,7 +106,7 @@ angular.module('shipyard').factory('ShipFactory', ['components', 'lodash', funct
* @return {string} The id of the selected component or '-' if none selected
*/
function idToStr(slot) {
- return slot.id === undefined? '-' : slot.id;
+ return (slot.id === null)? '-' : slot.id;
}
/**
@@ -126,97 +127,53 @@ angular.module('shipyard').factory('ShipFactory', ['components', 'lodash', funct
// TODO: improve...
for (var i = 1, c = 0, l = code.length; i < l; i++) {
- if(code.charAt(i) != '-') {
- if (c < commonCount) {
- comps.common[c] = code.substring(i, i + 2);
- } else if (c < hpCount) {
- comps.hardpoints[c - commonCount] = code.substring(i, i + 2);
- } else {
- comps.internal[c - hpCount] = code.substring(i, i + 2);
- }
+ var isNull = code.charAt(i) == '-';
+ if (c < commonCount) {
+ comps.common[c] = isNull? 0 : code.substring(i, i + 2);
+ } else if (c < hpCount) {
+ comps.hardpoints[c - commonCount] = isNull? 0 : code.substring(i, i + 2);
+ } else {
+ comps.internal[c - hpCount] = isNull? 0 : code.substring(i, i + 2);
+ }
+ if (!isNull) {
i++;
}
c++;
}
-
this.defaults = comps;
- this.buildWidth(comps);
+ this.buildWith(comps);
};
/**
- * Updates the ship totals based on currently selected component in each slot.
+ * Updates the ship totals based on the components for every slot.
*/
Ship.prototype.updateTotals = function() {
var c = _.reduce(this.common, optsSum, {cost: 0, power: 0, mass: 0, capacity: 0});
- var i = _.reduce(this.internal, optsSum, {cost: 0, power: 0, mass: 0, capacity: 0});
- var h = _.reduce(this.hardpoints, optsSum, {cost: 0, power: 0, mass: 0, capacity: 0});
+ var i = _.reduce(this.internal, optsSum, {cost: 0, power: 0, mass: 0, capacity: 0, armouradd: 0});
+ var h = _.reduce(this.hardpoints, optsSum, {cost: 0, power: 0, mass: 0, shieldmul: 1});
+ var fsd = this.common[2].c; // Frame Shift Drive;
this.totalCost = c.cost + i.cost + h.cost + (this.incCost? this.cost : 0) + (this.bulkheads.incCost? this.bulkheads.c.cost : 0);
this.unladenMass = c.mass + i.mass + h.mass + this.mass + this.bulkheads.c.mass;
this.powerAvailable = this.common[0].c.pGen;
this.fuelCapacity = this.common[6].c.capacity;
+ this.maxMass = this.common[1].c.maxmass;
this.cargoCapacity = i.capacity;
this.ladenMass = this.unladenMass + this.cargoCapacity + this.fuelCapacity;
this.powerRetracted = c.power + i.power + (this.cargoScoop.enabled? this.cargoScoop.c.power : 0);
this.powerDeployed = this.powerRetracted + h.power;
-
- // TODO: range
- this.calcShieldStrength = this.sgSI !== null? calcShieldStrength(this.mass, this.shields, this.internal[this.sgSI], 1) : 0;
- this.armourAdded = 0; // internal.armoradd TODO: Armour (reinforcement, bulkheads)
- this.armorTotal = this.armourAdded + this.armour;
+ this.armourAdded = i.armouradd;
+ this.shieldMultiplier = h.shieldmul;
+ this.unladenJumpRange = calcJumpRange(this.unladenMass + fsd.maxfuel, fsd); // Include fuel weight for jump
+ this.ladenJumpRange = calcJumpRange(this.ladenMass, fsd);
+ this.shieldStrength = this.sgSI !== null? calcShieldStrength(this.mass, this.shields, this.internal[this.sgSI].c, this.shieldMultiplier) : 0;
+ this.armourTotal = this.armourAdded + this.armour;
+ // TODO: shield recharge rate
+ // TODO: armor bonus / damage reduction for bulkheads
+ // TODO: thermal load and weapon recharge rate
+ this.code = this.toCode();
};
- /**
- * Update a slot with a the component if the id is different from the current id for this slot.
- * Frees the slot of the current component if the id matches the current id for the slot.
- *
- * @param {object} slot The component slot
- * @param {string} id Unique ID for the selected component
- * @param {object} component Properties for the selected component
- */
- Ship.prototype.use = function(slot, id, component) {
- if (slot.id != id) { // Selecting a different component
- slot.id = id;
- slot.c = component;
-
- // Selected componnent is a Shield Generator
- if(component.group == 'sg') {
- var slotIndex = this.internal.indexOf(slot);
- // You can only have one shield Generator
- if (this.sgSI !== null && this.sgSI != slotIndex) {
- // A shield generator is already selected in a different slot
- this.internal[this.sgSI].id = null;
- this.internal[this.sgSI].c = null;
- }
- this.sgSI = slotIndex;
- }
- this.updateTotals();
- }
- };
-
- /**
- * Calculate the a ships shield strength based on mass, shield generator and shield boosters used.
- *
- * @private
- * @param {number} mass Current mass of the ship
- * @param {number} shields Base Shield strength MJ for ship
- * @param {object} sg The shield generator used
- * @param {number} multiplier Shield multiplier for ship (1 + shield boosters if any)
- * @return {number} Approximate shield strengh in MJ
- */
- function calcShieldStrength (mass, shields, sg, multiplier) {
- if (mass <= sg.minmass) {
- return shields * multiplier * sg.minmul;
- }
- if (mass < sg.optmass) {
- return shields * multiplier * (sg.minmul + (mass - sg.minmass) / (sg.optmass - sg.minmass) * (sg.optmul - sg.minmul));
- }
- if (mass < sg.maxmass) {
- return shields * multiplier * (sg.optmul + (mass - sg.optmass) / (sg.maxmass - sg.optmass) * (sg.maxmul - sg.optmul));
- }
- return shields * multiplier * sg.maxmul;
- }
-
/**
* Utilify function for summing the components properties
*
@@ -226,15 +183,61 @@ angular.module('shipyard').factory('ShipFactory', ['components', 'lodash', funct
* @return {object} The mutated sum object
*/
function optsSum(sum, slot) {
- if (slot.c) { // The slot has a component selected
- sum.cost += (slot.incCost && slot.c.cost)? slot.c.cost : 0;
- sum.power += (slot.enabled && slot.c.power)? slot.c.power : 0;
- sum.mass += slot.c.mass || 0;
- sum.capacity += slot.c.capacity || 0;
+ var c = slot.c
+ if (c) { // The slot has a component mounted
+ sum.cost += (slot.incCost && c.cost)? c.cost : 0;
+ sum.power += (slot.enabled && c.power)? c.power : 0;
+ sum.mass += c.mass || 0;
+ sum.capacity += c.capacity || 0;
+ sum.shieldmul += c.shieldmul || 0;
+ sum.armouradd += c.armouradd || 0;
}
return sum;
}
+ Ship.prototype.useBulkhead = function(index) {
+ this.bulkheads.id = index;
+ this.bulkheads.c = DB.components.bulkheads[this.id][index];
+ this.updateTotals(); // Update mass, range, shield strength, armor
+ }
+
+ /**
+ * Update a slot with a the component if the id is different from the current id for this slot.
+ * Frees the slot of the current component if the id matches the current id for the slot.
+ *
+ * @param {object} slot The component slot
+ * @param {string} id Unique ID for the selected component
+ * @param {object} component Properties for the selected component
+ */
+ Ship.prototype.use = function(slot, id, component) {
+ // TODO: only single refinery allowed
+ if (slot.id != id) { // Selecting a different component
+ slot.id = id;
+ slot.c = component;
+ var slotIndex = this.internal.indexOf(slot);
+ if(slot.id == null) { // Slot has been emptied
+ if(this.sgSI == slotIndex) { // The slot containing the shield generator was emptied
+ this.sgSI = null;
+ }
+ } else {
+ // Selected component is a Shield Generator
+ if(component.group == 'sg') {
+ // You can only have one shield Generator
+ if (this.sgSI !== null && this.sgSI != slotIndex) {
+ // A shield generator is already selected in a different slot
+ this.internal[this.sgSI].id = null;
+ this.internal[this.sgSI].c = null;
+ }
+ this.sgSI = slotIndex;
+ // Replacing a shield generator with something else
+ } else if (this.sgSI == slotIndex) {
+ this.sgSI = null;
+ }
+ }
+ this.updateTotals();
+ }
+ };
+
/**
* Ship Factory function. Created a new instance of a ship based on the ship type.
*
diff --git a/app/js/shipyard/module-shipyard.js b/app/js/shipyard/module-shipyard.js
index 877de58c..1813b675 100644
--- a/app/js/shipyard/module-shipyard.js
+++ b/app/js/shipyard/module-shipyard.js
@@ -94,4 +94,40 @@ angular.module('shipyard', [])
}
return groupToLabel;
- });
\ No newline at end of file
+ })
+ .factory('CalcJumpRange', function() {
+ /**
+ * Calculate the maximum single jump range based on mass and a specific FSD
+ * @param {number} mass Mass of a ship: laden, unlanden, partially laden, etc
+ * @param {object} fsd The FDS object/component with maxfuel, fuelmul, fuelpower, optmass
+ * @param {number} fuel Optional - The fuel consumed during the jump (must be less than the drives max fuel per jump)
+ * @return {number} Distance in Light Years
+ */
+ return function(mass, fsd, fuel) {
+ return Math.pow(Math.min(fuel || Infinity, fsd.maxfuel) / fsd.fuelmul, 1 / fsd.fuelpower ) * fsd.optmass / mass;
+ };
+ })
+ .factory('CalcShieldStrength', function() {
+ /**
+ * Calculate the a ships shield strength based on mass, shield generator and shield boosters used.
+ *
+ * @private
+ * @param {number} mass Current mass of the ship
+ * @param {number} shields Base Shield strength MJ for ship
+ * @param {object} sg The shield generator used
+ * @param {number} multiplier Shield multiplier for ship (1 + shield boosters if any)
+ * @return {number} Approximate shield strengh in MJ
+ */
+ return function (mass, shields, sg, multiplier) {
+ if (mass <= sg.minmass) {
+ return shields * multiplier * sg.minmul;
+ }
+ if (mass < sg.optmass) {
+ return shields * multiplier * (sg.minmul + (mass - sg.minmass) / (sg.optmass - sg.minmass) * (sg.optmul - sg.minmul));
+ }
+ if (mass < sg.maxmass) {
+ return shields * multiplier * (sg.optmul + (mass - sg.optmass) / (sg.maxmass - sg.optmass) * (sg.maxmul - sg.optmul));
+ }
+ return shields * multiplier * sg.maxmul;
+ }
+ });
diff --git a/app/less/app.less b/app/less/app.less
index 9b2dd712..3f6a4004 100644
--- a/app/less/app.less
+++ b/app/less/app.less
@@ -1,45 +1,83 @@
@import 'colors';
@import 'fonts';
@import 'utilities';
-@import 'logos';
+@import 'icons';
@import 'shipyard';
@import 'list';
-@import 'components';
+@import 'slot';
@import 'ship';
+@import 'charts';
+@import 'meters';
+
html, body {
min-height: 100%;
}
body {
- color: #FFF;
+ color: @fg;
background-color: #000;
margin: 0;
padding: 0;
- font-family: @standardFamily;
+ font-family: @fStandard;
overflow-x: hidden;
}
+#bg {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: -1;
+ opacity: 0.3;
+ //background-image: url(images/docking-bay.jpg);
+ //background-repeat: no-repeat;
+ //background-position: center;
+ //background-size: cover;
+}
+
#main {
- min-height: 90%;
+ margin: 10px;
+ min-height: 800px;
+ clear: both;
+}
+
+.l {
+ float: left;
+}
+
+.r {
+ float: right;
+}
+
+.cl {
+ clear: left;
+}
+
+.cr {
+ clear: right;
+}
+
+.cb {
clear: both;
}
header {
- background-color: @fg;
+ background-color: @bg;
margin: 0;
- height: 40px;
- line-height: 40px;
- font-family: @titleFamily;
+ height: 55px;
+ line-height: 55px;
+ font-family: @fTitle;
vertical-align: middle;
a {
vertical-align: middle;
- color: @border;
+ color: @warning;
&:visited {
- color: @border;
+ color: @warning;
}
&:hover {
color: teal;
diff --git a/app/less/charts.less b/app/less/charts.less
new file mode 100644
index 00000000..e87a040f
--- /dev/null
+++ b/app/less/charts.less
@@ -0,0 +1,8 @@
+
+svg {
+ .user-select-none();
+ display: block;
+ width:100%;
+ height:100%;
+}
+
diff --git a/app/less/colors.less b/app/less/colors.less
index ba286f8e..8174b195 100644
--- a/app/less/colors.less
+++ b/app/less/colors.less
@@ -1,3 +1,20 @@
-@fg: #FF8C0D; // Light Orange
+@fg: #fff;
+@bg: #333;
+@primary: #FF8C0D; // Light Orange
+@secondary: #32DBDB; // Light blue
@warning: #FF3B00; // Dark Orange
-@border: rgba(201,34,2,0.50); // Dark Red
\ No newline at end of file
+
+@bgDarken: 40%;
+@disabledDarken: 15%;
+@bgTransparency: 10%;
+
+@disabled: #888;
+@primary-disabled: darken(@primary, @disabledDarken);
+@secondary-disabled: darken(@primary, @disabledDarken);
+@warning-disabled: darken(@primary, @disabledDarken);
+
+@bgBlack: rgba(0,0,0,0.6);
+
+@primary-bg: fadeout(darken(@primary, 45%), 30%);
+@secondary-bg: fadeout(darken(@secondary, @bgDarken), @bgTransparency); // Brown background
+@warning-bg: fadeout(darken(@warning, @bgDarken), @bgTransparency); // Dark Red
diff --git a/app/less/components.less b/app/less/components.less
deleted file mode 100644
index 6c085187..00000000
--- a/app/less/components.less
+++ /dev/null
@@ -1,118 +0,0 @@
-
-.slot-group {
- border: 2px solid @border;
- .border-radius(5px);
- margin: 5px;
- float: left;
- padding: 0 5px 5px;
- user-select: none;
- -moz-user-select: none;
- -webkit-user-select: none;
- -ms-user-select: none;
-
- legend {
- text-transform: uppercase;
- padding: 0 5px;
- color: @warning;
- }
-
- .slot {
- text-transform: uppercase;
- float: left;
- margin: 1%;
- border: 1px solid orange;
- .border-radius(2px);
- width: 250px;
- position: relative;
- padding: 3px;
-
- color: #BBB;
- font-size: 0.8em;
-
- .lbl,.cla {
- color: #666;
- }
-
- .lbl {
- float: left;
- }
-
- .cla {
- float: right;
- }
-
- .clear {
- clear: both;
- }
-
- .select {
- z-index: 1;
- top: 100%;
- padding-top: 10px;
- display: none;
- position: absolute;
- width: 100%;
- margin: 0;
- padding: 0;
- background-color: black;
- border-left: 1px solid teal;
- border-bottom: 1px solid teal;
- border-right: 1px solid teal;
- .border-bottom-radius(5px);
- left: -1px;
- max-height: 600px;
- overflow-y: scroll;
- }
-
- .select-group {
- clear: both;
- border-top: 1px solid grey;
- border-bottom: 1px solid grey;
- padding-left: 5px;
- }
-
- .c {
- cursor: pointer;
- .border-radius(3px);
- display: block;
- float:left;
- margin: 5px;
- padding: 0;
- height: 20px;
- line-height: 20px;
- background-color: #666;
- color: #BBB;
-
- &:hover {
- background-color: teal;
- color: #FFF;
- }
- }
-
- li.c {
- width: 25px;
- text-align: center;
-
- &:nth-child(5n +1) {
- clear: left;
- }
- }
-
- ul {
- margin: 0;
- list-style: none;
- }
-
- &:hover {
- border: 1px solid teal;
- color: #FFF;
- .lbl,.cla {
- color: #999;
- }
- .select {
- display: block;
- }
- }
-
- }
-}
\ No newline at end of file
diff --git a/app/less/fonts.less b/app/less/fonts.less
index af9f8fda..99d3187f 100644
--- a/app/less/fonts.less
+++ b/app/less/fonts.less
@@ -34,7 +34,45 @@
font-style: normal;
}
+@font-face {
+ font-family: 'Sintony-Bold';
+ src: url('fonts/sintony-bold-webfont.eot');
+ src: url('fonts/sintony-bold-webfont.eot?#iefix') format('embedded-opentype'),
+ url('fonts/sintony-bold-webfont.woff2') format('woff2'),
+ url('fonts/sintony-bold-webfont.woff') format('woff'),
+ url('fonts/sintony-bold-webfont.ttf') format('truetype'),
+ url('fonts/sintony-bold-webfont.svg#sintonybold') format('svg');
+ font-weight: normal;
+ font-style: normal;
+
+}
+
+@font-face {
+ font-family: 'Sintony-Regular';
+ src: url('fonts/sintony-regular-webfont.eot');
+ src: url('fonts/sintony-regular-webfont.eot?#iefix') format('embedded-opentype'),
+ url('fonts/sintony-regular-webfont.woff2') format('woff2'),
+ url('fonts/sintony-regular-webfont.woff') format('woff'),
+ url('fonts/sintony-regular-webfont.ttf') format('truetype'),
+ url('fonts/sintony-regular-webfont.svg#sintonyregular') format('svg');
+ font-weight: normal;
+ font-style: normal;
+
+}
+
+@font-face {
+ font-family: 'eurocaps';
+ src: url('fonts/eurocaps-webfont.eot');
+ src: url('fonts/eurocaps-webfont.eot?#iefix') format('embedded-opentype'),
+ url('fonts/eurocaps-webfont.woff2') format('woff2'),
+ url('fonts/eurocaps-webfont.woff') format('woff'),
+ url('fonts/eurocaps-webfont.ttf') format('truetype'),
+ url('fonts/eurocaps-webfont.svg#euro_capsregular') format('svg');
+ font-weight: normal;
+ font-style: normal;
+
+}
+
+@fStandard: 'eurocaps', Helvetica, sans-serif;
+@fTitle: 'Orbitron-Regular', Arial, sans-serif;
-@standardFamily: Helvetica, sans-serif;
-@titleFamily: 'Orbitron-Medium', Arial, sans-serif;
-@itemFamily: 'Orbitron-Regular', Arial, sans-serif;
\ No newline at end of file
diff --git a/app/less/icons.less b/app/less/icons.less
new file mode 100644
index 00000000..a7ef7fc5
--- /dev/null
+++ b/app/less/icons.less
@@ -0,0 +1,43 @@
+
+.logo, .icon {
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: contain;
+}
+
+.icon {
+ width: 25px;
+ height: 25px;
+}
+
+.logo {
+ display: inline-block;
+ width: 50px;
+ height: 50px;
+}
+
+.mount-T {
+ background-image: url(images/icons/mount-t.svg);
+}
+.mount-F {
+ background-image: url(images/icons/mount-f.svg);
+}
+.mount-G {
+ background-image: url(images/icons/mount-g.svg);
+}
+
+.shipyard {
+ background-image: url(images/icons/logo.svg);
+}
+
+.github {
+ background-image: url(images/icons/github-mark.svg);
+}
+
+.reddit {
+ background-image: url(images/icons/reddit.svg);
+}
+
+.elite-dangerous {
+ background-image: url(images/ed-logo-sm.png);
+}
\ No newline at end of file
diff --git a/app/less/list.less b/app/less/list.less
index 658b1f53..ea72aa4f 100644
--- a/app/less/list.less
+++ b/app/less/list.less
@@ -1,61 +1,84 @@
.list {
- user-select: none;
- -moz-user-select: none;
- -webkit-user-select: none;
- -ms-user-select: none;
- float: left;
+ overflow: hidden;
+ padding: 5px;
+ cursor: default;
+ position: relative;
+ font-size: 0.8em;
- .list-item {
+ .header {
+ position: absolute;
+ width: 100%;
+ height: 1.6em;
+ font-family: @fTitle;
+ color: @primary;
+ text-transform: uppercase;
+ }
+ .items {
+ margin-top: 25px;
+ margin-bottom: 10px;
clear: both;
overflow: hidden;
- margin: 3px 0px;
+
+ .item {
+ clear: both;
+ margin: 1px 0 0;
+ overflow: hidden;
+
+ .val {
+ float:right;
+ text-align: right;
+ }
+
+ .lbl {
+ float: left;
+ }
+ color: @disabled;
+ cursor: pointer;
+
+ &:hover {
+ color: @warning-disabled;
+ }
+
+ &.enabled {
+ color: @fg;
+ &:hover {
+ color: @warning;
+ }
+ }
+
+ &.consumer {
+ .val:before {
+ content: "-";
+ }
+ }
+
+ &.untoggleable {
+ cursor: default;
+ }
+ }
}
- .val {
- float:right;
+ .summary {
+ font-family: @fStandard;
+ overflow: hidden;
text-align: right;
+
+ .item {
+ float:right;
+ width: 25%
+ }
+ .lbl {
+ font-family: @fTitle;
+ color: @primary;
+ text-transform: uppercase;
+ }
}
- .lbl {
- float: left;
+ &:nth-child(n+2) {
+ border-top: 1px solid @primary;
}
}
-#cost-list {
- color: grey;
- width: 300px;
-
- .list-item {
- cursor: pointer;
- }
-
- .enabled {
- color: #FFF;
- }
-}
-
-
-#power-list {
- color: grey;
- width: 300px;
-
- .enabled {
- color: #FFF;
- }
-
- .consumer {
- cursor: pointer;
- }
-
- .consumer.enabled {
- color: @fg;
- }
-
- .common, .internal, .hardpoints {
-
- }
-
-}
\ No newline at end of file
diff --git a/app/less/logos.less b/app/less/logos.less
deleted file mode 100644
index 91ebcfe2..00000000
--- a/app/less/logos.less
+++ /dev/null
@@ -1,23 +0,0 @@
-
-.logo {
- background-repeat: no-repeat;
- background-position: center;
- display: inline-block;
- width: 30px;
- height: 30px;
-}
-
-.github {
- background-image: url(images/github-mark.svg);
- background-size: contain;
-}
-
-.reddit {
- background-image: url(images/reddit.svg);
- background-size: contain;
-}
-
-.elite-dangerous {
- background-image: url(images/ed-logo-sm.png);
- background-size: contain;
-}
\ No newline at end of file
diff --git a/app/less/meters.less b/app/less/meters.less
new file mode 100644
index 00000000..f1da75af
--- /dev/null
+++ b/app/less/meters.less
@@ -0,0 +1,18 @@
+
+svg.meter {
+ text {
+ fill: @warning;
+ font-size: 15px;
+ font-family: @fStandard;
+ text-transform:uppercase;
+ alignment-baseline: middle;
+ }
+
+ rect {
+ fill: @disabled;
+
+ &.active {
+ fill: @warning;
+ }
+ }
+}
diff --git a/app/less/ship.less b/app/less/ship.less
index 5c854a0a..0842d98c 100644
--- a/app/less/ship.less
+++ b/app/less/ship.less
@@ -14,13 +14,61 @@
}
#hardpoints {
- width: 525px;
+ .slot:nth-child(2n) {
+ clear: left;
+ margin-right: 10px;
+ }
}
#standard {
- width: 265px;
+ .slot {
+ clear: left;
+ }
}
#internal {
- width: 525px;
-}
\ No newline at end of file
+ .slot {
+ clear: left;
+ }
+}
+
+#summary {
+ .user-select-none();
+ float: right;
+ width: 40%;
+ border-top: 2px solid @primary;
+ border-bottom: 2px solid @primary;
+ background-color: @primary-bg;
+}
+
+legend {
+ text-transform: uppercase;
+ padding: 0 5px;
+ color: @warning;
+ font-family: @fTitle;
+}
+
+fieldset {
+ user-select: none;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ cursor: default;
+ border: 2px solid @warning-bg;
+ .border-radius(5px);
+ margin: 5px;
+ padding: 1px 5px 5px;
+}
+
+.toggle {
+ cursor: pointer;
+}
+
+.expandable {
+ display: none;
+
+ &.expanded {
+ display: block;
+ }
+}
+
diff --git a/app/less/shipyard.less b/app/less/shipyard.less
index 06aa79a2..a3dfec82 100644
--- a/app/less/shipyard.less
+++ b/app/less/shipyard.less
@@ -5,26 +5,29 @@ a.ship {
width: 22%;
height: 30%;
margin: 1% 1%;
- background-color: #222;
+ background-color: @bg;
padding: 0.5%;
text-decoration: none;
- color: #FFF;
- font-family: @standardFamily;
+ color: @fg;
+ font-family: @fStandard;
+ text-align: right;
+ .user-select-none();
&:hover {
- background-color: @fg;
+ background-color: @secondary-bg;
}
h2 {
width: 100%;
text-transform: uppercase;
margin: 0;
- font-family: @titleFamily;
+ font-family: @fTitle;
+ text-align: left;
}
small {
color: @warning;
- font-family: @titleFamily;
+ font-family: @fTitle;
float: left;
font-size: 0.8em;
}
diff --git a/app/less/slot.less b/app/less/slot.less
new file mode 100644
index 00000000..82072232
--- /dev/null
+++ b/app/less/slot.less
@@ -0,0 +1,164 @@
+
+.slot-group {
+ float: left;
+ margin: 0 5px;
+ background-color: @bgBlack;
+ .user-select-none();
+ cursor: default;
+
+ h1 {
+ font-family: @fTitle;
+ color: @bgBlack;
+ background-color: @primary-disabled;
+ text-transform: uppercase;
+ margin: 2px 0;
+ font-size: 0.8em;
+ padding-left: 0.5em;
+ }
+}
+
+.slot {
+ float: left;
+ width: 230px;
+ font-size: 0.75em;
+ margin-top: 3px;
+ position: relative;
+ z-index: 0;
+ padding-right: 0.4em;
+ padding-left: 1.65em;
+ box-sizing: border-box;
+ background-color: @primary-bg;
+ border: 1px solid @primary-disabled;
+ color: @disabled;
+
+ .details {
+ overflow: hidden;
+ height: 100%;
+ cursor: pointer;
+ }
+
+ .cb {
+ overflow: hidden;
+ }
+
+ .l {
+ margin-right: 1em;
+ }
+
+ .sz {
+ text-align: center;
+ position: absolute;
+ top: 0;
+ height: 100%;
+ left: 0;
+ font-size: 1.2em;
+ width: 1.2em;
+ color: @primary-disabled;
+ border-right: 1px solid @primary-disabled;
+ box-sizing: border-box;
+ }
+
+ .empty {
+ font-size: 1.5em;
+ color: lighten(@primary-bg, 12%);
+ text-align: center;
+ letter-spacing: 0.1em;
+ line-height: 1.8em;
+ }
+
+ &:hover{
+ color: @fg;
+ border: 1px solid @primary;
+
+ .sz {
+ color: @primary;
+ border-right: 1px solid @primary;
+ }
+ }
+
+ &.selected {
+ color: @primary-bg;
+ background-color: @primary;
+ border: 1px solid @primary;
+ z-index: 1;
+ .sz {
+ color: @primary;
+ background-color: @primary-bg;
+ border-right: 1px solid @primary;
+ }
+ }
+}
+
+.select {
+ color: @primary-disabled;
+ position: absolute;
+ left: -1px;
+ padding: 5px 0;
+ width: 100%;
+ margin: 0;
+ max-height: 300px;
+ overflow-y: scroll;
+ background-color: @bg;
+ border: 1px solid @primary;
+
+
+ .select-group {
+ clear: both;
+ margin: 5px 0;
+ padding-left: 5px;
+ border-top: 1px solid @primary-disabled;
+ border-bottom: 1px solid @primary-disabled;
+ }
+
+ .empty-c, .c, .lc {
+ cursor: pointer;
+
+ color: @primary-disabled;
+
+ &:hover {
+ color: @warning;
+ }
+ }
+
+ @optionSpacing: 1.8em;
+
+ .lc {
+ padding-left: 5px;
+ line-height:@optionSpacing;
+ }
+
+ .empty-c {
+ line-height:@optionSpacing;
+ text-align: center;
+ }
+
+ .c {
+ border:1px solid @primary-disabled;
+ display: block;
+ float:left;
+ padding: 0;
+ margin: 0.5em;
+ width: 2em;
+ //height: 1.5em;
+ line-height: @optionSpacing;
+ text-align: center;
+
+ &:hover {
+ border:1px solid @warning;
+ }
+
+ &:nth-child(5n +1) {
+ clear: left;
+ }
+ }
+
+ ul {
+ margin: 0;
+ margin-left: 20px;
+ padding: 0;
+ list-style: none;
+ overflow: hidden;
+ }
+
+
+}
diff --git a/app/less/utilities.less b/app/less/utilities.less
index d74c5e44..647299e1 100644
--- a/app/less/utilities.less
+++ b/app/less/utilities.less
@@ -19,4 +19,13 @@
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
+}
+
+.user-select-none (){
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
}
\ No newline at end of file
diff --git a/app/views/component_select.html b/app/views/component_select.html
index 65a1e0d1..2224ee19 100644
--- a/app/views/component_select.html
+++ b/app/views/component_select.html
@@ -1,3 +1,3 @@
- - {{o.class}}{{o.rating}}
+ - {{o.class}}{{o.rating}}{{' ' + o.name || ''}}
diff --git a/app/views/costs.html b/app/views/costs.html
index 538ea19c..421807f7 100644
--- a/app/views/costs.html
+++ b/app/views/costs.html
@@ -1,18 +1,29 @@
-
-
{{ship.name}}
{{$r.fCrd(ship.cost)}}
+
+
+
+
{{ship.name}}
{{$r.fCrd(ship.cost)}}
+
+
+
{{ship.bulkheads.c.name}}
{{$r.fCrd(ship.bulkheads.c.cost)}}
+
+
+
{{c.c.class}}{{c.c.rating}} {{$r.CArr[$index]}}
{{$r.fCrd(c.c.cost)}}
+
+
+
{{c.c.class}}{{c.c.rating}} {{c.c.name}}
{{$r.fCrd(c.c.cost)}}
+
+
+
{{c.c.class}}{{c.c.rating}} {{c.c.name || $r.igMap[c.c.group]}}
{{$r.fCrd(c.c.cost)}}
+
-
-
{{ship.bulkheads.c.name}}
{{$r.fCrd(ship.bulkheads.c.cost)}}
-
-
-
{{c.c.class}}{{c.c.rating}} {{$r.CArr[$index]}}
{{$r.fCrd(c.c.cost)}}
-
-
-
{{c.c.class}}{{c.c.rating}} {{c.c.name}}
{{$r.fCrd(c.c.cost)}}
-
-
-
{{c.c.class}}{{c.c.rating}} {{c.c.name || $r.igMap[c.c.group]}}
{{$r.fCrd(c.c.cost)}}
-
-
-
Total
{{$r.fCrd(ship.totalCost)}}
+
+
+
+
Total
+
{{$r.fCrd(ship.totalCost)}} CR
+
+
+
Insurance
+
{{$r.fCrd(ship.totalCost * (1-insurance))}} CR
+
diff --git a/app/views/hardpoint.html b/app/views/hardpoint.html
new file mode 100644
index 00000000..6b110641
--- /dev/null
+++ b/app/views/hardpoint.html
@@ -0,0 +1,16 @@
+
{{['U','S','M','L','H'][hp.maxClass]}}
+
EMPTY
+
+
{{hp.c.name}}
{{hp.c.class}}{{hp.c.rating}}/{{hp.c.mode}}{{hp.c.missile}}
+
+
+
Ammo: {{$r.fCrd(hp.c.clip)}}/{{$r.fCrd(hp.c.ammo)}}
+
ROF: {{hp.c.rof}}/s
+
+{{$r.fRPct(hp.c.shieldmul)}}
+
{{hp.c.range}} KM
+
{{hp.c.mass}} T
+
+
diff --git a/app/views/menu.html b/app/views/menu.html
index 0be50c47..923a8890 100644
--- a/app/views/menu.html
+++ b/app/views/menu.html
@@ -1,6 +1,6 @@
diff --git a/app/views/power.html b/app/views/power.html
index 8a773e74..416ff013 100644
--- a/app/views/power.html
+++ b/app/views/power.html
@@ -1,20 +1,37 @@
-
-
{{ship.common[0].c.class}}{{ship.common[0].c.rating}} {{$r.CArr[0]}}
{{$r.fPwr(ship.common[0].c.pGen)}}
-
-
-
{{c.c.class}}{{c.c.rating}} {{$r.CArr[$index]}}
{{$r.fPwr(c.c.power)}}
-
-
-
1H Cargo Scoop
{{$r.fPwr(ship.cargoScoop.c.power)}}
-
-
-
{{c.c.class}}{{c.c.rating}} {{c.c.name}}
{{$r.fPwr(c.c.power)}}
-
+
+
+
+
{{ship.common[0].c.class}}{{ship.common[0].c.rating}} {{$r.CArr[0]}}
{{$r.fPwr(ship.common[0].c.pGen)}}
+
-
-
{{c.c.class}}{{c.c.rating}} {{c.c.name || $r.igMap[c.c.group]}}
{{$r.fPwr(c.c.power)}}
-
+
+
{{c.c.class}}{{c.c.rating}} {{$r.CArr[$index]}}
{{$r.fPwr(c.c.power)}}
+
-
Retracted: {{$r.fPwr(ship.powerRetracted)}} ({{$r.fPct(ship.powerRetracted/ship.powerAvailable)}})
-
Deployed: {{$r.fPwr(ship.powerDeployed)}} ({{$r.fPct(ship.powerDeployed/ship.powerAvailable)}})
+
+
1H Cargo Scoop
{{$r.fPwr(ship.cargoScoop.c.power)}}
+
+
+
+
{{c.c.class}}{{c.c.rating}} {{c.c.name}}
{{$r.fPwr(c.c.power)}}
+
+
+
+
{{c.c.class}}{{c.c.rating}} {{c.c.name || $r.igMap[c.c.group]}}
{{$r.fPwr(c.c.power)}}
+
+
+
+
+
Available
+
{{$r.fPwr(ship.powerAvailable)}} MW
+
+
+
Deployed
+
{{$r.fPwr(ship.powerDeployed)}} MW ({{$r.fPct(ship.powerDeployed/ship.powerAvailable)}})
+
+
+
Retracted
+
{{$r.fPwr(ship.powerRetracted)}} MW ({{$r.fPct(ship.powerRetracted/ship.powerAvailable)}})
+
+
diff --git a/app/views/ship-range.html b/app/views/ship-range.html
new file mode 100644
index 00000000..b4533544
--- /dev/null
+++ b/app/views/ship-range.html
@@ -0,0 +1,15 @@
+
+
+
+ Stuff!
+
+
+
+
Laden
+
{{$r.fRound(ship.ladenJumpRange)}} Ly
+
+
+
Unladen
+
{{$r.fRound(ship.unladenJumpRange)}} Ly
+
+
diff --git a/app/views/ship.html b/app/views/ship.html
index c63f8d5a..ffa24f27 100644
--- a/app/views/ship.html
+++ b/app/views/ship.html
@@ -1,55 +1,164 @@
-
+
-