mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-10 15:15:34 +00:00
Refactoring of just about everything, interface beginning to come together
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}]);
|
||||
|
||||
@@ -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;
|
||||
}]);
|
||||
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
|
||||
|
||||
}]);
|
||||
|
||||
@@ -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});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
14
app/js/directives/directive-hardpoint.js
Normal file
14
app/js/directives/directive-hardpoint.js
Normal file
@@ -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;
|
||||
}
|
||||
};
|
||||
}]);
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
77
app/js/directives/directive-meter.js
Normal file
77
app/js/directives/directive-meter.js
Normal file
@@ -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);
|
||||
}
|
||||
};
|
||||
});
|
||||
52
app/js/directives/directive-ship-range.js
Normal file
52
app/js/directives/directive-ship-range.js
Normal file
@@ -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
|
||||
};*/
|
||||
}
|
||||
};
|
||||
}]);
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
});
|
||||
}]);
|
||||
@@ -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];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -94,4 +94,40 @@ angular.module('shipyard', [])
|
||||
}
|
||||
|
||||
return groupToLabel;
|
||||
});
|
||||
})
|
||||
.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;
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user