diff --git a/package-lock.json b/package-lock.json index 6dc12b01..40b03446 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "coriolis_shipyard", - "version": "2.5.2", + "version": "2.5.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/app/shipyard/Module.js b/src/app/shipyard/Module.js index 3728d539..f4f48401 100755 --- a/src/app/shipyard/Module.js +++ b/src/app/shipyard/Module.js @@ -64,10 +64,29 @@ export default class Module { } } } - // Sanitise the resultant value to 4dp equivalent 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 @@ -79,6 +98,9 @@ export default class Module { if (!this.mods) { this.mods = {}; } + if (!this.origVals) { + this.origVals = {}; + } if (valueiswithspecial && this.blueprint && this.blueprint.special) { // This module has a special effect, see if we need to alter the stored value const modifierActions = Modifications.modifierActions[this.blueprint.special.edname]; @@ -117,7 +139,7 @@ export default class Module { _getModifiedValue(name) { const modification = Modifications.modifications[name]; let result = this[name]; - + // console.log(`${name} = ${this[name]}`) if (!result) { if (modification && modification.method === 'additive') { // Additive modifications start at 0 rather than NULL @@ -135,7 +157,7 @@ export default class Module { if (modification.type === 'percentage') { modValue = this.getModValue(name) / 10000; } else if (modification.type === 'numeric') { - modValue = this.getModValue(name) / 100; + modValue = this.getModValue(name)/ 100; } else { modValue = this.getModValue(name); } diff --git a/src/app/shipyard/Ship.js b/src/app/shipyard/Ship.js index eddafc19..0495391e 100755 --- a/src/app/shipyard/Ship.js +++ b/src/app/shipyard/Ship.js @@ -490,7 +490,6 @@ export default class Ship { // Value passed is invalid; reset it to 0 value = 0; } - // Handle special cases if (name === 'pgen') { // 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 this.upgradeInternals(internal, 1 + this.standard.length + this.hardpoints.length, priorities, enabled, modifications, blueprints, version); } - + return this.buildWith( { bulkheads: code.charAt(0) * 1, diff --git a/src/app/utils/BlueprintFunctions.js b/src/app/utils/BlueprintFunctions.js index fda46761..4a51f19f 100644 --- a/src/app/utils/BlueprintFunctions.js +++ b/src/app/utils/BlueprintFunctions.js @@ -225,7 +225,13 @@ export function isValueBeneficial(feature, value) { */ export function getBlueprint(name, module) { // 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.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 diff --git a/src/app/utils/JournalUtils.js b/src/app/utils/JournalUtils.js index f0e788fb..c55eed99 100644 --- a/src/app/utils/JournalUtils.js +++ b/src/app/utils/JournalUtils.js @@ -11,16 +11,16 @@ import { getBlueprint } from './BlueprintFunctions' * @param {string} fdname the FD Name of the module * @return {Module} the module */ -function _moduleFromFdName(fdname) { - if (!fdname) return null; - fdname = fdname.toLowerCase(); +function _moduleFromFdName (fdname) { + if (!fdname) return null + fdname = fdname.toLowerCase() // Check standard modules for (const grp in Modules.standard) { if (Modules.standard.hasOwnProperty(grp)) { for (const i in Modules.standard[grp]) { if (Modules.standard[grp][i].symbol && Modules.standard[grp][i].symbol.toLowerCase() === fdname) { // 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]) { if (Modules.hardpoints[grp][i].symbol && Modules.hardpoints[grp][i].symbol.toLowerCase() === fdname) { // 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]) { if (Modules.internal[grp][i].symbol && Modules.internal[grp][i].symbol.toLowerCase() === fdname) { // 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) // Not found - return null; + return null } + /** * Build a ship from the journal Loadout event JSON * @param {object} json the Loadout event JSON * @return {Ship} the built ship */ -export function shipFromLoadoutJSON(json) { +export function shipFromLoadoutJSON (json) { // Start off building a basic ship - const shipModel = shipModelFromJson(json); + const shipModel = shipModelFromJson(json) 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); - ship.buildWith(null); + let ship = new Ship(shipModel, shipTemplate.properties, shipTemplate.slots) + ship.buildWith(null) // Initial Ship building, don't do engineering yet. for (const module of json.Modules) { + if (!module.Engineering) module.Engineering = {}; switch (module.Slot) { // Cargo Hatch. case 'CargoHatch': - ship.cargoHatch.enabled = module.On; - ship.cargoHatch.priority = module.Priority; - break; + ship.cargoHatch.enabled = module.On + ship.cargoHatch.priority = module.Priority + break // Add the bulkheads case 'Armour': - if (module.Item.endsWith('_Armour_Grade1')) { - ship.useBulkhead(0, true); - } else if (module.Item.endsWith('_Armour_Grade2')) { - ship.useBulkhead(1, true); - } else if (module.Item.endsWith('_Armour_Grade3')) { - ship.useBulkhead(2, true); - } else if (module.Item.endsWith('_Armour_Mirrored')) { - ship.useBulkhead(3, true); - } else if (module.Item.endsWith('_Armour_Reactive')) { - ship.useBulkhead(4, true); + if (module.Item.toLowerCase().endsWith('_armour_grade1')) { + ship.useBulkhead(0, true) + } else if (module.Item.toLowerCase().endsWith('_armour_grade2')) { + ship.useBulkhead(1, true) + } else if (module.Item.toLowerCase().endsWith('_armour_grade3')) { + ship.useBulkhead(2, true) + } else if (module.Item.toLowerCase().endsWith('_armour_mirrored')) { + ship.useBulkhead(3, true) + } else if (module.Item.toLowerCase().endsWith('_armour_reactive')) { + ship.useBulkhead(4, true) } else { - throw 'Unknown bulkheads "' + module.Item + '"'; + throw 'Unknown bulkheads "' + module.Item + '"' } - ship.bulkheads.enabled = true; - break; + ship.bulkheads.enabled = true + _addModifications(ship.bulkheads.m, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level) + break case 'PowerPlant': - const powerplant = _moduleFromFdName(module.Item); - ship.use(ship.standard[0], powerplant, true); - ship.standard[0].enabled = module.On; - ship.standard[0].priority = module.Priority; - _addModifications(powerplant, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level); - break; + const powerplant = _moduleFromFdName(module.Item) + ship.use(ship.standard[0], powerplant, true) + ship.standard[0].enabled = module.On + ship.standard[0].priority = module.Priority + _addModifications(powerplant, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level) + break case 'MainEngines': - const thrusters = _moduleFromFdName(module.Item); - ship.use(ship.standard[1], thrusters, true); - ship.standard[1].enabled = module.On; - ship.standard[1].priority = module.Priority; - break; + const thrusters = _moduleFromFdName(module.Item) + ship.use(ship.standard[1], thrusters, true) + ship.standard[1].enabled = module.On + ship.standard[1].priority = module.Priority + _addModifications(thrusters, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level) + break case 'FrameShiftDrive': - const frameshiftdrive = _moduleFromFdName(module.Item); - ship.use(ship.standard[2], frameshiftdrive, true); - ship.standard[2].enabled = module.On; - ship.standard[2].priority = module.Priority; - break; + const frameshiftdrive = _moduleFromFdName(module.Item) + ship.use(ship.standard[2], frameshiftdrive, true) + ship.standard[2].enabled = module.On + ship.standard[2].priority = module.Priority + _addModifications(frameshiftdrive, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level) + break case 'LifeSupport': - const lifesupport = _moduleFromFdName(module.Item); - ship.use(ship.standard[3], lifesupport, true); - ship.standard[3].enabled = module.On === true; - ship.standard[3].priority = module.Priority; - break; + const lifesupport = _moduleFromFdName(module.Item) + ship.use(ship.standard[3], lifesupport, true) + ship.standard[3].enabled = module.On === true + ship.standard[3].priority = module.Priority + _addModifications(lifesupport, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level) + break case 'PowerDistributor': - const powerdistributor = _moduleFromFdName(module.Item); - ship.use(ship.standard[4], powerdistributor, true); - ship.standard[4].enabled = module.On; - ship.standard[4].priority = module.Priority; - break; + const powerdistributor = _moduleFromFdName(module.Item) + ship.use(ship.standard[4], powerdistributor, true) + ship.standard[4].enabled = module.On + ship.standard[4].priority = module.Priority + _addModifications(powerdistributor, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level) + break case 'Radar': - const sensors = _moduleFromFdName(module.Item); - ship.use(ship.standard[5], sensors, true); - ship.standard[5].enabled = module.On; - ship.standard[5].priority = module.Priority; - break; + const sensors = _moduleFromFdName(module.Item) + ship.use(ship.standard[5], sensors, true) + ship.standard[5].enabled = module.On + ship.standard[5].priority = module.Priority + _addModifications(sensors, module.Engineering.Modifiers, module.Engineering.BlueprintName, module.Engineering.Level) + break case 'FuelTank': - const fueltank = _moduleFromFdName(module.Item); - ship.use(ship.standard[6], fueltank, true); - ship.standard[6].enabled = true; - ship.standard[6].priority = 0; - break; + const fueltank = _moduleFromFdName(module.Item) + ship.use(ship.standard[6], fueltank, true) + ship.standard[6].enabled = true + ship.standard[6].priority = 0 + break default: } if (module.Slot.search(/Hardpoint/) !== -1) { // Add hardpoints - let hardpointClassNum = -1; - let hardpointSlotNum = -1; - let hardpointArrayNum = 0; + let hardpointClassNum = -1 + let hardpointSlotNum = -1 + let hardpointArrayNum = 0 for (let i in shipTemplate.slots.hardpoints) { if (shipTemplate.slots.hardpoints[i] === hardpointClassNum) { // Another slot of the same class - hardpointSlotNum++; + hardpointSlotNum++ } else { // The first slot of a new class - hardpointClassNum = shipTemplate.slots.hardpoints[i]; - hardpointSlotNum = 1; + hardpointClassNum = shipTemplate.slots.hardpoints[i] + hardpointSlotNum = 1 } // Now that we know what we're looking for, find it - const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum; - const hardpointSlot = json.Modules.find(elem => elem.Slot === hardpointName); + const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum + const hardpointSlot = json.Modules.find(elem => elem.Slot === hardpointName) if (!hardpointSlot) { // This can happen with old imports that don't contain new hardpoints } else if (!hardpointSlot) { // No module } else { - const hardpoint = _moduleFromFdName(hardpointSlot.Item); - ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true); - ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On; - ship.hardpoints[hardpointArrayNum].priority = hardpointSlot.Priority; + const hardpoint = _moduleFromFdName(hardpointSlot.Item) + ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true) + ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On + 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) { - let internalSlotNum = 1; - let militarySlotNum = 1; + let internalSlotNum = 1 + let militarySlotNum = 1 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 - let internalSlot = null; + let internalSlot = null if (isMilitary) { - const internalName = 'Military0' + militarySlotNum; - internalSlot = json.Modules.find(elem => elem.Slot === internalName); - militarySlotNum++; + const internalName = 'Military0' + militarySlotNum + internalSlot = json.Modules.find(elem => elem.Slot === internalName) + militarySlotNum++ } else { // Slot numbers are not contiguous so handle skips. while (internalSlot === null && internalSlotNum < 99) { // Slot sizes have no relationship to the actual size, either, so check all possibilities 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)) { - internalSlot = json.Modules.find(elem => elem.Slot === internalName); - break; + internalSlot = json.Modules.find(elem => elem.Slot === internalName) + break } } - internalSlotNum++; + internalSlotNum++ } } @@ -202,11 +211,12 @@ export function shipFromLoadoutJSON(json) { } else if (!internalSlot) { // No module } else { - const internalJson = internalSlot; - const internal = _moduleFromFdName(internalJson.Item); - ship.use(ship.internal[i], internal, true); - ship.internal[i].enabled = internalJson.On === true; - ship.internal[i].priority = internalJson.Priority; + const internalJson = internalSlot + const internal = _moduleFromFdName(internalJson.Item) + ship.use(ship.internal[i], internal, true) + ship.internal[i].enabled = internalJson.On === true + 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 if (!ship.cargoHatch) { - ship.cargoHatch.enabled = false; - ship.cargoHatch.priority = 4; + ship.cargoHatch.enabled = false + ship.cargoHatch.priority = 4 } - console.log(ship); + console.log(ship) // 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} specialModifications special modification */ -function _addModifications(module, modifiers, blueprint, grade, specialModifications) { - if (!modifiers) return; - console.log(modifiers); - let special; +function _addModifications (module, modifiers, blueprint, grade, specialModifications) { + if (!modifiers) return + let special if (specialModifications) { special = Modifications.specials[Object.keys(specialModifications)[0]] } for (const i in modifiers) { // Some special modifications - if (modifiers[i].name === 'mod_weapon_clip_size_override') { - // This is a numeric addition to the clip size, but we need to work it out in terms of being a percentage so - // that it works the same as other modifications - const origClip = module.clip || 1; - module.setModValue('clip', ((modifiers[i].value - origClip) / origClip) * 10000); - } else if (modifiers[i].name === 'mod_weapon_burst_size') { - // 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') { - // This is an absolute number that acts as an override - module.setModValue('burstrof', modifiers[i].value * 100); - } else if (modifiers[i].name === 'mod_weapon_falloffrange_from_range') { - // Obtain the falloff value directly from the range - module.setModValue('fallofffromrange', 1); - } else if (modifiers[i].name && modifiers[i].name.startsWith('special_')) { - // We don't add special effects directly, but keep a note of them so they can be added when fetching values - 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); - } + // Look up the modifiers to find what we need to do + const findMod = val => Object.keys(Modifications.modifierActions).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0) + const modifierActions = Modifications.modifierActions[findMod(modifiers[i].Label)] + console.log(`${modifiers[i].Label}: ${findMod(modifiers[i].Label)}`) + //TODO: Figure out how to scale this value. + if (!!modifiers[i].LessIsGood) { + + } + let value = modifiers[i].Value / modifiers[i].OriginalValue * 100 - 100; + // 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 + module.setModValue(action, value * 100) } } } // Add the blueprint definition, grade and special if (blueprint) { - module.blueprint = getBlueprint(blueprint, module); + console.log(blueprint); + module.blueprint = getBlueprint(blueprint, module) if (grade) { - module.blueprint.grade = Number(grade); + module.blueprint.grade = Number(grade) } if (special) { - module.blueprint.special = special; + module.blueprint.special = special } } -} \ No newline at end of file +}