Engineers. Are. Back. Probably.

This commit is contained in:
Willyb321
2018-04-14 14:50:37 +10:00
parent 8375ad95b3
commit 58b55eb3da
5 changed files with 166 additions and 155 deletions

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{ {
"name": "coriolis_shipyard", "name": "coriolis_shipyard",
"version": "2.5.2", "version": "2.5.3",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@@ -64,10 +64,29 @@ export default class Module {
} }
} }
} }
// Sanitise the resultant value to 4dp equivalent // Sanitise the resultant value to 4dp equivalent
return isNaN(result) ? result : Math.round(result); return isNaN(result) ? result : Math.round(result);
} }
/**
* Set a value for a given modification ID
* @param {Number} name The name of the modification
* @param {object} value The value of the modification. If it is a numeric value then it should be an integer scaled so that -2.34% == -234
*/
setModValueFromJournal(name, value, origVal) {
if (!this.mods) {
this.mods = {};
}
if (!this.origVals) {
this.origVals = {};
}
if (value == null || value == 0) {
delete this.mods[name];
} else {
this.mods[name] = value;
this.origVals[name] = origVal;
}
}
/** /**
* Set a value for a given modification ID * Set a value for a given modification ID
@@ -79,6 +98,9 @@ export default class Module {
if (!this.mods) { if (!this.mods) {
this.mods = {}; this.mods = {};
} }
if (!this.origVals) {
this.origVals = {};
}
if (valueiswithspecial && this.blueprint && this.blueprint.special) { if (valueiswithspecial && this.blueprint && this.blueprint.special) {
// This module has a special effect, see if we need to alter the stored value // This module has a special effect, see if we need to alter the stored value
const modifierActions = Modifications.modifierActions[this.blueprint.special.edname]; const modifierActions = Modifications.modifierActions[this.blueprint.special.edname];
@@ -117,7 +139,7 @@ export default class Module {
_getModifiedValue(name) { _getModifiedValue(name) {
const modification = Modifications.modifications[name]; const modification = Modifications.modifications[name];
let result = this[name]; let result = this[name];
// console.log(`${name} = ${this[name]}`)
if (!result) { if (!result) {
if (modification && modification.method === 'additive') { if (modification && modification.method === 'additive') {
// Additive modifications start at 0 rather than NULL // Additive modifications start at 0 rather than NULL
@@ -135,7 +157,7 @@ export default class Module {
if (modification.type === 'percentage') { if (modification.type === 'percentage') {
modValue = this.getModValue(name) / 10000; modValue = this.getModValue(name) / 10000;
} else if (modification.type === 'numeric') { } else if (modification.type === 'numeric') {
modValue = this.getModValue(name) / 100; modValue = this.getModValue(name)/ 100;
} else { } else {
modValue = this.getModValue(name); modValue = this.getModValue(name);
} }

View File

@@ -490,7 +490,6 @@ export default class Ship {
// Value passed is invalid; reset it to 0 // Value passed is invalid; reset it to 0
value = 0; value = 0;
} }
// Handle special cases // Handle special cases
if (name === 'pgen') { if (name === 'pgen') {
// Power generation // Power generation
@@ -771,7 +770,7 @@ export default class Ship {
// Alter as required due to changes in the (build) code from one version to the next // Alter as required due to changes in the (build) code from one version to the next
this.upgradeInternals(internal, 1 + this.standard.length + this.hardpoints.length, priorities, enabled, modifications, blueprints, version); this.upgradeInternals(internal, 1 + this.standard.length + this.hardpoints.length, priorities, enabled, modifications, blueprints, version);
} }
return this.buildWith( return this.buildWith(
{ {
bulkheads: code.charAt(0) * 1, bulkheads: code.charAt(0) * 1,

View File

@@ -225,7 +225,13 @@ export function isValueBeneficial(feature, value) {
*/ */
export function getBlueprint(name, module) { export function getBlueprint(name, module) {
// Start with a copy of the blueprint // Start with a copy of the blueprint
const blueprint = JSON.parse(JSON.stringify(Modifications.blueprints[name])); const findMod = val => Object.keys(Modifications.blueprints).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0)
const found = Modifications.blueprints[findMod(name)];
if (!found || !found.fdname) {
return undefined;
}
const blueprint = JSON.parse(JSON.stringify(found));
console.log(blueprint)
if (module) { if (module) {
if (module.grp === 'bh' || module.grp === 'hr' || module.grp === 'sg' || module.grp === 'psg' || module.grp === 'bsg') { if (module.grp === 'bh' || module.grp === 'hr' || module.grp === 'sg' || module.grp === 'psg' || module.grp === 'bsg') {
// Bulkheads, hull reinforcements and shield generators need to have their resistances altered by the base values // Bulkheads, hull reinforcements and shield generators need to have their resistances altered by the base values

View File

@@ -11,16 +11,16 @@ import { getBlueprint } from './BlueprintFunctions'
* @param {string} fdname the FD Name of the module * @param {string} fdname the FD Name of the module
* @return {Module} the module * @return {Module} the module
*/ */
function _moduleFromFdName(fdname) { function _moduleFromFdName (fdname) {
if (!fdname) return null; if (!fdname) return null
fdname = fdname.toLowerCase(); fdname = fdname.toLowerCase()
// Check standard modules // Check standard modules
for (const grp in Modules.standard) { for (const grp in Modules.standard) {
if (Modules.standard.hasOwnProperty(grp)) { if (Modules.standard.hasOwnProperty(grp)) {
for (const i in Modules.standard[grp]) { for (const i in Modules.standard[grp]) {
if (Modules.standard[grp][i].symbol && Modules.standard[grp][i].symbol.toLowerCase() === fdname) { if (Modules.standard[grp][i].symbol && Modules.standard[grp][i].symbol.toLowerCase() === fdname) {
// Found it // Found it
return new Module({ template: Modules.standard[grp][i] }); return new Module({template: Modules.standard[grp][i]})
} }
} }
} }
@@ -32,7 +32,7 @@ function _moduleFromFdName(fdname) {
for (const i in Modules.hardpoints[grp]) { for (const i in Modules.hardpoints[grp]) {
if (Modules.hardpoints[grp][i].symbol && Modules.hardpoints[grp][i].symbol.toLowerCase() === fdname) { if (Modules.hardpoints[grp][i].symbol && Modules.hardpoints[grp][i].symbol.toLowerCase() === fdname) {
// Found it // Found it
return new Module({ template: Modules.hardpoints[grp][i] }); return new Module({template: Modules.hardpoints[grp][i]})
} }
} }
} }
@@ -44,7 +44,7 @@ function _moduleFromFdName(fdname) {
for (const i in Modules.internal[grp]) { for (const i in Modules.internal[grp]) {
if (Modules.internal[grp][i].symbol && Modules.internal[grp][i].symbol.toLowerCase() === fdname) { if (Modules.internal[grp][i].symbol && Modules.internal[grp][i].symbol.toLowerCase() === fdname) {
// Found it // Found it
return new Module({ template: Modules.internal[grp][i] }); return new Module({template: Modules.internal[grp][i]})
} }
} }
} }
@@ -52,148 +52,157 @@ function _moduleFromFdName(fdname) {
console.log(fdname) console.log(fdname)
// Not found // Not found
return null; return null
} }
/** /**
* Build a ship from the journal Loadout event JSON * Build a ship from the journal Loadout event JSON
* @param {object} json the Loadout event JSON * @param {object} json the Loadout event JSON
* @return {Ship} the built ship * @return {Ship} the built ship
*/ */
export function shipFromLoadoutJSON(json) { export function shipFromLoadoutJSON (json) {
// Start off building a basic ship // Start off building a basic ship
const shipModel = shipModelFromJson(json); const shipModel = shipModelFromJson(json)
if (!shipModel) { if (!shipModel) {
throw 'No such ship found: "' + json.Ship + '"'; throw 'No such ship found: "' + json.Ship + '"'
} }
const shipTemplate = Ships[shipModel]; const shipTemplate = Ships[shipModel]
let ship = new Ship(shipModel, shipTemplate.properties, shipTemplate.slots); let ship = new Ship(shipModel, shipTemplate.properties, shipTemplate.slots)
ship.buildWith(null); ship.buildWith(null)
// Initial Ship building, don't do engineering yet. // Initial Ship building, don't do engineering yet.
for (const module of json.Modules) { for (const module of json.Modules) {
if (!module.Engineering) module.Engineering = {};
switch (module.Slot) { switch (module.Slot) {
// Cargo Hatch. // Cargo Hatch.
case 'CargoHatch': case 'CargoHatch':
ship.cargoHatch.enabled = module.On; ship.cargoHatch.enabled = module.On
ship.cargoHatch.priority = module.Priority; ship.cargoHatch.priority = module.Priority
break; break
// Add the bulkheads // Add the bulkheads
case 'Armour': case 'Armour':
if (module.Item.endsWith('_Armour_Grade1')) { if (module.Item.toLowerCase().endsWith('_armour_grade1')) {
ship.useBulkhead(0, true); ship.useBulkhead(0, true)
} else if (module.Item.endsWith('_Armour_Grade2')) { } else if (module.Item.toLowerCase().endsWith('_armour_grade2')) {
ship.useBulkhead(1, true); ship.useBulkhead(1, true)
} else if (module.Item.endsWith('_Armour_Grade3')) { } else if (module.Item.toLowerCase().endsWith('_armour_grade3')) {
ship.useBulkhead(2, true); ship.useBulkhead(2, true)
} else if (module.Item.endsWith('_Armour_Mirrored')) { } else if (module.Item.toLowerCase().endsWith('_armour_mirrored')) {
ship.useBulkhead(3, true); ship.useBulkhead(3, true)
} else if (module.Item.endsWith('_Armour_Reactive')) { } else if (module.Item.toLowerCase().endsWith('_armour_reactive')) {
ship.useBulkhead(4, true); ship.useBulkhead(4, true)
} else { } else {
throw 'Unknown bulkheads "' + module.Item + '"'; throw 'Unknown bulkheads "' + module.Item + '"'
} }
ship.bulkheads.enabled = true; ship.bulkheads.enabled = true
break; _addModifications(ship.bulkheads.m, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
break
case 'PowerPlant': case 'PowerPlant':
const powerplant = _moduleFromFdName(module.Item); const powerplant = _moduleFromFdName(module.Item)
ship.use(ship.standard[0], powerplant, true); ship.use(ship.standard[0], powerplant, true)
ship.standard[0].enabled = module.On; ship.standard[0].enabled = module.On
ship.standard[0].priority = module.Priority; ship.standard[0].priority = module.Priority
_addModifications(powerplant, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level); _addModifications(powerplant, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
break; break
case 'MainEngines': case 'MainEngines':
const thrusters = _moduleFromFdName(module.Item); const thrusters = _moduleFromFdName(module.Item)
ship.use(ship.standard[1], thrusters, true); ship.use(ship.standard[1], thrusters, true)
ship.standard[1].enabled = module.On; ship.standard[1].enabled = module.On
ship.standard[1].priority = module.Priority; ship.standard[1].priority = module.Priority
break; _addModifications(thrusters, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
break
case 'FrameShiftDrive': case 'FrameShiftDrive':
const frameshiftdrive = _moduleFromFdName(module.Item); const frameshiftdrive = _moduleFromFdName(module.Item)
ship.use(ship.standard[2], frameshiftdrive, true); ship.use(ship.standard[2], frameshiftdrive, true)
ship.standard[2].enabled = module.On; ship.standard[2].enabled = module.On
ship.standard[2].priority = module.Priority; ship.standard[2].priority = module.Priority
break; _addModifications(frameshiftdrive, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
break
case 'LifeSupport': case 'LifeSupport':
const lifesupport = _moduleFromFdName(module.Item); const lifesupport = _moduleFromFdName(module.Item)
ship.use(ship.standard[3], lifesupport, true); ship.use(ship.standard[3], lifesupport, true)
ship.standard[3].enabled = module.On === true; ship.standard[3].enabled = module.On === true
ship.standard[3].priority = module.Priority; ship.standard[3].priority = module.Priority
break; _addModifications(lifesupport, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
break
case 'PowerDistributor': case 'PowerDistributor':
const powerdistributor = _moduleFromFdName(module.Item); const powerdistributor = _moduleFromFdName(module.Item)
ship.use(ship.standard[4], powerdistributor, true); ship.use(ship.standard[4], powerdistributor, true)
ship.standard[4].enabled = module.On; ship.standard[4].enabled = module.On
ship.standard[4].priority = module.Priority; ship.standard[4].priority = module.Priority
break; _addModifications(powerdistributor, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
break
case 'Radar': case 'Radar':
const sensors = _moduleFromFdName(module.Item); const sensors = _moduleFromFdName(module.Item)
ship.use(ship.standard[5], sensors, true); ship.use(ship.standard[5], sensors, true)
ship.standard[5].enabled = module.On; ship.standard[5].enabled = module.On
ship.standard[5].priority = module.Priority; ship.standard[5].priority = module.Priority
break; _addModifications(sensors, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
break
case 'FuelTank': case 'FuelTank':
const fueltank = _moduleFromFdName(module.Item); const fueltank = _moduleFromFdName(module.Item)
ship.use(ship.standard[6], fueltank, true); ship.use(ship.standard[6], fueltank, true)
ship.standard[6].enabled = true; ship.standard[6].enabled = true
ship.standard[6].priority = 0; ship.standard[6].priority = 0
break; break
default: default:
} }
if (module.Slot.search(/Hardpoint/) !== -1) { if (module.Slot.search(/Hardpoint/) !== -1) {
// Add hardpoints // Add hardpoints
let hardpointClassNum = -1; let hardpointClassNum = -1
let hardpointSlotNum = -1; let hardpointSlotNum = -1
let hardpointArrayNum = 0; let hardpointArrayNum = 0
for (let i in shipTemplate.slots.hardpoints) { for (let i in shipTemplate.slots.hardpoints) {
if (shipTemplate.slots.hardpoints[i] === hardpointClassNum) { if (shipTemplate.slots.hardpoints[i] === hardpointClassNum) {
// Another slot of the same class // Another slot of the same class
hardpointSlotNum++; hardpointSlotNum++
} else { } else {
// The first slot of a new class // The first slot of a new class
hardpointClassNum = shipTemplate.slots.hardpoints[i]; hardpointClassNum = shipTemplate.slots.hardpoints[i]
hardpointSlotNum = 1; hardpointSlotNum = 1
} }
// Now that we know what we're looking for, find it // Now that we know what we're looking for, find it
const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum; const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum
const hardpointSlot = json.Modules.find(elem => elem.Slot === hardpointName); const hardpointSlot = json.Modules.find(elem => elem.Slot === hardpointName)
if (!hardpointSlot) { if (!hardpointSlot) {
// This can happen with old imports that don't contain new hardpoints // This can happen with old imports that don't contain new hardpoints
} else if (!hardpointSlot) { } else if (!hardpointSlot) {
// No module // No module
} else { } else {
const hardpoint = _moduleFromFdName(hardpointSlot.Item); const hardpoint = _moduleFromFdName(hardpointSlot.Item)
ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true); ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true)
ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On; ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On
ship.hardpoints[hardpointArrayNum].priority = hardpointSlot.Priority; ship.hardpoints[hardpointArrayNum].priority = hardpointSlot.Priority
_addModifications(hardpoint, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
} }
hardpointArrayNum++; hardpointArrayNum++
} }
} }
if (module.Slot.search(/Slot\d/) !== -1) { if (module.Slot.search(/Slot\d/) !== -1) {
let internalSlotNum = 1; let internalSlotNum = 1
let militarySlotNum = 1; let militarySlotNum = 1
for (let i in shipTemplate.slots.internal) { for (let i in shipTemplate.slots.internal) {
const isMilitary = isNaN(shipTemplate.slots.internal[i]) ? shipTemplate.slots.internal[i].name = 'Military' : false; const isMilitary = isNaN(shipTemplate.slots.internal[i]) ? shipTemplate.slots.internal[i].name = 'Military' : false
// The internal slot might be a standard or a military slot. Military slots have a different naming system // The internal slot might be a standard or a military slot. Military slots have a different naming system
let internalSlot = null; let internalSlot = null
if (isMilitary) { if (isMilitary) {
const internalName = 'Military0' + militarySlotNum; const internalName = 'Military0' + militarySlotNum
internalSlot = json.Modules.find(elem => elem.Slot === internalName); internalSlot = json.Modules.find(elem => elem.Slot === internalName)
militarySlotNum++; militarySlotNum++
} else { } else {
// Slot numbers are not contiguous so handle skips. // Slot numbers are not contiguous so handle skips.
while (internalSlot === null && internalSlotNum < 99) { while (internalSlot === null && internalSlotNum < 99) {
// Slot sizes have no relationship to the actual size, either, so check all possibilities // Slot sizes have no relationship to the actual size, either, so check all possibilities
for (let slotsize = 0; slotsize < 9; slotsize++) { for (let slotsize = 0; slotsize < 9; slotsize++) {
const internalName = 'Slot' + (internalSlotNum <= 9 ? '0' : '') + internalSlotNum + '_Size' + slotsize; const internalName = 'Slot' + (internalSlotNum <= 9 ? '0' : '') + internalSlotNum + '_Size' + slotsize
if (json.Modules.find(elem => elem.Slot === internalName)) { if (json.Modules.find(elem => elem.Slot === internalName)) {
internalSlot = json.Modules.find(elem => elem.Slot === internalName); internalSlot = json.Modules.find(elem => elem.Slot === internalName)
break; break
} }
} }
internalSlotNum++; internalSlotNum++
} }
} }
@@ -202,11 +211,12 @@ export function shipFromLoadoutJSON(json) {
} else if (!internalSlot) { } else if (!internalSlot) {
// No module // No module
} else { } else {
const internalJson = internalSlot; const internalJson = internalSlot
const internal = _moduleFromFdName(internalJson.Item); const internal = _moduleFromFdName(internalJson.Item)
ship.use(ship.internal[i], internal, true); ship.use(ship.internal[i], internal, true)
ship.internal[i].enabled = internalJson.On === true; ship.internal[i].enabled = internalJson.On === true
ship.internal[i].priority = internalJson.Priority; ship.internal[i].priority = internalJson.Priority
_addModifications(internal, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level)
} }
} }
} }
@@ -214,13 +224,13 @@ export function shipFromLoadoutJSON(json) {
} }
// We don't have any information on it so guess it's priority 5 and disabled // We don't have any information on it so guess it's priority 5 and disabled
if (!ship.cargoHatch) { if (!ship.cargoHatch) {
ship.cargoHatch.enabled = false; ship.cargoHatch.enabled = false
ship.cargoHatch.priority = 4; ship.cargoHatch.priority = 4
} }
console.log(ship); console.log(ship)
// Now update the ship's codes before returning it // Now update the ship's codes before returning it
return ship.updatePowerPrioritesString().updatePowerEnabledString().updateModificationsString(); return ship.updatePowerPrioritesString().updatePowerEnabledString().updateModificationsString()
} }
/** /**
@@ -231,69 +241,43 @@ export function shipFromLoadoutJSON(json) {
* @param {Object} grade the grade of the modification * @param {Object} grade the grade of the modification
* @param {Object} specialModifications special modification * @param {Object} specialModifications special modification
*/ */
function _addModifications(module, modifiers, blueprint, grade, specialModifications) { function _addModifications (module, modifiers, blueprint, grade, specialModifications) {
if (!modifiers) return; if (!modifiers) return
console.log(modifiers); let special
let special;
if (specialModifications) { if (specialModifications) {
special = Modifications.specials[Object.keys(specialModifications)[0]] special = Modifications.specials[Object.keys(specialModifications)[0]]
} }
for (const i in modifiers) { for (const i in modifiers) {
// Some special modifications // Some special modifications
if (modifiers[i].name === 'mod_weapon_clip_size_override') { // Look up the modifiers to find what we need to do
// This is a numeric addition to the clip size, but we need to work it out in terms of being a percentage so const findMod = val => Object.keys(Modifications.modifierActions).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0)
// that it works the same as other modifications const modifierActions = Modifications.modifierActions[findMod(modifiers[i].Label)]
const origClip = module.clip || 1; console.log(`${modifiers[i].Label}: ${findMod(modifiers[i].Label)}`)
module.setModValue('clip', ((modifiers[i].value - origClip) / origClip) * 10000); //TODO: Figure out how to scale this value.
} else if (modifiers[i].name === 'mod_weapon_burst_size') { if (!!modifiers[i].LessIsGood) {
// This is an absolute number that acts as an override
module.setModValue('burst', modifiers[i].value * 100); }
} else if (modifiers[i].name === 'mod_weapon_burst_rof') { let value = modifiers[i].Value / modifiers[i].OriginalValue * 100 - 100;
// This is an absolute number that acts as an override // Carry out the required changes
module.setModValue('burstrof', modifiers[i].value * 100); for (const action in modifierActions) {
} else if (modifiers[i].name === 'mod_weapon_falloffrange_from_range') { if (isNaN(modifierActions[action])) {
// Obtain the falloff value directly from the range module.setModValue(action, modifierActions[action])
module.setModValue('fallofffromrange', 1); } else {
} else if (modifiers[i].name && modifiers[i].name.startsWith('special_')) { const actionValue = modifierActions[action] * value
// We don't add special effects directly, but keep a note of them so they can be added when fetching values module.setModValue(action, value * 100)
special = Modifications.specials[modifiers[i].name];
} else {
// Look up the modifiers to find what we need to do
const findMod = val => {
return Object.keys(Modifications.modifierActions).find(elem => {
return elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_)/igm, '')) >= 0
})
};
console.log(i + ': ' + findMod(modifiers[i].Label))
const modifierActions = Modifications.modifierActions[findMod(modifiers[i].Label)];
console.log(modifierActions);
//TODO: Figure out how to scale this value.
let value = modifiers[i].Value;
console.log(`${i}: ${value}`)
// Carry out the required changes
for (const action in modifierActions) {
if (isNaN(modifierActions[action])) {
module.setModValue(action, modifierActions[action]);
} else {
const actionValue = modifierActions[action] * value;
let mod = module.getModValue(action) / 10000;
if (!mod) {
mod = 0;
}
module.setModValue(action, ((1 + mod) * (1 + actionValue) - 1) * 10000);
}
} }
} }
} }
// Add the blueprint definition, grade and special // Add the blueprint definition, grade and special
if (blueprint) { if (blueprint) {
module.blueprint = getBlueprint(blueprint, module); console.log(blueprint);
module.blueprint = getBlueprint(blueprint, module)
if (grade) { if (grade) {
module.blueprint.grade = Number(grade); module.blueprint.grade = Number(grade)
} }
if (special) { if (special) {
module.blueprint.special = special; module.blueprint.special = special
} }
} }
} }