More refactoring and features

This commit is contained in:
Colin McLeod
2015-05-04 18:31:34 -07:00
parent c5cdebc5a7
commit f4df56e34a
57 changed files with 1186 additions and 708 deletions

View File

@@ -55,21 +55,22 @@ angular.module('app').controller('OutfitController', ['$rootScope','$scope', '$s
*/
$scope.select = function(type, slot, e) {
e.stopPropagation();
if (e.srcElement.id) {
if(type == 'h') {
ship.use(slot, e.srcElement.id, Components.hardpoints(e.srcElement.id));
} else if (type == 'c') {
ship.use(slot, e.srcElement.id, Components.common(ship.common.indexOf(slot), e.srcElement.id));
} else if (type == 'i') {
ship.use(slot, e.srcElement.id, Components.internal(e.srcElement.id));
} else if (type == 'b') {
ship.useBulkhead(e.srcElement.id);
} else {
var id = angular.element(e.srcElement).attr('cpid'); // Get component ID
if (id) {
if (id == 'empty') {
ship.use(slot, null, null);
} else if(type == 'h') {
ship.use(slot, id, Components.hardpoints(id));
} else if (type == 'c') {
ship.use(slot, id, Components.common(ship.common.indexOf(slot), id));
} else if (type == 'i') {
ship.use(slot, id, Components.internal(id));
} else if (type == 'b') {
ship.useBulkhead(id);
}
$scope.selectedSlot = null;
$scope.code = Serializer.fromShip(ship);
$state.go('outfit', {shipId: ship.id, code: $scope.code, bn: $scope.buildName}, {location:'replace', notify:false});
updateState();
}
}
@@ -80,7 +81,7 @@ angular.module('app').controller('OutfitController', ['$rootScope','$scope', '$s
if ($scope.buildName && $scope.savedCode) {
Serializer.toShip(ship, $scope.savedCode); // Repopulate with components from last save
$scope.code = $scope.savedCode;
$state.go('outfit', {shipId: ship.id, code: $scope.savedCode, bn: $scope.buildName}, {location:'replace', notify:false});
updateState();
}
};
@@ -89,11 +90,18 @@ angular.module('app').controller('OutfitController', ['$rootScope','$scope', '$s
* for this ship & with the exact name.
*/
$scope.saveBuild = function() {
if($scope.buildName && $scope.code != $scope.savedCode) {
if (!$scope.buildName) {
return;
}
// No change hav been made, i.e. save ship default build under a name
if (!$scope.code) {
$scope.code = Serializer.fromShip(ship);
}
// Only save if there a build name and a change has been made or the build has never been saved
if ($scope.code != $scope.savedCode) {
Persist.saveBuild(ship.id, $scope.buildName, $scope.code);
$scope.savedCode = $scope.code;
// Edge case TODO: comment more
$state.go('outfit', {shipId: ship.id, code: $scope.savedCode, bn: $scope.buildName}, {location:'replace', notify:false});
updateState();
}
}
@@ -111,6 +119,22 @@ angular.module('app').controller('OutfitController', ['$rootScope','$scope', '$s
$scope.savedCode = Persist.getBuild(ship.id, $scope.buildName);
}
$scope.toggleCost = function(item) {
item.incCost = !item.incCost;
ship.updateTotals();
};
$scope.togglePwr = function(item) {
item.enabled = !item.enabled;
ship.updateTotals();
};
// Utilify functions
function updateState() {
$state.go('outfit', {shipId: ship.id, code: $scope.code, bn: $scope.buildName}, {location:'replace', notify:false});
}
// Event listeners
$rootScope.$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) {

View File

@@ -1,41 +1,68 @@
angular.module('app').directive('componentSelect', [ function() {
angular.module('app').directive('componentSelect', function() {
// Generting the HTML in this manner is MUCH faster than using an angular template.
function appendGroup(list, opts, cid, mass) {
var prevClass = null, prevRating = null;
var count = Object.keys(opts).length;
for (id in opts) {
var o = opts[id];
list.push('<li class="', o.name? 'lc' : 'c');
if(o.class != prevClass && count > 6) list.push(' cl');
if (cid == id) list.push(' active');
list.push((o.maxmass && mass > o.maxmass)? ' disabled"' : '" cpid="', id, '">', o.class, o.rating);
if(o.mode) {
list.push('/' + o.mode);
if(o.missile) {
list.push(o.missile);
}
}
if(o.name) list.push(' ' + o.name);
list.push('</li>');
prevClass = o.class;
prevRating= o.rating;
}
}
return {
restrict: 'A',
scope:{
opts: '=', // Component Options object
mass: '=' // Current ship mass
opts: '=', // Component Options object
groups: '=', // Groups of Component Options
mass: '=', // Current ship unladen mass
s: '=' // Current Slot
},
link: function(scope, element) {
var list = [], o, id;
var list = [];
var cid = scope.s.id; // Slot's current component id
var component = scope.s.c; // Slot's Current Component (may be null/undefined)
var opts = scope.opts;
var groups = scope.groups;
var mass = scope.mass || 0;
// Generting the HTML in this manner is MUCH faster than using an angular template.
for (id in opts) {
o = opts[id];
list.push('<li class="');
list.push(o.name? 'lc' : 'c');
if (o.maxmass && mass > o.maxmass) { // Omit id if mass is exceeded making it 'disabled'
list.push(' disabled"');
} else {
list.push('" id="');
if(groups) {
// At present time slots with grouped options (Hardpoints and Internal) can be empty
list.push('<div class="empty-c" cpid="empty">EMPTY</div>');
for (g in groups) {
var grp = groups[g];
var grpCode = grp[Object.keys(grp)[0]].grp; // Nasty operation to get the grp property of the first/any single component
list.push('<div id="', grpCode ,'" class="select-group">', g, '</div><ul>');
appendGroup(list, grp, cid, mass);
list.push('</ul>');
}
list.push(id);
list.push('">');
list.push(o.class);
list.push(o.rating);
if(o.mode) {
list.push('/' + o.mode);
if(o.missile) {
list.push(o.missile);
}
}
if(o.name) {
list.push(' ' + o.name);
}
list.push('</li>');
} else {
list.push('<ul>');
appendGroup(list, opts, cid, mass);
list.push('</ul>');
}
element.html('<ul>' + list.join('') + '</ul>');
element.html(list.join(''));
// If groups are present and a component is already selectd
if (groups && component && component.grp) {
var groupElement = angular.element(document.getElementById(component.grp));
var parentElem = element[0].parentElement;
parentElem.scrollTop = groupElement[0].offsetTop; // Scroll to currently selected group
}
}
};
}]);
});

View File

@@ -1,4 +1,4 @@
angular.module('app').directive('shipyardHeader', ['$rootScope', 'Persist', function ($rootScope, Persist) {
angular.module('app').directive('shipyardHeader', ['lodash','$rootScope', 'Persist', function (_, $rootScope, Persist) {
return {
restrict: 'E',
@@ -10,15 +10,33 @@ angular.module('app').directive('shipyardHeader', ['$rootScope', 'Persist', func
scope.allBuilds = Persist.builds;
scope.bs = Persist.state;
// Insurance options and management here for now.
$rootScope.insurance = {
opts: [
{ name:'Standard', pct: 0.05 },
{ name:'Alpha', pct: 0.025 },
{ name:'Beta', pct: 0.035 }
]
}
var insIndex = _.findIndex($rootScope.insurance.opts, 'name', localStorage.getItem('insurance'));
$rootScope.insurance.current = $rootScope.insurance.opts[insIndex != -1? insIndex : 0];
// Close menus if a navigation change event occurs
$rootScope.$on('$stateChangeStart',function(){
scope.openedMenu = null;
});
$rootScope.$on('close', function (e, keyEvent) {
$rootScope.$on('close', function () {
scope.openedMenu = null;
});
scope.openMenu = function (menu) {
scope.updateInsurance = function(){
localStorage.setItem('insurance', $rootScope.insurance.current.name);
}
scope.openMenu = function (e, menu) {
e.stopPropagation();
if(menu == scope.openedMenu) {
scope.openedMenu = null;
return;

View File

@@ -1,28 +0,0 @@
angular.module('app').directive('costList', ['$rootScope', function ($r) {
return {
restrict: 'A',
scope: {
ship: '='
},
templateUrl: 'views/costs.html',
link: function (scope) {
scope.expanded = false;
scope.$r = $r;
scope.insuranceOptions = {
Alpha: 0.975,
Beta: 0.965,
Standard: 0.95
};
scope.insurance = scope.insuranceOptions.Standard;
scope.toggleExpand = function() {
scope.expanded = !scope.expanded;
}
scope.toggle = function(item) {
item.incCost = !item.incCost;
scope.ship.updateTotals();
};
}
};
}]);

View File

@@ -1,23 +0,0 @@
angular.module('app')
.directive('powerList', ['$rootScope', function ($r) {
return {
restrict: 'A',
scope: {
ship: '=ship'
},
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();
};
}
};
}]);

View File

@@ -1,52 +0,0 @@
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
};*/
}
};
}]);

View File

@@ -6,7 +6,7 @@ angular.module('app').directive('slotHardpoint', ['$rootScope', function ($r) {
size: '=',
lbl: '=',
},
templateUrl: 'views/slot-hardpoint.html',
templateUrl: 'views/_slot-hardpoint.html',
link: function (scope) {
scope.$r = $r;
}

View File

@@ -6,7 +6,7 @@ angular.module('app').directive('slotInternal', ['$rootScope', function ($r) {
lbl: '=',
opts: '='
},
templateUrl: 'views/slot-internal.html',
templateUrl: 'views/_slot-internal.html',
link: function(scope) {
scope.$r = $r;
}

View File

@@ -15,7 +15,7 @@ angular.module('app').service('Serializer', ['lodash', function (_) {
_.map(ship.hardpoints, idToStr),
_.map(ship.internal, idToStr),
];
console.log('code',_.flatten(data).join(''));
return _.flatten(data).join('');
};

View File

@@ -16,9 +16,9 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
for (p in properties) { this[p] = properties[p]; } // Copy all base properties from shipData
for (groupName in slots) { // Initialize all slots
var slotGroup = slots[groupName];
var group = this[groupName] = []; // Initialize Slot group (Common, Hardpoints, Internal)
for (slotType in slots) { // Initialize all slots
var slotGroup = slots[slotType];
var group = this[slotType] = []; // Initialize Slot group (Common, Hardpoints, Internal)
for(var i = 0; i < slotGroup.length; i++){
group.push({id: null, c: null, enabled: true, incCost: true, maxClass: slotGroup[i]});
}
@@ -115,10 +115,6 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
return sum;
}
function findInternal(slots, group) {
}
Ship.prototype.useBulkhead = function(index) {
this.bulkheads.id = index;
this.bulkheads.c = DB.components.bulkheads[this.id][index];
@@ -145,7 +141,7 @@ angular.module('shipyard').factory('Ship', ['Components', 'calcShieldStrength',
}
} else {
// Selected component is a Shield Generator
if(component.group == 'sg') {
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