Compare commits

...

28 Commits

Author SHA1 Message Date
Colin McLeod
b285a433b2 Bumping version to 0.13.2 2015-06-18 09:52:48 -07:00
Colin McLeod
f19c786f64 Update ship armour stats 2015-06-18 09:52:18 -07:00
Colin McLeod
806e545361 Fix charts in comparison page 2015-06-17 23:32:56 -07:00
Colin McLeod
ae62781d53 Bump version to 0.13.0 2015-06-17 23:17:15 -07:00
Colin McLeod
3abfcf7c95 Tweak chart axis UI 2015-06-17 23:12:27 -07:00
Colin McLeod
dc8b829d8a fix: total range calculation bug 2015-06-17 20:41:54 -07:00
Colin McLeod
353396398b Linting fix 2015-06-17 20:41:11 -07:00
Colin McLeod
bf99b34596 Tweak outfit page charts responsiveness 2015-06-16 15:28:06 -07:00
Colin McLeod
f3af0f3a99 Toggling shield and boosters updates shield strength 2015-06-16 15:27:41 -07:00
Colin McLeod
0fd4a8395e Tweak area chart tooltip 2015-06-16 15:26:47 -07:00
Colin McLeod
cb664003a5 Tweak slider 2015-06-16 15:26:22 -07:00
Colin McLeod
4686f17d18 Strip build should reset bulkheads 2015-06-16 15:26:05 -07:00
Colin McLeod
45c96dc136 Icon tweaks, added feather icon 2015-06-16 15:25:25 -07:00
Colin McLeod
389fdc8dfa Removing unused svg icon 2015-06-15 23:25:42 -07:00
Colin McLeod
b94e6126cd Chart performance tweaks, UI tweaks 2015-06-15 21:46:55 -07:00
Colin McLeod
bee4f7e6bc Fix strip build bug, and update state 2015-06-15 18:18:27 -07:00
Colin McLeod
345b7f5ffe Removing codeship, adding travis build status to readme 2015-06-15 18:08:41 -07:00
Colin McLeod
f1b40eb38c Adding gulp back to package.json 2015-06-15 18:06:09 -07:00
Colin McLeod
f459c26bd7 Locking down npm dependencies, add caching to travis 2015-06-15 18:03:02 -07:00
Colin McLeod
825b678fb0 Total Range chart feature added 2015-06-15 17:43:28 -07:00
Colin McLeod
ce3818f99a Use Travis CI instead of Codeship 2015-06-15 17:32:18 -07:00
Colin McLeod
94e2b60cd1 Changing version link 2015-06-15 17:31:27 -07:00
Colin McLeod
3bbef71a5e Merge pull request #58 from shearn89/strip-ship
Adding in 'Strip Ship' functionality.
2015-06-15 16:26:01 -07:00
Alex Shearn
ca280673d1 Fixing indentation 2015-06-15 22:09:18 +01:00
Alex Shearn
ff477c035a Moving button as per comments 2015-06-15 20:28:15 +01:00
Alex Shearn
1c0b76a8c2 Adding in 'Strip Ship' functionality.
This commit adds a simple button next to the save/reload icons that strips the ship to maximum class, D-rated modules, and no optional modules. Still needs a custom icon! May try to add in future things like 'all cargo' or 'fill empty with...' options.
2015-06-15 20:07:13 +01:00
Colin McLeod
bef741332d Bumping version to 0.12.1 2015-06-15 10:11:34 -07:00
Colin McLeod
f54620ee24 Imperial Courier shield correction 2015-06-15 10:11:12 -07:00
35 changed files with 243 additions and 147 deletions

19
.travis.yml Normal file
View File

@@ -0,0 +1,19 @@
language: node_js
notifications:
email: false
sudo: false
node_js:
- "0.12"
cache:
directories:
- node_modules
- bower_components
before_script:
- npm install -g gulp
- npm install -g bower
- bower install
script:
- gulp lint
- gulp build-prod
- gulp test

View File

