mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 22:55:35 +00:00
SVG sprites, modals, general improvements
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
angular.module('app', ['ui.router', 'shipyard', 'ngLodash', 'app.templates'])
|
||||
angular.module('app', ['ui.router', 'ct.ui.router.extras.sticky', 'shipyard', 'ngLodash', 'app.templates'])
|
||||
.run(['$rootScope', '$location', '$window', '$document','$state','commonArray','shipPurpose','shipSize','hardPointClass','internalGroupMap','hardpointsGroupMap', function ($rootScope, $location, $window, $doc, $state, CArr, shipPurpose, sz, hpc, igMap, hgMap) {
|
||||
// Redirect any state transition errors to the error controller/state
|
||||
$rootScope.$on('$stateChangeError', function(e, toState, toParams, fromState, fromParams, error){
|
||||
@@ -7,8 +7,11 @@ angular.module('app', ['ui.router', 'shipyard', 'ngLodash', 'app.templates'])
|
||||
});
|
||||
|
||||
// Track on Google analytics if available
|
||||
$rootScope.$on('$stateChangeSuccess', function() {
|
||||
if ($window.ga) ga('send', 'pageview', {page: $location.path()});
|
||||
$rootScope.$on('$stateChangeSuccess', function(e, to, toParams, from, fromParams) {
|
||||
$rootScope.prevState = { name: from.name, params: fromParams };
|
||||
if(to.url) { // Only track states that have a URL
|
||||
if ($window.ga) ga('send', 'pageview', {page: $location.path()});
|
||||
}
|
||||
});
|
||||
|
||||
// Global Reference variables
|
||||
@@ -24,6 +27,7 @@ angular.module('app', ['ui.router', 'shipyard', 'ngLodash', 'app.templates'])
|
||||
$rootScope.fCrd = d3.format(',.0f');
|
||||
$rootScope.fPwr = d3.format(',.2f');
|
||||
$rootScope.fRound = function(d) { return d3.round(d, 2) };
|
||||
$rootScope.fRound4 = function(d) { return d3.round(d, 4) };
|
||||
$rootScope.fPct = d3.format('.2%');
|
||||
$rootScope.fRPct = d3.format('%');
|
||||
$rootScope.fTime = function(d) { return Math.floor(d/60) + ":" + ("00" + (d%60)).substr(-2,2); };
|
||||
|
||||
@@ -23,11 +23,20 @@ angular.module('app').config(['$provide','$stateProvider', '$urlRouterProvider',
|
||||
throw { type: 'no-ship', message: $p.shipId };
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
sticky: true
|
||||
})
|
||||
.state('shipyard', { url: '/', templateUrl: 'views/page-shipyard.html', controller: 'ShipyardController' })
|
||||
.state('comparison', { url: '/comparison', templateUrl: 'views/page-comparison.html', controller: 'ComparisonController' })
|
||||
.state('error', { params: {type:null, message:null, details: null }, templateUrl: 'views/page-error.html', controller: 'ErrorController' })
|
||||
.state('shipyard', { url: '/', templateUrl: 'views/page-shipyard.html', controller: 'ShipyardController', sticky: true })
|
||||
.state('comparison', { url: '/comparison', templateUrl: 'views/page-comparison.html', controller: 'ComparisonController', sticky: true })
|
||||
.state('error', { params: {type:null, message:null, details: null }, templateUrl: 'views/page-error.html', controller: 'ErrorController', sticky: true })
|
||||
|
||||
// Modal States and views
|
||||
.state('modal', { abstract: true, views:{ "modal": { templateUrl: "views/_modal.html", controller: 'ModalController' } } })
|
||||
.state('modal.about', { views: { "modal-content": { templateUrl: "views/modal-about.html" } } })
|
||||
.state('modal.export', { views: { "modal-content": { templateUrl: "views/modal-export.html", controller: 'ExportController' } } })
|
||||
.state('modal.import', { views: { "modal-content": { templateUrl: "views/modal-import.html", controller: 'ImportController' } } })
|
||||
.state('modal.delete', { views: { "modal-content": { templateUrl: "views/modal-delete.html", controller: 'DeleteController' } } });
|
||||
|
||||
|
||||
// Redirects
|
||||
$urlRouterProvider.when('/outfit','/outfit/sidewinder/');
|
||||
|
||||
@@ -15,10 +15,20 @@ angular.module('app').controller('ComparisonController', ['$rootScope', '$scope'
|
||||
shipId: shipId,
|
||||
buildName: buildName,
|
||||
ship: ship,
|
||||
code: code
|
||||
code: code,
|
||||
pctRetracted: ship.powerRetracted / ship.powerAvailable,
|
||||
pctDeployed: ship.powerDeployed / ship.powerAvailable,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$scope.predicate = 'ship.name';
|
||||
$scope.desc = false;
|
||||
|
||||
$scope.sort = function (key) {
|
||||
$scope.desc = ($scope.predicate == key)? !$scope.desc : $scope.desc;
|
||||
$scope.predicate = key;
|
||||
}
|
||||
|
||||
|
||||
}]);
|
||||
7
app/js/controllers/controller-delete.js
Normal file
7
app/js/controllers/controller-delete.js
Normal file
@@ -0,0 +1,7 @@
|
||||
angular.module('app').controller('DeleteController', ['$scope', 'Persist', function ($scope, Persist) {
|
||||
$scope.deleteAll = function () {
|
||||
Persist.deleteAll();
|
||||
$scope.$parent.dismiss();
|
||||
};
|
||||
|
||||
}]);
|
||||
@@ -25,7 +25,7 @@ angular.module('app')
|
||||
break;
|
||||
default:
|
||||
$rootScope.bodyClass = 'thargoid'; // TODO: create background imag for this
|
||||
$scope.msgPre = "Uh, this is bad..";
|
||||
$scope.msgPre = "Uh, Jameson, we have a problem..";
|
||||
$scope.errorMessage = $p.message;
|
||||
$scope.details = $p.details;
|
||||
}
|
||||
|
||||
7
app/js/controllers/controller-export.js
Normal file
7
app/js/controllers/controller-export.js
Normal file
@@ -0,0 +1,7 @@
|
||||
angular.module('app').controller('ExportController', ['$scope', 'Persist', function ($scope, Persist) {
|
||||
$scope.builds = {
|
||||
builds: Persist.builds
|
||||
// TODO: add comparisons
|
||||
};
|
||||
|
||||
}]);
|
||||
96
app/js/controllers/controller-import.js
Normal file
96
app/js/controllers/controller-import.js
Normal file
@@ -0,0 +1,96 @@
|
||||
angular.module('app').controller('ImportController', ['$scope', 'ShipsDB', 'Ship', 'Persist', 'Serializer', function ($scope, Ships, Ship, Persist, Serializer) {
|
||||
$scope.jsonValid = false;
|
||||
$scope.importData = null;
|
||||
$scope.errorMsg = null;
|
||||
|
||||
$scope.validateJson = function() {
|
||||
var importObj = null;
|
||||
$scope.jsonValid = false;
|
||||
$scope.errorMsg = null;
|
||||
$scope.builds = null;
|
||||
$scope.ships = Ships;
|
||||
|
||||
if(!$scope.importData) return;
|
||||
|
||||
try {
|
||||
importObj = angular.fromJson($scope.importData);
|
||||
} catch (e) {
|
||||
$scope.errorMsg = 'Cannot Parse JSON!';
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof importObj != 'object') {
|
||||
$scope.errorMsg = 'Must be an object!';
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!importObj.builds || !Object.keys(importObj.builds).length) && (!importObj.comparisons || !Object.keys(importObj.comparisons).length)) {
|
||||
$scope.errorMsg = 'No builds or comparisons in data';
|
||||
return;
|
||||
}
|
||||
|
||||
for (var shipId in importObj.builds) {
|
||||
var shipData = Ships[shipId];
|
||||
if (shipData) {
|
||||
for (buildName in importObj.builds[shipId]) {
|
||||
if (typeof importObj.builds[shipId][buildName] != 'string') {
|
||||
$scope.errorMsg = shipData.properties.name + ' build "' + buildName + '" must be a string!';
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Actually build the ship with the code to ensure it's valid
|
||||
Serializer.toShip(new Ship(shipId, shipData.properties, shipData.slots), importObj.builds[shipId][buildName]);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
$scope.errorMsg = shipData.properties.name + ' build "' + buildName + '" is not valid!';
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$scope.errorMsg = '"' + shipId + '" is not a valid Ship Id!';
|
||||
return;
|
||||
}
|
||||
$scope.builds = importObj.builds;
|
||||
}
|
||||
|
||||
// Check for comparison object
|
||||
// if (importObj.comparisons)
|
||||
|
||||
$scope.jsonValid = true;
|
||||
};
|
||||
|
||||
$scope.hasBuild = function (shipId, name) {
|
||||
return Persist.getBuild(shipId, name) != null;
|
||||
}
|
||||
|
||||
$scope.process = function() {
|
||||
var builds = $scope.builds;
|
||||
for (var shipId in builds) {
|
||||
for (var buildName in builds[shipId]) {
|
||||
var code = builds[shipId][buildName];
|
||||
// Update builds object such that orginal name retained, but can be renamed
|
||||
builds[shipId][buildName] = {
|
||||
code: code,
|
||||
useName: buildName
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
$scope.processed = true;
|
||||
};
|
||||
|
||||
$scope.import = function() {
|
||||
var builds = $scope.builds;
|
||||
for (var shipId in builds) {
|
||||
for (var buildName in builds[shipId]) {
|
||||
var build = builds[shipId][buildName];
|
||||
var name = build.useName.trim();
|
||||
if (name) {
|
||||
Persist.saveBuild(shipId, name, build.code);
|
||||
}
|
||||
}
|
||||
}
|
||||
$scope.$parent.dismiss();
|
||||
};
|
||||
|
||||
}]);
|
||||
14
app/js/controllers/controller-modal.js
Normal file
14
app/js/controllers/controller-modal.js
Normal file
@@ -0,0 +1,14 @@
|
||||
angular.module('app').controller('ModalController', ['$rootScope','$scope', '$state', function ($rootScope, $scope, $state) {
|
||||
var dismissListener;
|
||||
$scope.dismiss = function() {
|
||||
if ($rootScope.prevState) {
|
||||
var state = $rootScope.prevState;
|
||||
$state.go(state.name, state.params, {location: 'replace', reload: false});
|
||||
} else {
|
||||
$state.go('shipyard');
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$on('close', $scope.dismiss);
|
||||
|
||||
}]);
|
||||
@@ -135,7 +135,7 @@ angular.module('app').controller('OutfitController', ['$rootScope','$scope', '$s
|
||||
}
|
||||
|
||||
// Event listeners
|
||||
$rootScope.$on('keyup', function (e, keyEvent) {
|
||||
$scope.$on('keyup', function (e, keyEvent) {
|
||||
// CTRL + S or CMD + S will override the default and save the build is possible
|
||||
if (keyEvent.keycode == 83 && keyEvent.ctrlKey) {
|
||||
e.preventDefault();
|
||||
@@ -144,12 +144,12 @@ angular.module('app').controller('OutfitController', ['$rootScope','$scope', '$s
|
||||
});
|
||||
|
||||
// Hide any open menu/slot/etc if escape key is pressed
|
||||
$rootScope.$on('escape', function (e, keyEvent) {
|
||||
$scope.$on('escape', function (e, keyEvent) {
|
||||
$scope.selectedSlot = null;
|
||||
$scope.$apply();
|
||||
});
|
||||
// Hide any open menu/slot/etc if the background is clicked
|
||||
$rootScope.$on('close', function (e, keyEvent) {
|
||||
$scope.$on('close', function (e, keyEvent) {
|
||||
$scope.selectedSlot = null;
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,11 @@ angular.module('app').directive('componentSelect', function() {
|
||||
list.push('<li class="', o.name? 'lc' : 'c');
|
||||
if(wrap && o.class != prevClass) list.push(' cl');
|
||||
if (cid == o.id) list.push(' active');
|
||||
list.push((o.maxmass && mass > o.maxmass)? ' disabled"' : '" cpid="', id, '">', o.class, o.rating);
|
||||
list.push((o.maxmass && mass > o.maxmass)? ' disabled"' : '" cpid="', id, '">');
|
||||
if(o.mode) {
|
||||
list.push('<svg cpid="', id, '" class="icon lg"><use xlink:href="#mount-', o.mode , '"></use></svg> ');
|
||||
}
|
||||
list.push(o.class, o.rating);
|
||||
if(o.mode) {
|
||||
list.push('/' + o.mode);
|
||||
if(o.missile) {
|
||||
|
||||
@@ -43,7 +43,7 @@ angular.module('app').directive('shipyardHeader', ['lodash','$rootScope', 'Persi
|
||||
return;
|
||||
}
|
||||
|
||||
if (menu == 'b' && !scope.bs.hasBuilds) {
|
||||
if ((menu == 'comp' || menu == 'b') && !scope.bs.hasBuilds) {
|
||||
scope.openedMenu = null;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
* [description]
|
||||
*/
|
||||
angular.module('app').service('Persist', ['lodash', function (_) {
|
||||
var LS_KEY = 'builds';
|
||||
var LS_KEY_BUILDS = 'builds';
|
||||
var LS_KEY_COMPARISONS = 'comparisons';
|
||||
|
||||
var buildJson = localStorage.getItem(LS_KEY);
|
||||
var buildJson = localStorage.getItem(LS_KEY_BUILDS);
|
||||
|
||||
if (buildJson) {
|
||||
this.builds = angular.fromJson(localStorage.getItem(LS_KEY));
|
||||
this.builds = angular.fromJson(localStorage.getItem(LS_KEY_BUILDS));
|
||||
} else {
|
||||
this.builds = {};
|
||||
}
|
||||
@@ -29,8 +30,8 @@ angular.module('app').service('Persist', ['lodash', function (_) {
|
||||
|
||||
this.builds[shipId][name] = code;
|
||||
this.state.hasBuilds = true;
|
||||
// Persist updated build collection to localstorage
|
||||
localStorage.setItem(LS_KEY, angular.toJson(this.builds));
|
||||
// Persist updated build collection to localStorage
|
||||
localStorage.setItem(LS_KEY_BUILDS, angular.toJson(this.builds));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,9 +63,20 @@ angular.module('app').service('Persist', ['lodash', function (_) {
|
||||
delete this.builds[shipId];
|
||||
this.state.hasBuilds = Object.keys(this.builds).length > 0;
|
||||
}
|
||||
// Persist updated build collection to localstorage
|
||||
localStorage.setItem(LS_KEY, angular.toJson(this.builds));
|
||||
// Persist updated build collection to localStorage
|
||||
localStorage.setItem(LS_KEY_BUILDS, angular.toJson(this.builds));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all builds and comparisons from localStorage
|
||||
*/
|
||||
this.deleteAll = function() {
|
||||
angular.copy({}, this.builds); // Empty object but keep original instance
|
||||
angular.copy({}, this.comparisons);
|
||||
this.state.hasBuilds = false;
|
||||
localStorage.removeItem(LS_KEY_BUILDS);
|
||||
localStorage.removeItem(LS_KEY_COMPARISONS);
|
||||
}
|
||||
|
||||
}]);
|
||||
|
||||
@@ -12,7 +12,6 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
|
||||
this.incCost = true;
|
||||
this.cargoScoop = { enabled: true, c: Components.cargoScoop() };
|
||||
this.bulkheads = { incCost: true, maxClass: 8 };
|
||||
this.sgSI = null; // Shield Generator Index
|
||||
|
||||
for (p in properties) { this[p] = properties[p]; } // Copy all base properties from shipData
|
||||
|
||||
@@ -56,9 +55,6 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
|
||||
if (comps.internal[i] !== 0) {
|
||||
internal[i].id = comps.internal[i];
|
||||
internal[i].c = Components.internal(comps.internal[i]);
|
||||
if (internal[i].c.grp == 'sg') {
|
||||
this.sgSI = i;
|
||||
}
|
||||
} else {
|
||||
internal[i].id = internal[i].c = null;
|
||||
}
|
||||
@@ -70,28 +66,30 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
|
||||
* 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 c = _.reduce(this.common, optsSum, {cost: 0, power: 0, mass: 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;
|
||||
var h = _.reduce(this.hardpoints, hpSum, {cost: 0, active: 0, passive: 0, mass: 0, shieldmul: 1});
|
||||
var fsd = this.common[2].c; // Frame Shift Drive;
|
||||
var sgSI = this.findInternalByGroup('sg'); // Find Shield Generator slot Index if any
|
||||
|
||||
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.powerAvailable = this.common[0].c.pGen; // Power Plant
|
||||
this.fuelCapacity = this.common[6].c.capacity;
|
||||
this.maxMass = this.common[1].c.maxmass;
|
||||
this.maxMass = this.common[1].c.maxmass; // Thrusters Max Mass
|
||||
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;
|
||||
this.powerRetracted = c.power + i.power + h.passive + (this.cargoScoop.enabled? this.cargoScoop.c.power : 0);
|
||||
this.powerDeployed = this.powerRetracted + h.active;
|
||||
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.shieldStrength = sgSI != -1? calcShieldStrength(this.mass, this.shields, this.internal[sgSI].c, this.shieldMultiplier) : 0;
|
||||
this.armourTotal = this.armourAdded + this.armour;
|
||||
// TODO: shield recharge rate
|
||||
// TODO: shield recharge rate based pips, shield generator, power distributor
|
||||
// TODO: armor bonus / damage reduction for bulkheads
|
||||
// TODO: Damage / DPS total (for all weapons)
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -104,17 +102,35 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
|
||||
*/
|
||||
function optsSum(sum, slot) {
|
||||
var c = slot.c
|
||||
if (c) { // The slot has a component mounted
|
||||
if (c) { // The slot has a component installed
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utilify function for summing the hardpoint properties
|
||||
*
|
||||
* @private
|
||||
* @param {object} sum Sum of cost, power, etc
|
||||
* @param {object} slot Slot object
|
||||
* @return {object} The mutated sum object
|
||||
*/
|
||||
function hpSum(sum, slot) {
|
||||
var c = slot.c
|
||||
if (c) { // The slot has a component installed
|
||||
sum.cost += (slot.incCost && c.cost)? c.cost : 0;
|
||||
sum[c.passive? 'passive': 'active'] += slot.enabled? c.power : 0;
|
||||
sum.mass += c.mass || 0;
|
||||
sum.shieldmul += c.shieldmul || 0;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
Ship.prototype.useBulkhead = function(index) {
|
||||
this.bulkheads.id = index;
|
||||
this.bulkheads.c = Components.bulkheads(this.id, index);
|
||||
@@ -123,40 +139,44 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Has logic handling components that you may only have 1 of (Shield Generator or Refinery).
|
||||
*
|
||||
* @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.grp == '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;
|
||||
// Slot is an internal slot, is not being emptied, and the selected component group/type must be of unique
|
||||
if(slotIndex != -1 && component && (component.grp == 'sg' || component.grp || 'rf')) {
|
||||
// Find another internal slot that already has this type/group installed
|
||||
var similarSlotIndex = this.findInternalByGroup(component.grp);
|
||||
// If another slot has an installed component with of the same type
|
||||
if (similarSlotIndex != -1 && similarSlotIndex != slotIndex) {
|
||||
// Empty the slot
|
||||
this.internal[similarSlotIndex].id = null;
|
||||
this.internal[similarSlotIndex].c = null;
|
||||
}
|
||||
}
|
||||
// Update slot with selected component (or empty)
|
||||
slot.id = id;
|
||||
slot.c = component;
|
||||
this.updateTotals();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Find an internal slot that has an installed component of the specific group.
|
||||
*
|
||||
* @param {string} group Component group/type
|
||||
* @return {number} The index of the slot in ship.internal
|
||||
*/
|
||||
Ship.prototype.findInternalByGroup = function(group) {
|
||||
return _.findIndex(this.internal, function (slot) {
|
||||
return slot.c && slot.c.grp == group;
|
||||
});
|
||||
};
|
||||
|
||||
return Ship;
|
||||
}]);
|
||||
|
||||
Reference in New Issue
Block a user