@@ -1,4 +1,4 @@
[ ![Codeship Status for cmmcleod/coriolis](https://codeship.com/projects/637858c0-f2a5-0132-7af7-5ed004d44c71/status?branch=master)](https://codeship.com/projects/85232) [![Tasks in Ready](https://badge.waffle.io/cmmcleod/coriolis.png?label=ready&title=Ready)](https://waffle.io/cmmcleod/coriolis) [![Tasks in Progress](https://badge.waffle.io/cmmcleod/coriolis.svg?label=in%20progress&title=In%20Progress)](http://waffle.io/cmmcleod/coriolis) [![Build Status](https://travis-ci.org/cmmcleod/coriolis.svg?branch=master)](https://travis-ci.org/cmmcleod/coriolis) [![Tasks in Ready](https://badge.waffle.io/cmmcleod/coriolis.png?label=ready&title=Ready)](https://waffle.io/cmmcleod/coriolis) [![Tasks in Progress](https://badge.waffle.io/cmmcleod/coriolis.svg?label=in%20progress&title=In%20Progress)](http://waffle.io/cmmcleod/coriolis)

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generated by IcoMoon.io -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32">
<path d="M16 0c-8.837 0-16 7.163-16 16s7.163 16 16 16 16-7.163 16-16-7.163-16-16-16zM16 29c-7.18 0-13-5.82-13-13s5.82-13 13-13 13 5.82 13 13-5.82 13-13 13z"></path>
<path d="M21 8l-5 5-5-5-3 3 5 5-5 5 3 3 5-5 5 5 3-3-5-5 5-5z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 554 B

3
app/icons/feather.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="724" height="1024" viewBox="0 0 1024 1024">
<path d="M0 1024c128-384 463-1024 1024-1024-263 211-384 704-576 704s-192 0-192 0l-192 320h-64z"></path>
</svg>

After

Width:  |  Height:  |  Size: 218 B

View File

@@ -1,6 +1,3 @@
<?xml version="1.0" encoding="utf-8"?> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="33" height="33" viewBox="0 0 33 33">
<!-- Generated by IcoMoon.io -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32">
<path d="M32 12h-12l4.485-4.485c-2.267-2.266-5.28-3.515-8.485-3.515s-6.219 1.248-8.485 3.515c-2.266 2.267-3.515 5.28-3.515 8.485s1.248 6.219 3.515 8.485c2.267 2.266 5.28 3.515 8.485 3.515s6.219-1.248 8.485-3.515c0.189-0.189 0.371-0.384 0.546-0.583l3.010 2.634c-2.933 3.349-7.239 5.464-12.041 5.464-8.837 0-16-7.163-16-16s7.163-16 16-16c4.418 0 8.418 1.791 11.313 4.687l4.687-4.687v12z"></path> <path d="M32 12h-12l4.485-4.485c-2.267-2.266-5.28-3.515-8.485-3.515s-6.219 1.248-8.485 3.515c-2.266 2.267-3.515 5.28-3.515 8.485s1.248 6.219 3.515 8.485c2.267 2.266 5.28 3.515 8.485 3.515s6.219-1.248 8.485-3.515c0.189-0.189 0.371-0.384 0.546-0.583l3.010 2.634c-2.933 3.349-7.239 5.464-12.041 5.464-8.837 0-16-7.163-16-16s7.163-16 16-16c4.418 0 8.418 1.791 11.313 4.687l4.687-4.687v12z"></path>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 713 B

After

Width:  |  Height:  |  Size: 499 B

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generated by IcoMoon.io --> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="33" height="33" viewBox="0 0 33 33">
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32">
<path d="M20 4.581v4.249c1.131 0.494 2.172 1.2 3.071 2.099 1.889 1.889 2.929 4.4 2.929 7.071s-1.040 5.182-2.929 7.071c-1.889 1.889-4.4 2.929-7.071 2.929s-5.182-1.040-7.071-2.929c-1.889-1.889-2.929-4.4-2.929-7.071s1.040-5.182 2.929-7.071c0.899-0.899 1.94-1.606 3.071-2.099v-4.249c-5.783 1.721-10 7.077-10 13.419 0 7.732 6.268 14 14 14s14-6.268 14-14c0-6.342-4.217-11.698-10-13.419zM14 0h4v16h-4z"></path> <path d="M20 4.581v4.249c1.131 0.494 2.172 1.2 3.071 2.099 1.889 1.889 2.929 4.4 2.929 7.071s-1.040 5.182-2.929 7.071c-1.889 1.889-4.4 2.929-7.071 2.929s-5.182-1.040-7.071-2.929c-1.889-1.889-2.929-4.4-2.929-7.071s1.040-5.182 2.929-7.071c0.899-0.899 1.94-1.606 3.071-2.099v-4.249c-5.783 1.721-10 7.077-10 13.419 0 7.732 6.268 14 14 14s14-6.268 14-14c0-6.342-4.217-11.698-10-13.419zM14 0h4v16h-4z"></path>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 723 B

After

Width:  |  Height:  |  Size: 510 B

View File

@@ -63,7 +63,7 @@
<footer> <footer>
<div class="right"> <div class="right">
<a href="https://github.com/cmmcleod/coriolis" target="_blank" title="Coriolis Github Project">Version <%= version %> - <%= date %></a> <a href="https://github.com/cmmcleod/coriolis/releases/" target="_blank" title="Coriolis Github Project">Version <%= version %> - <%= date %></a>
</div> </div>
<div style="max-width:50%" class="l"> <div style="max-width:50%" class="l">
Coriolis Shipyard was created for non-commercial purposes. It is not endorsed by nor reflects the views or opinions of Frontier Developments. Coriolis Shipyard was created for non-commercial purposes. It is not endorsed by nor reflects the views or opinions of Frontier Developments.

View File

@@ -1,4 +1,4 @@
angular.module('app').controller('OutfitController', ['$window', '$rootScope', '$scope', '$state', '$stateParams', 'ShipsDB', 'Ship', 'Components', 'Serializer', 'Persist', function($window, $rootScope, $scope, $state, $p, Ships, Ship, Components, Serializer, Persist) { angular.module('app').controller('OutfitController', ['$window', '$rootScope', '$scope', '$state', '$stateParams', 'ShipsDB', 'Ship', 'Components', 'Serializer', 'Persist', 'calcTotalRange', function($window, $rootScope, $scope, $state, $p, Ships, Ship, Components, Serializer, Persist, calcTotalRange) {
var data = Ships[$p.shipId]; // Retrieve the basic ship properties, slots and defaults var data = Ships[$p.shipId]; // Retrieve the basic ship properties, slots and defaults
var ship = new Ship($p.shipId, data.properties, data.slots); // Create a new Ship instance var ship = new Ship($p.shipId, data.properties, data.slots); // Create a new Ship instance
var win = angular.element($window); // Angularized window object for event triggering var win = angular.element($window); // Angularized window object for event triggering
@@ -39,8 +39,7 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
$scope.jrSeries = { $scope.jrSeries = {
xMin: 0, xMin: 0,
xMax: ship.cargoCapacity, xMax: ship.cargoCapacity,
// Slightly higher than actual based bacuse components are excluded yMax: ship.unladenRange,
yMax: ship.jumpRangeWithMass(ship.unladenMass),
yMin: 0, yMin: 0,
func: function(cargo) { // X Axis is Cargo func: function(cargo) { // X Axis is Cargo
return ship.jumpRangeWithMass(ship.unladenMass + $scope.fuel + cargo, $scope.fuel); return ship.jumpRangeWithMass(ship.unladenMass + $scope.fuel + cargo, $scope.fuel);
@@ -60,6 +59,29 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
watch: $scope.fsd watch: $scope.fsd
}; };
$scope.trSeries = {
xMin: 0,
xMax: ship.cargoCapacity,
yMax: ship.unladenTotalRange,
yMin: 0,
func: function(cargo) { // X Axis is Cargo
return calcTotalRange(ship.unladenMass + cargo, $scope.fsd.c, $scope.fuel);
}
};
$scope.trChart = {
labels: {
xAxis: {
title: 'Cargo',
unit: 'T'
},
yAxis: {
title: 'Total Range',
unit: 'LY'
}
},
watch: $scope.fsd
};
/** /**
* 'Opens' a select for component selection. * 'Opens' a select for component selection.
* *
@@ -116,6 +138,21 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
} }
}; };
/**
* Strip ship to D-class and no other components.
*/
$scope.stripBuild = function() {
for (var i = 0, l = ship.common.length - 1; i < l; i++) { // All except Fuel Tank
var id = ship.common[i].maxClass + 'D';
ship.use(ship.common[i], id, Components.common(i, id));
}
ship.hardpoints.forEach(function(slot) { ship.use(slot, null, null); });
ship.internal.forEach(function(slot) { ship.use(slot, null, null); });
ship.useBulkhead(0);
$scope.code = Serializer.fromShip(ship);
updateState();
};
/** /**
* Save the current build. Will replace the saved build if there is one * Save the current build. Will replace the saved build if there is one
* for this ship & with the exact name. * for this ship & with the exact name.
@@ -216,9 +253,9 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
function updateState() { function updateState() {
$state.go('outfit', { shipId: ship.id, code: $scope.code, bn: $scope.buildName }, { location: 'replace', notify: false }); $state.go('outfit', { shipId: ship.id, code: $scope.code, bn: $scope.buildName }, { location: 'replace', notify: false });
$scope.jrSeries.xMax = ship.cargoCapacity; $scope.trSeries.xMax = $scope.jrSeries.xMax = ship.cargoCapacity;
$scope.jrSeries.yMax = ship.jumpRangeWithMass(ship.unladenMass); $scope.jrSeries.yMax = ship.unladenRange;
$scope.jrSeries.mass = ship.unladenMass; $scope.trSeries.yMax = ship.unladenTotalRange;
win.triggerHandler('pwrchange'); win.triggerHandler('pwrchange');
} }

View File

@@ -19,7 +19,8 @@ angular.module('app').directive('areaChart', ['$window', function($window) {
xAxis = d3.svg.axis().outerTickSize(0).orient('bottom').tickFormat(d3.format('.2r')), xAxis = d3.svg.axis().outerTickSize(0).orient('bottom').tickFormat(d3.format('.2r')),
yAxis = d3.svg.axis().ticks(6).outerTickSize(0).orient('left').tickFormat(fmt), yAxis = d3.svg.axis().ticks(6).outerTickSize(0).orient('left').tickFormat(fmt),
x = d3.scale.linear(), x = d3.scale.linear(),
y = d3.scale.linear(); y = d3.scale.linear(),
data = [];
// Create chart // Create chart
var svg = d3.select(element[0]).append('svg'); var svg = d3.select(element[0]).append('svg');
@@ -61,56 +62,15 @@ angular.module('app').directive('areaChart', ['$window', function($window) {
// Create and Add tooltip // Create and Add tooltip
var tip = vis.append('g').style('display', 'none'); var tip = vis.append('g').style('display', 'none');
tip.append('rect').attr('width', '4em').attr('height', '2em').attr('x', '0.5em').attr('y', '-1em').attr('class', 'tip'); tip.append('rect').attr('width', '4.5em').attr('height', '2em').attr('x', '0.5em').attr('y', '-1em').attr('class', 'tip');
tip.append('circle') tip.append('circle')
.attr('class', 'marker') .attr('class', 'marker')
.attr('r', 4); .attr('r', 4);
tip.append('text').attr('class', 'label x').attr('y', '-0.25em'); tip.append('text').attr('class', 'label x').attr('y', '-0.25em');
tip.append('text').attr('class', 'label y').attr('y', '0.85em'); tip.append('text').attr('class', 'label y').attr('y', '0.85em');
/**
* Watch for changes in the series data (mass changes, etc)
*/
scope.$watchCollection('series', render);
angular.element($window).bind('orientationchange resize render', render);
function render() {
var width = element[0].parentElement.offsetWidth,
height = width * 0.5,
w = width - margin.left - margin.right,
h = height - margin.top - margin.bottom,
data = [];
if (series.xMax == series.xMin) {
var yVal = func(series.xMin);
data.push([ series.xMin, yVal ]);
data.push([ series.xMin, yVal ]);
area.x(function(d, i) { return i * w; }).y0(h).y1(function(d) { return y(d[1]); });
} else {
for (var val = series.xMin; val <= series.xMax; val += 1) {
data.push([ val, func(val) ]);
}
area.x(function(d) { return x(d[0]); }).y0(h).y1(function(d) { return y(d[1]); });
}
// Update Chart Size
svg.attr('width', width).attr('height', height);
// Update domain and scale for axes;
x.range([0, w]).domain([series.xMin, series.xMax]).clamp(true);
xAxis.scale(x);
xLbl.attr('transform', 'translate(0,' + h + ')');
xTxt.attr('x', w / 2);
y.range([h, 0]).domain([series.yMin, series.yMax]);
yAxis.scale(y);
yTxt.attr('x', -h / 2);
vis.selectAll('.y.axis').call(yAxis);
vis.selectAll('.x.axis').call(xAxis);
// Remove existing elements
vis.selectAll('path.area').remove();
vis.insert('path', ':first-child') // Area/Path to appear behind everything else vis.insert('path', ':first-child') // Area/Path to appear behind everything else
.datum(data) .data([data])
.attr('class', 'area') .attr('class', 'area')
.attr('fill', 'url(#gradient)') .attr('fill', 'url(#gradient)')
.attr('d', area) .attr('d', area)
@@ -130,6 +90,49 @@ angular.module('app').directive('areaChart', ['$window', function($window) {
hideTip(); hideTip();
}) })
.on('drag', moveTip); .on('drag', moveTip);
/**
* Watch for changes in the series data (mass changes, etc)
*/
scope.$watchCollection('series', render);
angular.element($window).bind('orientationchange resize render', render);
function render() {
var width = element[0].parentElement.offsetWidth,
height = width * 0.5,
w = width - margin.left - margin.right,
h = height - margin.top - margin.bottom;
data.length = 0; // Reset Data array
if (series.xMax == series.xMin) {
var yVal = func(series.xMin);
data.push([ series.xMin, yVal ]);
data.push([ series.xMin, yVal ]);
area.x(function(d, i) { return i * w; }).y0(h).y1(function(d) { return y(d[1]); });
} else {
for (var val = series.xMin; val <= series.xMax; val += 1) {
data.push([ val, func(val) ]);
}
area.x(function(d) { return x(d[0]); }).y0(h).y1(function(d) { return y(d[1]); });
}
// Update Chart Size
svg.attr('width', width).attr('height', height);
// Update domain and scale for axes
x.range([0, w]).domain([series.xMin, series.xMax]).clamp(true);
xAxis.scale(x);
xLbl.attr('transform', 'translate(0,' + h + ')');
xTxt.attr('x', w / 2);
y.range([h, 0]).domain([series.yMin, series.yMax]);
yAxis.scale(y);
yTxt.attr('x', -h / 2);
vis.selectAll('.y.axis').call(yAxis);
vis.selectAll('.x.axis').call(xAxis);
vis.selectAll('path.area') // Area/Path to appear behind everything else
.data([data])
.attr('d', area);
} }
function showTip() { function showTip() {
@@ -143,10 +146,10 @@ angular.module('app').directive('areaChart', ['$window', function($window) {
} }
function moveTip() { function moveTip() {
var xPos = d3.mouse(this)[0], x0 = x.invert(xPos), y0 = func(x0), flip = (x0 / x.domain()[1] > 0.75); var xPos = d3.mouse(this)[0], x0 = x.invert(xPos), y0 = func(x0), flip = (x0 / x.domain()[1] > 0.65);
tip.attr('transform', 'translate(' + x(x0) + ',' + y(y0) + ')'); tip.attr('transform', 'translate(' + x(x0) + ',' + y(y0) + ')');
tip.selectAll('rect').attr('x', flip ? '-4.5em' : '0.5em').style('text-anchor', flip ? 'end' : 'start'); tip.selectAll('rect').attr('x', flip ? '-5.75em' : '0.5em').style('text-anchor', flip ? 'end' : 'start');
tip.selectAll('text.label').attr('x', flip ? '-1em' : '1em').style('text-anchor', flip ? 'end' : 'start'); tip.selectAll('text.label').attr('x', flip ? '-2em' : '1em').style('text-anchor', flip ? 'end' : 'start');
tip.select('text.label.x').text(fmtLong(x0) + ' ' + labels.xAxis.unit); tip.select('text.label.x').text(fmtLong(x0) + ' ' + labels.xAxis.unit);
tip.select('text.label.y').text(fmtLong(y0) + ' ' + labels.yAxis.unit); tip.select('text.label.y').text(fmtLong(y0) + ' ' + labels.yAxis.unit);
} }

View File

@@ -8,7 +8,7 @@ angular.module('app').directive('slider', ['$window', function($window) {
change: '&onChange' change: '&onChange'
}, },
link: function(scope, element) { link: function(scope, element) {
var margin = { top: -10, right: 140, bottom: 0, left: 50 }, var margin = { top: -10, right: 145, bottom: 0, left: 50 },
height = 40, // Height is fixed height = 40, // Height is fixed
h = height - margin.top - margin.bottom, h = height - margin.top - margin.bottom,
fmt = d3.format('.2f'), fmt = d3.format('.2f'),

View File

@@ -1,4 +1,4 @@
angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength', 'calcJumpRange', 'lodash', function(Components, calcShieldStrength, calcJumpRange, _) { angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength', 'calcJumpRange', 'calcTotalRange', 'lodash', function(Components, calcShieldStrength, calcJumpRange, calcTotalRange, _) {
/** /**
* Returns the power usage type of a slot and it's particular component * Returns the power usage type of a slot and it's particular component
@@ -238,11 +238,21 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
}; };
Ship.prototype.setSlotEnabled = function(slot, enabled) { Ship.prototype.setSlotEnabled = function(slot, enabled) {
if (slot.enabled != enabled && slot.c) { // Enabled state is changing if (slot.enabled != enabled) { // Enabled state is changing
slot.enabled = enabled;
if (slot.c) {
this.priorityBands[slot.priority][powerUsageType(slot, slot.c)] += enabled ? slot.c.power : -slot.c.power; this.priorityBands[slot.priority][powerUsageType(slot, slot.c)] += enabled ? slot.c.power : -slot.c.power;
if (slot.c.grp == 'sg') {
this.updateShieldStrength();
} else if (slot.c.grp == 'sb') {
this.shieldMultiplier += slot.c.shieldmul * (enabled ? 1 : -1);
this.updateShieldStrength();
}
this.updatePower(); this.updatePower();
} }
slot.enabled = enabled; }
}; };
Ship.prototype.getSlotStatus = function(slot, deployed) { Ship.prototype.getSlotStatus = function(slot, deployed) {
@@ -277,7 +287,7 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
this.armourAdded -= old.armouradd; this.armourAdded -= old.armouradd;
break; break;
case 'sb': case 'sb':
this.shieldMultiplier -= old.shieldmul; this.shieldMultiplier -= slot.enabled ? old.shieldmul : 0;
break; break;
} }
@@ -307,7 +317,7 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
this.armourAdded += n.armouradd; this.armourAdded += n.armouradd;
break; break;
case 'sb': case 'sb':
this.shieldMultiplier += n.shieldmul; this.shieldMultiplier += slot.enabled ? n.shieldmul : 0;
break; break;
} }
@@ -351,7 +361,7 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
Ship.prototype.updateShieldStrength = function() { Ship.prototype.updateShieldStrength = function() {
var sgSlot = this.findInternalByGroup('sg'); // Find Shield Generator slot Index if any var sgSlot = this.findInternalByGroup('sg'); // Find Shield Generator slot Index if any
this.shieldStrength = sgSlot ? calcShieldStrength(this.mass, this.shields, sgSlot.c, this.shieldMultiplier) : 0; this.shieldStrength = sgSlot && sgSlot.enabled ? calcShieldStrength(this.mass, this.shields, sgSlot.c, this.shieldMultiplier) : 0;
}; };
/** /**
@@ -359,23 +369,12 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
*/ */
Ship.prototype.updateJumpStats = function() { Ship.prototype.updateJumpStats = function() {
var fsd = this.common[2].c; // Frame Shift Drive; var fsd = this.common[2].c; // Frame Shift Drive;
var fuelRemaining = this.fuelCapacity % fsd.maxfuel; // Fuel left after making N max jumps
var jumps = this.fuelCapacity / fsd.maxfuel;
this.unladenRange = calcJumpRange(this.unladenMass + fsd.maxfuel, fsd, this.fuelCapacity); // Include fuel weight for jump this.unladenRange = calcJumpRange(this.unladenMass + fsd.maxfuel, fsd, this.fuelCapacity); // Include fuel weight for jump
this.fullTankRange = calcJumpRange(this.unladenMass + this.fuelCapacity, fsd, this.fuelCapacity); // Full Tanke this.fullTankRange = calcJumpRange(this.unladenMass + this.fuelCapacity, fsd, this.fuelCapacity); // Full Tanke
this.ladenRange = calcJumpRange(this.ladenMass, fsd, this.fuelCapacity); this.ladenRange = calcJumpRange(this.ladenMass, fsd, this.fuelCapacity);
this.maxJumpCount = Math.ceil(jumps); // Number of full fuel jumps + final jump to empty tank this.unladenTotalRange = calcTotalRange(this.unladenMass, fsd, this.fuelCapacity);
this.ladenTotalRange = calcTotalRange(this.unladenMass + this.cargoCapacity, fsd, this.fuelCapacity);
// Going backwards, start with the last jump using the remaining fuel this.maxJumpCount = Math.ceil(this.fuelCapacity / fsd.maxfuel);
this.unladenTotalRange = fuelRemaining > 0 ? calcJumpRange(this.unladenMass + fuelRemaining, fsd, fuelRemaining) : 0;
this.ladenTotalRange = fuelRemaining > 0 ? calcJumpRange(this.unladenMass + this.cargoCapacity + fuelRemaining, fsd, fuelRemaining) : 0;
// For each max fuel jump, calculate the max jump range based on fuel left in the tank
for (var j = 0, l = Math.floor(jumps); j < l; j++) {
fuelRemaining += fsd.maxfuel;
this.unladenTotalRange += calcJumpRange(this.unladenMass + fuelRemaining, fsd);
this.ladenTotalRange += calcJumpRange(this.unladenMass + this.cargoCapacity + fuelRemaining, fsd);
}
}; };
return Ship; return Ship;

View File

@@ -175,6 +175,27 @@ angular.module('shipyard', ['ngLodash'])
*/ */
.value('calcJumpRange', function(mass, fsd, fuel) { .value('calcJumpRange', function(mass, fsd, fuel) {
return Math.pow(Math.min(fuel === undefined ? fsd.maxfuel : fuel, fsd.maxfuel) / fsd.fuelmul, 1 / fsd.fuelpower ) * fsd.optmass / mass; return Math.pow(Math.min(fuel === undefined ? fsd.maxfuel : fuel, fsd.maxfuel) / fsd.fuelmul, 1 / fsd.fuelpower ) * fsd.optmass / mass;
})
/**
* Calculate the total range based on mass and a specific FSD, and all fuel available
*
* @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 The total fuel available
* @return {number} Distance in Light Years
*/
.value('calcTotalRange', function(mass, fsd, fuel) {
var fuelRemaining = fuel % fsd.maxfuel; // Fuel left after making N max jumps
var jumps = fuel / fsd.maxfuel;
mass += fuelRemaining;
// Going backwards, start with the last jump using the remaining fuel
var totalRange = fuelRemaining > 0 ? Math.pow(fuelRemaining / fsd.fuelmul, 1 / fsd.fuelpower ) * fsd.optmass / mass : 0;
// For each max fuel jump, calculate the max jump range based on fuel left in the tank
for (var j = 0, l = Math.floor(jumps); j < l; j++) {
fuelRemaining += fsd.maxfuel;
totalRange += Math.pow(fsd.maxfuel / fsd.fuelmul, 1 / fsd.fuelpower ) * fsd.optmass / mass;
}
return totalRange;
}) })
/** /**
* Calculate the a ships shield strength based on mass, shield generator and shield boosters used. * Calculate the a ships shield strength based on mass, shield generator and shield boosters used.

View File

@@ -1,11 +1,9 @@
.chart { .chart {
.user-select-none(); .user-select-none();
display: inline-block; display: inline-block;
margin: 0; margin: 0;
cursor: default; cursor: default;
overflow: hidden; overflow: hidden;
width: 33%; width: 33%;
box-sizing: border-box; box-sizing: border-box;
@@ -17,12 +15,23 @@
width: 100%; width: 100%;
}); });
.medPhone({
.axis {
font-size: 0.8em;
g.tick:nth-child(2n + 1) text {
display: none;
}
}
});
h3 { h3 {
text-align: center; text-align: center;
&[ng-click] { &[ng-click] {
cursor: pointer; cursor: pointer;
} }
} }
} }
@@ -63,5 +72,3 @@ svg {
stroke-width: 1px; stroke-width: 1px;
} }
} }

View File

@@ -162,8 +162,24 @@ table.total {
}); });
.smallTablet({ .smallTablet({
overflow-x: auto; width: 100% !important;
-webkit-overflow-scrolling: touch; });
}
&.semi {
width: 50%;
.smallTablet({
.axis {
font-size: 0.8em;
g.tick:nth-child(2n + 1) text {
display: none;
}
}
});
.medPhone({
width: 100% !important; width: 100% !important;
}); });
} }
@@ -177,7 +193,7 @@ table.total {
#componentPriority { #componentPriority {
.tablet({ .tablet({
text.primary, text.warning, text.primary-bg { text.primary, text.warning, text.primary-bg, text.secondary {
font-size: 0.8em; font-size: 0.8em;
} }

View File

@@ -16,6 +16,9 @@
<button ui-sref="outfit({shipId: ship.id,code:null, bn: buildName})" ng-disabled="!code"> <button ui-sref="outfit({shipId: ship.id,code:null, bn: buildName})" ng-disabled="!code">
<svg class="icon lg"><use xlink:href="#switch"></use></svg><span class="button-lbl">Reset</span> <svg class="icon lg"><use xlink:href="#switch"></use></svg><span class="button-lbl">Reset</span>
</button> </button>
<button ng-click="stripBuild()">
<svg class="icon lg"><use xlink:href="#feather"></use></svg><span class="button-lbl">Low-Weight</span>
</button>
</div> </div>
</div> </div>
@@ -53,7 +56,7 @@
<td>{{fRound(ship.speed)}} <u>m/s</u></td> <td>{{fRound(ship.speed)}} <u>m/s</u></td>
<td>{{fRound(ship.boost)}} <u>m/s</u></td> <td>{{fRound(ship.boost)}} <u>m/s</u></td>
<td>{{ship.armourTotal}} <span ng-if="ship.armourAdded">({{ship.armour}} + {{ship.armourAdded}})</span></td> <td>{{ship.armourTotal}} <span ng-if="ship.armourAdded">({{ship.armour}} + {{ship.armourAdded}})</span></td>
<td>{{fRound(ship.shieldStrength)}} <u>MJ</u> <span ng-if="ship.shieldMultiplier > 1">({{fRPct(ship.shieldMultiplier)}})</span></td> <td>{{fRound(ship.shieldStrength)}} <u>MJ</u> <span ng-if="ship.shieldMultiplier > 1 && ship.shieldStrength > 0">({{fRPct(ship.shieldMultiplier)}})</span></td>
<td>{{fRound(ship.unladenMass)}} <u>T</u></td> <td>{{fRound(ship.unladenMass)}} <u>T</u></td>
<td>{{fRound(ship.ladenMass)}} <u>T</u></td> <td>{{fRound(ship.ladenMass)}} <u>T</u></td>
<td>{{fRound(ship.cargoCapacity)}} <u>T</u></td> <td>{{fRound(ship.cargoCapacity)}} <u>T</u></td>
@@ -261,14 +264,20 @@
</table> </table>
</div> </div>
<div class="group dbl"> <div class="group semi">
<h1>Jump Range</h1> <h1>Jump Range</h1>
<div class="cen">
<div area-chart config="jrChart" series="jrSeries"></div> <div area-chart config="jrChart" series="jrSeries"></div>
</div>
<div class="group semi">
<h1>Total Range</h1>
<div area-chart config="trChart" series="trSeries"></div>
</div>
<div class="group dbl">
<div slider max="ship.fuelCapacity" unit="'T'" on-change="::fuelChange(val)" style="position:relative; margin: 0 auto;"> <div slider max="ship.fuelCapacity" unit="'T'" on-change="::fuelChange(val)" style="position:relative; margin: 0 auto;">
<svg class="icon xl primary-disabled" style="position:absolute;height: 100%;"><use xlink:href="#fuel"></use></svg> <svg class="icon xl primary-disabled" style="position:absolute;height: 100%;"><use xlink:href="#fuel"></use></svg>
</div> </div>
</div> </div>
</div>
</div> </div>

View File

@@ -10,7 +10,7 @@
"boost": 320, "boost": 320,
"agility": 8, "agility": 8,
"shields": 60, "shields": 60,
"armour": 90, "armour": 162,
"fuelcost": 50, "fuelcost": 50,
"mass": 35 "mass": 35
}, },

View File

@@ -10,7 +10,7 @@
"boost": 240, "boost": 240,
"agility": 2, "agility": 2,
"shields": 350, "shields": 350,
"armour": 525, "armour": 945,
"fuelcost": 50, "fuelcost": 50,
"mass": 400 "mass": 400
}, },

View File

@@ -10,7 +10,7 @@
"boost": 340, "boost": 340,
"agility": 6, "agility": 6,
"shields": 140, "shields": 140,
"armour": 210, "armour": 378,
"fuelcost": 50, "fuelcost": 50,
"mass": 280 "mass": 280
}, },

View File

@@ -10,7 +10,7 @@
"boost": 400, "boost": 400,
"agility": 6, "agility": 6,
"shields": 80, "shields": 80,
"armour": 120, "armour": 216,
"fuelcost": 50, "fuelcost": 50,
"mass": 180 "mass": 180
}, },

View File

@@ -10,7 +10,7 @@
"boost": 350, "boost": 350,
"agility": 10, "agility": 10,
"shields": 60, "shields": 60,
"armour": 40, "armour": 72,
"fuelcost": 50, "fuelcost": 50,
"mass": 50 "mass": 50
}, },

View File

@@ -10,7 +10,7 @@
"boost": 300, "boost": 300,
"agility": 0, "agility": 0,
"shields": 200, "shields": 200,
"armour": 300, "armour": 540,
"fuelcost": 50, "fuelcost": 50,
"mass": 580 "mass": 580
}, },

View File

@@ -10,7 +10,7 @@
"boost": 350, "boost": 350,
"agility": 6, "agility": 6,
"shields": 300, "shields": 300,
"armour": 225, "armour": 405,
"fuelcost": 50, "fuelcost": 50,
"mass": 250 "mass": 250
}, },

View File

@@ -10,7 +10,7 @@
"boost": 300, "boost": 300,
"agility": 6, "agility": 6,
"shields": 50, "shields": 50,
"armour": 50, "armour": 90,
"fuelcost": 50, "fuelcost": 50,
"mass": 14 "mass": 14
}, },

View File

@@ -10,7 +10,7 @@
"boost": 380, "boost": 380,
"agility": 2, "agility": 2,
"shields": 180, "shields": 180,
"armour": 270, "armour": 486,
"fuelcost": 50, "fuelcost": 50,
"mass": 400 "mass": 400
}, },

View File

@@ -9,7 +9,7 @@
"speed": 277, "speed": 277,
"boost": 380, "boost": 380,
"agility": 6, "agility": 6,
"shields": 230, "shields": 197,
"armour": 144, "armour": 144,
"fuelcost": 50, "fuelcost": 50,
"mass": 35 "mass": 35

View File

@@ -10,7 +10,7 @@
"boost": 380, "boost": 380,
"agility": 2, "agility": 2,
"shields": 220, "shields": 220,
"armour": 220, "armour": 396,
"fuelcost": 50, "fuelcost": 50,
"mass": 580 "mass": 580
}, },

View File

@@ -10,7 +10,7 @@
"boost": 280, "boost": 280,
"agility": 6, "agility": 6,
"shields": 260, "shields": 260,
"armour": 260, "armour": 468,
"fuelcost": 50, "fuelcost": 50,
"mass": 350 "mass": 350
}, },

View File

@@ -10,7 +10,7 @@
"boost": 320, "boost": 320,
"agility": 8, "agility": 8,
"shields": 40, "shields": 40,
"armour": 60, "armour": 108,
"fuelcost": 50, "fuelcost": 50,
"mass": 25 "mass": 25
}, },

View File

@@ -10,7 +10,7 @@
"boost": 350, "boost": 350,
"agility": 3, "agility": 3,
"shields": 90, "shields": 90,
"armour": 90, "armour": 162,
"fuelcost": 50, "fuelcost": 50,
"mass": 155 "mass": 155
}, },

View File

@@ -10,7 +10,7 @@
"boost": 300, "boost": 300,
"agility": 2, "agility": 2,
"shields": 120, "shields": 120,
"armour": 120, "armour": 216,
"fuelcost": 50, "fuelcost": 50,
"mass": 420 "mass": 420
}, },

View File

@@ -10,7 +10,7 @@
"boost": 200, "boost": 200,
"agility": 0, "agility": 0,
"shields": 240, "shields": 240,
"armour": 240, "armour": 432,
"fuelcost": 50, "fuelcost": 50,
"mass": 1000 "mass": 1000
}, },

View File

@@ -10,7 +10,7 @@
"boost": 400, "boost": 400,
"agility": 6, "agility": 6,
"shields": 105, "shields": 105,
"armour": 70, "armour": 126,
"fuelcost": 50, "fuelcost": 50,
"mass": 60 "mass": 60
}, },

View File

@@ -10,7 +10,7 @@
"boost": 340, "boost": 340,
"agility": 9, "agility": 9,
"shields": 240, "shields": 240,
"armour": 160, "armour": 288,
"fuelcost": 50, "fuelcost": 50,
"mass": 230 "mass": 230
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "coriolis_shipyard", "name": "coriolis_shipyard",
"version": "0.12.0", "version": "0.13.2",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/cmmcleod/coriolis" "url": "https://github.com/cmmcleod/coriolis"
@@ -9,33 +9,35 @@
"engine": "node >= 0.12.2", "engine": "node >= 0.12.2",
"dependencies": {}, "dependencies": {},
"devDependencies": { "devDependencies": {
"angular-mocks": "^1.3.16", "angular-mocks": "1.3.x",
"async": "^0.9.0", "async": "0.9.x",
"del": "^1.1.1", "del": "1.2.x",
"gulp": "^3.8.11", "gulp": "3.9.x",
"gulp-angular-templatecache": "^1.6.0", "gulp-angular-templatecache": "1.6.x",
"gulp-concat": "^2.5.2", "gulp-concat": "2.5.x",
"gulp-eslint": "^0.13.2", "gulp-eslint": "0.13.x",
"gulp-htmlmin": "^1.1.1", "gulp-htmlmin": "1.1.x",
"gulp-jasmine": "^2.0.1", "gulp-jasmine": "2.0.x",
"gulp-jsonlint": "^1.0.2", "gulp-jsonlint": "1.1.x",
"gulp-less": "^3.0.2", "gulp-less": "3.0.x",
"gulp-manifest": "0.0.6", "gulp-manifest": "0.0.6",
"gulp-minify-css": "^1.0.0", "gulp-minify-css": "1.1.x",
"gulp-rev-all": "0.8.18", "gulp-rev-all": "0.8.18",
"gulp-sourcemaps": "^1.5.1", "gulp-sourcemaps": "1.5.x",
"gulp-svgmin": "^1.1.2", "gulp-svgmin": "1.1.x",
"gulp-svgstore": "^5.0.1", "gulp-svgstore": "5.0.x",
"gulp-template": "^3.0.0", "gulp-template": "3.0.x",
"gulp-uglify": "^1.2.0", "gulp-uglify": "1.2.x",
"gulp-util": "^3.0.4", "gulp-util": "3.0.x",
"jasmine-core": "^2.3.4", "jasmine-core": "2.3.x",
"json-concat": "0.0.0", "json-concat": "0.0.x",
"karma": "^0.12.36", "karma": "0.12.x",
"karma-chrome-launcher": "^0.1.12", "karma-jasmine": "0.3.x",
"karma-jasmine": "^0.3.5", "karma-mocha-reporter": "1.0.x",
"main-bower-files": "^2.6.2", "karma-phantomjs-launcher": "0.2.x",
"run-sequence": "^1.0.2", "main-bower-files": "2.8.x",
"uglify-js": "^2.4.19" "phantomjs": "1.9.x",
"run-sequence": "1.1.x",
"uglify-js": "2.4.x"
} }
} }

View File

@@ -14,21 +14,13 @@ module.exports = function(config) {
'../build/app*.js', '../build/app*.js',
'tests/**/*.js' 'tests/**/*.js'
], ],
// list of files to exclude reporters: ['mocha'],
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
port: 9876, port: 9876,
colors: true, colors: true,
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,
autoWatch: false, autoWatch: false,
browsers: ['Chrome'], browsers: ['PhantomJS'],
singleRun: false singleRun: false
}); });
}; };