mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-10 07:05:35 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5f61d7ae8 | ||
|
|
8a5d4a36bf | ||
|
|
2c9237626d | ||
|
|
37f889e317 | ||
|
|
f86ba48295 | ||
|
|
aac35633a3 | ||
|
|
e73e0a305d | ||
|
|
4b2b0efe37 | ||
|
|
8fe20f6f65 | ||
|
|
11af7f567a | ||
|
|
3b8444482f | ||
|
|
c09e1b1b3e | ||
|
|
5770cf8d39 | ||
|
|
6da09f2e5d | ||
|
|
294fadf7cd | ||
|
|
2a97678574 | ||
|
|
76b3bd34f5 | ||
|
|
02bfecb92d | ||
|
|
719759ad56 | ||
|
|
fd446b29ba | ||
|
|
e5552d3e10 | ||
|
|
50946eeeb8 | ||
|
|
faab41117c | ||
|
|
0ab59c1f9a | ||
|
|
1067dceaa3 | ||
|
|
9042de422a | ||
|
|
f0547feb93 | ||
|
|
f863daa347 | ||
|
|
fdb202e7d6 | ||
|
|
c6bde19052 |
23
ChangeLog.md
23
ChangeLog.md
@@ -1,4 +1,25 @@
|
|||||||
#2.2.x
|
#2.2.4
|
||||||
|
* Add shortlink for outfitting page
|
||||||
|
* Use coriolis-data 2.2.4:
|
||||||
|
* Fix incorrect ID for class 5 luxury passenger cabin
|
||||||
|
* Add damage type modifier
|
||||||
|
* Change modifications from simple strings to objects, to allow more data-driven behaviour
|
||||||
|
* Add special effects
|
||||||
|
* Modification tooltip now shows special effect
|
||||||
|
|
||||||
|
#2.2.3
|
||||||
|
* Fix hull boost calculation - now shows correct % modifier and total armour
|
||||||
|
* Fix import of DiamondBack - can now be imported
|
||||||
|
* Fix import of Beluga - can now be imported
|
||||||
|
* Use coriolis-data 2.2.3:
|
||||||
|
* Fix mismatch between class 5 and class 7 fighter hangars - now shows correct module
|
||||||
|
* Add details for concordant sequence special effect - now shows correct damage
|
||||||
|
* Fix details for thermal shock special effect - now shows correct damage
|
||||||
|
* Add engineer blueprints
|
||||||
|
* Modification tooltip now shows name and grade of modifications for imported builds
|
||||||
|
* Retain import URL unless user changes the build - allows future updates of Coriolis to take advantage of additional build information
|
||||||
|
|
||||||
|
#2.2.2
|
||||||
* Update DPS/HPS/EPS in real-time as modifiers change
|
* Update DPS/HPS/EPS in real-time as modifiers change
|
||||||
* Use coriolis-data 2.2.2:
|
* Use coriolis-data 2.2.2:
|
||||||
* Add distributor draw modifier to shield generators
|
* Add distributor draw modifier to shield generators
|
||||||
|
|||||||
255
__tests__/fixtures/asp-test-detailed-export-v4.json
Normal file
255
__tests__/fixtures/asp-test-detailed-export-v4.json
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://cdn.coriolis.io/schemas/ship-loadout/4.json#",
|
||||||
|
"name": "Multi-purpose Asp Explorer",
|
||||||
|
"ship": "Asp Explorer",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Coriolis.io",
|
||||||
|
"url": "https://coriolis.edcd.io/outfit/asp?code=0pftiFflfddsnf5------020202033c044002v62f2i.AwRj4yvI.CwRgDBldHnJA.H4sIAAAAAAAAA2P858DAwPCXEUhwHPvx%2F78YG5AltB7I%2F8%2F0TwImJboDSPJ%2F%2B%2Ff%2Fv%2FKlX%2F%2F%2Fi3AwMTBIfARK%2FGf%2BJwVSxArStVAYqOjvz%2F%2F%2FJVo5GRhE2IBc4SKQSSz%2FDGEmCa398P8%2F%2F2%2BgTf%2F%2FAwDFxwtofAAAAA%3D%3D&bn=Multi-purpose%20Asp%20Explorer",
|
||||||
|
"code": "0pftiFflfddsnf5------020202033c044002v62f2i.AwRj4yvI.CwRgDBldHnJA.H4sIAAAAAAAAA2P858DAwPCXEUhwHPvx/78YG5AltB7I/8/0TwImJboDSPJ/+/f/v/KlX///i3AwMTBIfARK/Gf+JwVSxArStVAYqOjvz///JVo5GRhE2IBc4SKQSSz/DGEmCa398P8//2+gTf//AwDFxwtofAAAAA==",
|
||||||
|
"shipId": "asp"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"components": {
|
||||||
|
"standard": {
|
||||||
|
"bulkheads": "Lightweight Alloy",
|
||||||
|
"cargoHatch": {
|
||||||
|
"enabled": false,
|
||||||
|
"priority": 5
|
||||||
|
},
|
||||||
|
"powerPlant": {
|
||||||
|
"class": 5,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 2,
|
||||||
|
"modifications": {
|
||||||
|
"eff": -1850,
|
||||||
|
"pgen": 6,
|
||||||
|
"mass": 431
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 64,
|
||||||
|
"name": "Low emissions",
|
||||||
|
"grade": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"thrusters": {
|
||||||
|
"class": 5,
|
||||||
|
"rating": "D",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"modifications": {
|
||||||
|
"optmul": 440,
|
||||||
|
"integrity": -266,
|
||||||
|
"thermload": -1326,
|
||||||
|
"optmass": 520,
|
||||||
|
"power": 241
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 24,
|
||||||
|
"name": "Clean",
|
||||||
|
"grade": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frameShiftDrive": {
|
||||||
|
"class": 5,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"modifications": {
|
||||||
|
"mass": 5025,
|
||||||
|
"integrity": -1539,
|
||||||
|
"power": 2437,
|
||||||
|
"optmass": 4870,
|
||||||
|
"maxfuel": 370
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 26,
|
||||||
|
"name": "Increased range",
|
||||||
|
"grade": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lifeSupport": {
|
||||||
|
"class": 4,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"modifications": {
|
||||||
|
"mass": -3923,
|
||||||
|
"integrity": -1797
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 49,
|
||||||
|
"name": "Lightweight",
|
||||||
|
"grade": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"powerDistributor": {
|
||||||
|
"class": 3,
|
||||||
|
"rating": "D",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1
|
||||||
|
},
|
||||||
|
"sensors": {
|
||||||
|
"class": 5,
|
||||||
|
"rating": "D",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1
|
||||||
|
},
|
||||||
|
"fuelTank": {
|
||||||
|
"class": 5,
|
||||||
|
"rating": "C",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hardpoints": [
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
"utility": [
|
||||||
|
{
|
||||||
|
"class": 0,
|
||||||
|
"rating": "I",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Heat Sink Launcher",
|
||||||
|
"name": "Heat Sink Launcher"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 0,
|
||||||
|
"rating": "I",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Heat Sink Launcher",
|
||||||
|
"name": "Heat Sink Launcher"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 0,
|
||||||
|
"rating": "I",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Heat Sink Launcher",
|
||||||
|
"name": "Heat Sink Launcher"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 0,
|
||||||
|
"rating": "I",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Point Defence",
|
||||||
|
"name": "Point Defence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"internal": [
|
||||||
|
{
|
||||||
|
"class": 6,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Fuel Scoop"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 5,
|
||||||
|
"rating": "E",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 2,
|
||||||
|
"group": "Cargo Rack"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 3,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Shield Generator"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 3,
|
||||||
|
"rating": "E",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 2,
|
||||||
|
"group": "Cargo Rack"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 2,
|
||||||
|
"rating": "G",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Planetary Vehicle Hangar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 1,
|
||||||
|
"rating": "C",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 2,
|
||||||
|
"group": "Scanner",
|
||||||
|
"name": "Advanced Discovery Scanner"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 1,
|
||||||
|
"rating": "C",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 2,
|
||||||
|
"group": "Scanner",
|
||||||
|
"name": "Detailed Surface Scanner"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"class": 2,
|
||||||
|
"hullCost": 6135660,
|
||||||
|
"speed": 250,
|
||||||
|
"boost": 340,
|
||||||
|
"boostEnergy": 13,
|
||||||
|
"agility": 6,
|
||||||
|
"baseShieldStrength": 140,
|
||||||
|
"baseArmour": 210,
|
||||||
|
"hullMass": 280,
|
||||||
|
"masslock": 11,
|
||||||
|
"pipSpeed": 0.13,
|
||||||
|
"moduleCostMultiplier": 1,
|
||||||
|
"fuelCapacity": 32,
|
||||||
|
"cargoCapacity": 40,
|
||||||
|
"ladenMass": 435.26,
|
||||||
|
"armour": 378,
|
||||||
|
"shield": 113.43,
|
||||||
|
"shieldCells": 0,
|
||||||
|
"totalCost": 48402550,
|
||||||
|
"unladenMass": 363.26,
|
||||||
|
"totalDpe": 0,
|
||||||
|
"totalExplDpe": 0,
|
||||||
|
"totalKinDpe": 0,
|
||||||
|
"totalThermDpe": 0,
|
||||||
|
"totalDps": 0,
|
||||||
|
"totalExplDps": 0,
|
||||||
|
"totalKinDps": 0,
|
||||||
|
"totalThermDps": 0,
|
||||||
|
"totalSDps": 0,
|
||||||
|
"totalExplSDps": 0,
|
||||||
|
"totalKinSDps": 0,
|
||||||
|
"totalThermSDps": 0,
|
||||||
|
"totalEps": 1.2,
|
||||||
|
"totalHps": 1,
|
||||||
|
"shieldExplRes": 0.5,
|
||||||
|
"shieldKinRes": 0.6,
|
||||||
|
"shieldThermRes": 1.2,
|
||||||
|
"hullExplRes": 1.4,
|
||||||
|
"hullKinRes": 1.2,
|
||||||
|
"hullThermRes": 1,
|
||||||
|
"powerAvailable": 20.41,
|
||||||
|
"powerRetracted": 11.91,
|
||||||
|
"powerDeployed": 11.91,
|
||||||
|
"unladenRange": 50.45,
|
||||||
|
"fullTankRange": 47.03,
|
||||||
|
"ladenRange": 42.71,
|
||||||
|
"unladenFastestRange": 317.24,
|
||||||
|
"ladenFastestRange": 287.02,
|
||||||
|
"maxJumpCount": 7,
|
||||||
|
"topSpeed": 274.01,
|
||||||
|
"topBoost": 372.65
|
||||||
|
}
|
||||||
|
}
|
||||||
552
__tests__/fixtures/companion-api-import-2.json
Normal file
552
__tests__/fixtures/companion-api-import-2.json
Normal file
@@ -0,0 +1,552 @@
|
|||||||
|
{
|
||||||
|
"cargo": {
|
||||||
|
"capacity": 32
|
||||||
|
},
|
||||||
|
"free": false,
|
||||||
|
"fuel": {
|
||||||
|
"main": {
|
||||||
|
"capacity": 128
|
||||||
|
},
|
||||||
|
"reserve": {
|
||||||
|
"capacity": 0.81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": 31,
|
||||||
|
"modules": {
|
||||||
|
"Armour": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128049346,
|
||||||
|
"name": "BelugaLiner_Armour_Grade1",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Bobble01": [],
|
||||||
|
"Bobble02": [],
|
||||||
|
"Bobble03": [],
|
||||||
|
"Bobble04": [],
|
||||||
|
"Bobble05": [],
|
||||||
|
"Bobble06": [],
|
||||||
|
"Bobble07": [],
|
||||||
|
"Bobble08": [],
|
||||||
|
"Bobble09": [],
|
||||||
|
"Bobble10": [],
|
||||||
|
"Decal1": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128667757,
|
||||||
|
"name": "Decal_Explorer_Ranger",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Decal2": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128667742,
|
||||||
|
"name": "Decal_Combat_Deadly",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Decal3": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128667750,
|
||||||
|
"name": "Decal_Trade_Tycoon",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"EngineColour": [],
|
||||||
|
"FrameShiftDrive": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128064132,
|
||||||
|
"modifiers": {
|
||||||
|
"engineerID": 300100,
|
||||||
|
"id": 175,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"name": "mod_mass",
|
||||||
|
"type": 1,
|
||||||
|
"value": 0.4457540512085
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_health",
|
||||||
|
"type": 1,
|
||||||
|
"value": -0.24584779143333
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_passive_power",
|
||||||
|
"type": 1,
|
||||||
|
"value": 0.24457727372646
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_fsd_optimised_mass",
|
||||||
|
"type": 1,
|
||||||
|
"value": 0.49257898330688
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_fsd_max_fuel_per_jump",
|
||||||
|
"type": 2,
|
||||||
|
"value": 0.028505677357316
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_fsd_heat_rate",
|
||||||
|
"type": 2,
|
||||||
|
"value": -0.079360365867615
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"moduleTags": [
|
||||||
|
16
|
||||||
|
],
|
||||||
|
"recipeID": 128673694,
|
||||||
|
"slotIndex": 53
|
||||||
|
},
|
||||||
|
"name": "Int_Hyperdrive_Size7_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"recipeLevel": 5,
|
||||||
|
"recipeName": "FSD_LongRange",
|
||||||
|
"recipeValue": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 46160201
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"FuelTank": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128064352,
|
||||||
|
"name": "Int_FuelTank_Size7_Class3",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 1602822,
|
||||||
|
"value": 1602822
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"LifeSupport": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128064174,
|
||||||
|
"name": "Int_LifeSupport_Size8_Class2",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 1569565
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MainEngines": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128064094,
|
||||||
|
"modifiers": {
|
||||||
|
"engineerID": 300100,
|
||||||
|
"id": 253,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"name": "mod_engine_mass_curve_multiplier",
|
||||||
|
"type": 1,
|
||||||
|
"value": 0.098235413432121
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_engine_heat",
|
||||||
|
"type": 1,
|
||||||
|
"value": 0.18069696426392
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_passive_power",
|
||||||
|
"type": 1,
|
||||||
|
"value": 0.033788848668337
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_health",
|
||||||
|
"type": 1,
|
||||||
|
"value": -0.056404989212751
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_engine_mass_curve",
|
||||||
|
"type": 1,
|
||||||
|
"value": -0.027384582906961
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_engine_heat",
|
||||||
|
"type": 2,
|
||||||
|
"value": -0.072683908045292
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"moduleTags": [
|
||||||
|
17
|
||||||
|
],
|
||||||
|
"recipeID": 128673655,
|
||||||
|
"slotIndex": 52
|
||||||
|
},
|
||||||
|
"name": "Int_Engine_Size7_Class2",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"recipeLevel": 1,
|
||||||
|
"recipeName": "Engine_Dirty",
|
||||||
|
"recipeValue": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 1709638
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MediumHardpoint1": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128049436,
|
||||||
|
"name": "Hpt_BeamLaser_Turret_Medium",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 1889910
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MediumHardpoint2": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128049436,
|
||||||
|
"name": "Hpt_BeamLaser_Turret_Medium",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 1889910
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MediumHardpoint3": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128049460,
|
||||||
|
"name": "Hpt_MultiCannon_Gimbal_Medium",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 51300
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MediumHardpoint4": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128049460,
|
||||||
|
"name": "Hpt_MultiCannon_Gimbal_Medium",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 51300
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MediumHardpoint5": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128049460,
|
||||||
|
"name": "Hpt_MultiCannon_Gimbal_Medium",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 51300
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PaintJob": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128732290,
|
||||||
|
"name": "PaintJob_BelugaLiner_Tactical_White",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PlanetaryApproachSuite": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128672317,
|
||||||
|
"name": "Int_PlanetApproachSuite",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 450,
|
||||||
|
"value": 450
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PowerDistributor": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128064207,
|
||||||
|
"name": "Int_PowerDistributor_Size6_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 3128120
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PowerPlant": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128064057,
|
||||||
|
"modifiers": {
|
||||||
|
"engineerID": 300100,
|
||||||
|
"id": 277,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"name": "mod_powerplant_power",
|
||||||
|
"type": 1,
|
||||||
|
"value": 0.054692290723324
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_health",
|
||||||
|
"type": 1,
|
||||||
|
"value": -0.033690698444843
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_powerplant_heat",
|
||||||
|
"type": 1,
|
||||||
|
"value": 0.027470717206597
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mod_powerplant_heat",
|
||||||
|
"type": 2,
|
||||||
|
"value": -0.056317910552025
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"moduleTags": [
|
||||||
|
18
|
||||||
|
],
|
||||||
|
"recipeID": 128673765,
|
||||||
|
"slotIndex": 51
|
||||||
|
},
|
||||||
|
"name": "Int_Powerplant_Size6_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"recipeLevel": 1,
|
||||||
|
"recipeName": "PowerPlant_Boosted",
|
||||||
|
"recipeValue": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 14561578
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Radar": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128064239,
|
||||||
|
"name": "Int_Sensors_Size5_Class2",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 71500
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot01_Size6": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128666681,
|
||||||
|
"name": "Int_FuelScoop_Size6_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 25887249
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot02_Size6": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128064287,
|
||||||
|
"name": "Int_ShieldGenerator_Size6_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 14561578
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot03_Size6": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128727927,
|
||||||
|
"name": "Int_PassengerCabin_Size6_Class2",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 165808,
|
||||||
|
"value": 165808
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot04_Size6": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128727928,
|
||||||
|
"name": "Int_PassengerCabin_Size6_Class3",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 497429
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot05_Size5": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128727925,
|
||||||
|
"name": "Int_PassengerCabin_Size5_Class4",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 1492286
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot06_Size5": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128064342,
|
||||||
|
"name": "Int_CargoRack_Size5_Class1",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 100409,
|
||||||
|
"value": 100409
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot07_Size4": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128727922,
|
||||||
|
"name": "Int_PassengerCabin_Size4_Class1",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 17059
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot08_Size3": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128667632,
|
||||||
|
"name": "Int_Repairer_Size3_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 2361960
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot09_Size3": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128672289,
|
||||||
|
"name": "Int_BuggyBay_Size2_Class2",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 19440
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot10_Size3": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128666634,
|
||||||
|
"name": "Int_DetailedSurfaceScanner_Tiny",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 225000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Slot11_Size3": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128663561,
|
||||||
|
"name": "Int_StellarBodyDiscoveryScanner_Advanced",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 1390500
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TinyHardpoint1": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128049513,
|
||||||
|
"name": "Hpt_ChaffLauncher_Tiny",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 7650
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TinyHardpoint2": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128668536,
|
||||||
|
"name": "Hpt_ShieldBooster_Size0_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 252900
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TinyHardpoint3": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128668536,
|
||||||
|
"name": "Hpt_ShieldBooster_Size0_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 252900
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TinyHardpoint4": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128668536,
|
||||||
|
"name": "Hpt_ShieldBooster_Size0_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 281000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TinyHardpoint5": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128668536,
|
||||||
|
"name": "Hpt_ShieldBooster_Size0_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 281000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TinyHardpoint6": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128668536,
|
||||||
|
"name": "Hpt_ShieldBooster_Size0_Class5",
|
||||||
|
"on": true,
|
||||||
|
"priority": 0,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 281000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"WeaponColour": {
|
||||||
|
"module": {
|
||||||
|
"free": false,
|
||||||
|
"id": 128732194,
|
||||||
|
"name": "WeaponCustomisation_Purple",
|
||||||
|
"on": true,
|
||||||
|
"priority": 1,
|
||||||
|
"unloaned": 0,
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "BelugaLiner",
|
||||||
|
"value": {
|
||||||
|
"hull": 71688743,
|
||||||
|
"modules": 120812762,
|
||||||
|
"unloaned": 1869489
|
||||||
|
}
|
||||||
|
}
|
||||||
327
__tests__/fixtures/courier-test-detailed-export-v4.json
Normal file
327
__tests__/fixtures/courier-test-detailed-export-v4.json
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://cdn.coriolis.io/schemas/ship-loadout/4.json#",
|
||||||
|
"name": "Multi-purpose Imperial Courier",
|
||||||
|
"ship": "Imperial Courier",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Coriolis.io",
|
||||||
|
"url": "https://coriolis.edcd.io/outfit/imperial_courier?code=0patzF5l0das8f31a1a270202000e402t0101-2f.AwRj4zKA.CwRgDBldLiQ%3D.H4sIAAAAAAAAA12OP0tCYRjFj9fuVbvF1du9ekkT8s%2FkIg4NElyIBBd321yaGvwUQTS3N7UFfYygIT9EoyQUJA36ns47XJCWA%2B%2Fz%2Bz3Pe3ImBbDNKaqNPSBoGrL4ngfomKpFGiJ%2BLgHteR1IPjxJT5pF11uSeXNsJVcRfgdC92syWUuK0iMdKZqrjJ%2F0aoA71lJ5oKf38knWcCiptCPdhJIerdS00vlK0qktlqoj983UmqqHjQ33VsW8eazFmaTyULP2hQ4lX8LBme6g%2F6v0TTdbxJ2KhdEIaCw15MF%2FNB0L%2BS2hwEwyFM8KgP%2BqEpWWA3Qu9Z3z9kPWHzakt7Dt%2BAeD7ghSTgEAAA%3D%3D&bn=Multi-purpose%20Imperial%20Courier",
|
||||||
|
"code": "0patzF5l0das8f31a1a270202000e402t0101-2f.AwRj4zKA.CwRgDBldLiQ=.H4sIAAAAAAAAA12OP0tCYRjFj9fuVbvF1du9ekkT8s/kIg4NElyIBBd321yaGvwUQTS3N7UFfYygIT9EoyQUJA36ns47XJCWA+/z+z3Pe3ImBbDNKaqNPSBoGrL4ngfomKpFGiJ+LgHteR1IPjxJT5pF11uSeXNsJVcRfgdC92syWUuK0iMdKZqrjJ/0aoA71lJ5oKf38knWcCiptCPdhJIerdS00vlK0qktlqoj983UmqqHjQ33VsW8eazFmaTyULP2hQ4lX8LBme6g/6v0TTdbxJ2KhdEIaCw15MF/NB0L+S2hwEwyFM8KgP+qEpWWA3Qu9Z3z9kPWHzakt7Dt+AeD7ghSTgEAAA==",
|
||||||
|
"shipId": "imperial_courier"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"components": {
|
||||||
|
"standard": {
|
||||||
|
"bulkheads": "Lightweight Alloy",
|
||||||
|
"cargoHatch": {
|
||||||
|
"enabled": false,
|
||||||
|
"priority": 5
|
||||||
|
},
|
||||||
|
"powerPlant": {
|
||||||
|
"class": 4,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 2,
|
||||||
|
"modifications": {
|
||||||
|
"pgen": 1052,
|
||||||
|
"integrity": -482,
|
||||||
|
"eff": 974
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 63,
|
||||||
|
"name": "Overcharged",
|
||||||
|
"grade": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"thrusters": {
|
||||||
|
"class": 3,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"name": "Enhanced Performance",
|
||||||
|
"modifications": {
|
||||||
|
"optmul": 2476,
|
||||||
|
"thermload": 7023,
|
||||||
|
"power": 1763,
|
||||||
|
"integrity": 165,
|
||||||
|
"optmass": -667
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 22,
|
||||||
|
"name": "Dirty",
|
||||||
|
"grade": 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frameShiftDrive": {
|
||||||
|
"class": 3,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"modifications": {
|
||||||
|
"mass": 4082,
|
||||||
|
"integrity": -2422,
|
||||||
|
"power": 1782,
|
||||||
|
"optmass": 4927
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 26,
|
||||||
|
"name": "Increased range",
|
||||||
|
"grade": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lifeSupport": {
|
||||||
|
"class": 1,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1
|
||||||
|
},
|
||||||
|
"powerDistributor": {
|
||||||
|
"class": 3,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1
|
||||||
|
},
|
||||||
|
"sensors": {
|
||||||
|
"class": 2,
|
||||||
|
"rating": "D",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1
|
||||||
|
},
|
||||||
|
"fuelTank": {
|
||||||
|
"class": 3,
|
||||||
|
"rating": "C",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hardpoints": [
|
||||||
|
{
|
||||||
|
"class": 2,
|
||||||
|
"rating": "F",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Pulse Laser",
|
||||||
|
"mount": "Fixed",
|
||||||
|
"modifications": {
|
||||||
|
"rof": 5931,
|
||||||
|
"damage": -184,
|
||||||
|
"jitter": 50,
|
||||||
|
"distdraw": -4689,
|
||||||
|
"piercing": 3328
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 89,
|
||||||
|
"name": "Rapid fire",
|
||||||
|
"grade": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 2,
|
||||||
|
"rating": "F",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Pulse Laser",
|
||||||
|
"mount": "Fixed",
|
||||||
|
"modifications": {
|
||||||
|
"rof": 4715,
|
||||||
|
"damage": -97,
|
||||||
|
"jitter": 30,
|
||||||
|
"distdraw": -4548,
|
||||||
|
"piercing": 1057,
|
||||||
|
"integrity": 319
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 89,
|
||||||
|
"name": "Rapid fire",
|
||||||
|
"grade": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 2,
|
||||||
|
"rating": "F",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Multi-cannon",
|
||||||
|
"mount": "Gimballed",
|
||||||
|
"modifications": {
|
||||||
|
"damage": 2437,
|
||||||
|
"distdraw": 5487,
|
||||||
|
"rof": 1120,
|
||||||
|
"jitter": 58,
|
||||||
|
"thermload": 1346,
|
||||||
|
"power": 1009,
|
||||||
|
"integrity": -202,
|
||||||
|
"ammo": -2000
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 88,
|
||||||
|
"name": "Overcharged",
|
||||||
|
"grade": 3,
|
||||||
|
"special": {
|
||||||
|
"id": 3,
|
||||||
|
"name": "Corrosive shell"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"utility": [
|
||||||
|
{
|
||||||
|
"class": 0,
|
||||||
|
"rating": "I",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Heat Sink Launcher",
|
||||||
|
"name": "Heat Sink Launcher",
|
||||||
|
"modifications": {
|
||||||
|
"ammo": 5000,
|
||||||
|
"mass": 17684,
|
||||||
|
"reload": 9707
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 37,
|
||||||
|
"name": "Ammo capacity",
|
||||||
|
"grade": 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 0,
|
||||||
|
"rating": "I",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Heat Sink Launcher",
|
||||||
|
"name": "Heat Sink Launcher",
|
||||||
|
"modifications": {
|
||||||
|
"ammo": 5000,
|
||||||
|
"mass": 18520,
|
||||||
|
"reload": 8715
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 37,
|
||||||
|
"name": "Ammo capacity",
|
||||||
|
"grade": 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 0,
|
||||||
|
"rating": "I",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Chaff Launcher",
|
||||||
|
"name": "Chaff Launcher"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 0,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Frame Shift Wake Scanner"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"internal": [
|
||||||
|
{
|
||||||
|
"class": 3,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Shield Generator",
|
||||||
|
"modifications": {
|
||||||
|
"optmul": 1888,
|
||||||
|
"explres": 455,
|
||||||
|
"kinres": 546,
|
||||||
|
"thermres": 1092,
|
||||||
|
"brokenregen": -2614,
|
||||||
|
"regen": -876,
|
||||||
|
"distdraw": 463
|
||||||
|
},
|
||||||
|
"blueprint": {
|
||||||
|
"id": 77,
|
||||||
|
"name": "Reinforced",
|
||||||
|
"grade": 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 3,
|
||||||
|
"rating": "A",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 1,
|
||||||
|
"group": "Fuel Scoop"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 2,
|
||||||
|
"rating": "E",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 2,
|
||||||
|
"group": "Cargo Rack"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class": 2,
|
||||||
|
"rating": "E",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 2,
|
||||||
|
"group": "Cargo Rack"
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
"class": 1,
|
||||||
|
"rating": "C",
|
||||||
|
"enabled": true,
|
||||||
|
"priority": 2,
|
||||||
|
"group": "Scanner",
|
||||||
|
"name": "Advanced Discovery Scanner"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"class": 1,
|
||||||
|
"hullCost": 2481550,
|
||||||
|
"speed": 280,
|
||||||
|
"boost": 380,
|
||||||
|
"boostEnergy": 10,
|
||||||
|
"agility": 6,
|
||||||
|
"baseShieldStrength": 200,
|
||||||
|
"baseArmour": 80,
|
||||||
|
"hullMass": 35,
|
||||||
|
"masslock": 7,
|
||||||
|
"pipSpeed": 0.05,
|
||||||
|
"moduleCostMultiplier": 1,
|
||||||
|
"fuelCapacity": 8,
|
||||||
|
"cargoCapacity": 8,
|
||||||
|
"ladenMass": 104.25,
|
||||||
|
"armour": 144,
|
||||||
|
"shield": 404.19,
|
||||||
|
"shieldCells": 0,
|
||||||
|
"totalCost": 14059860,
|
||||||
|
"unladenMass": 88.25,
|
||||||
|
"totalDpe": 32.25,
|
||||||
|
"totalExplDpe": 0,
|
||||||
|
"totalKinDpe": 9.41,
|
||||||
|
"totalThermDpe": 22.84,
|
||||||
|
"totalDps": 53.8,
|
||||||
|
"totalExplDps": 0,
|
||||||
|
"totalKinDps": 17.44,
|
||||||
|
"totalThermDps": 36.35,
|
||||||
|
"totalSDps": 48.99,
|
||||||
|
"totalExplSDps": 0,
|
||||||
|
"totalKinSDps": 12.64,
|
||||||
|
"totalThermSDps": 36.35,
|
||||||
|
"totalEps": 9.84,
|
||||||
|
"totalHps": 12.28,
|
||||||
|
"shieldExplRes": 0.48,
|
||||||
|
"shieldKinRes": 0.55,
|
||||||
|
"shieldThermRes": 1.09,
|
||||||
|
"hullExplRes": 1.4,
|
||||||
|
"hullKinRes": 1.2,
|
||||||
|
"hullThermRes": 1,
|
||||||
|
"powerAvailable": 17.24,
|
||||||
|
"powerRetracted": 11.3,
|
||||||
|
"powerDeployed": 16.41,
|
||||||
|
"unladenRange": 25.57,
|
||||||
|
"fullTankRange": 23.92,
|
||||||
|
"ladenRange": 22.09,
|
||||||
|
"unladenFastestRange": 116.23,
|
||||||
|
"ladenFastestRange": 107,
|
||||||
|
"maxJumpCount": 5,
|
||||||
|
"topSpeed": 386.56,
|
||||||
|
"topBoost": 524.62
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"type_6_transporter": {
|
"type_6_transporter": {
|
||||||
"Cargo": "0p0tdFal8d8s8f4-----04040303430101.Iw1-kA==.Aw1-kA==.",
|
"Cargo": "0p0tdFal8d8s8f4-----04040303430101.Iw1/kA==.Aw1/kA==.",
|
||||||
"Miner": "0p5tdFal8d8s8f42l2l---040403451q0101.Iw1-kA==.Aw1-kA==.",
|
"Miner": "0p5tdFal8d8s8f42l2l---040403451q0101.Iw1/kA==.Aw1/kA==.",
|
||||||
"Hopper": "0p0tdFal8d0s8f41717---030302024300-.Iw1-kA==.Aw1-kA==."
|
"Hopper": "0p0tdFal8d0s8f41717---030302024300-.Iw1/kA==.Aw1/kA==."
|
||||||
},
|
},
|
||||||
"type_7_transport": {
|
"type_7_transport": {
|
||||||
"Cargo": "0p0tiFfliddsdf5--------0505040403480101.Iw18aQ==.Aw18aQ==.",
|
"Cargo": "0p0tiFfliddsdf5--------0505040403480101.Iw18aQ==.Aw18aQ==.",
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"Test": "4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.Iw18ZlA=.Aw18ZlA=."
|
"Test": "4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.Iw18ZlA=.Aw18ZlA=."
|
||||||
},
|
},
|
||||||
"diamondback_explorer": {
|
"diamondback_explorer": {
|
||||||
"Explorer": "0p0tdFfldddsdf5---0202--320p432i2f.Iw1-kA==.Aw1-kA==."
|
"Explorer": "0p0tdFfldddsdf5---0202--320p432i2f.Iw1/kA==.Aw1/kA==."
|
||||||
},
|
},
|
||||||
"vulture": {
|
"vulture": {
|
||||||
"Bounty Hunter": "3patcFalddksff31e1e0404-0l4a5d27662j.Iw19kA==.Aw19kA==."
|
"Bounty Hunter": "3patcFalddksff31e1e0404-0l4a5d27662j.Iw19kA==.Aw19kA==."
|
||||||
@@ -45,6 +45,6 @@
|
|||||||
"Attack": "2pfthFalidpsff31r0s0s0s0s000404-04-4a-5d27-.Iw18aQ==.Aw18aQ==."
|
"Attack": "2pfthFalidpsff31r0s0s0s0s000404-04-4a-5d27-.Iw18aQ==.Aw18aQ==."
|
||||||
},
|
},
|
||||||
"eagle": {
|
"eagle": {
|
||||||
"Figther": "4p0t5F5l3d5s5f20p0p24-40532j-.Iw1-EA==.Aw1-EA==."
|
"Figther": "4p0t5F5l3d5s5f20p0p24-40532j-.Iw1/EA==.Aw1/EA==."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ describe('Import Modal', function() {
|
|||||||
expect(modal.state.singleBuild).toBe(true);
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
clickProceed();
|
clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/anaconda/4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA==.CwBhCYzBGW9qCTSqs5xA.?bn=Test%20My%20Ship');
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/anaconda?code=4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA%3D%3D.CwBhCYzBGW9qCTSqs5xA.&bn=Test%20My%20Ship');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('catches an invalid build', function() {
|
it('catches an invalid build', function() {
|
||||||
@@ -167,7 +167,36 @@ describe('Import Modal', function() {
|
|||||||
expect(modal.state.singleBuild).toBe(true);
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
clickProceed();
|
clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/anaconda/4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA==.CwBhCYzBGW9qCTSqs5xA.H4sIAAAAAAAAA2MUe8HMwPD-PwDDhxeuCAAAAA==?bn=Test%20My%20Ship');
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/anaconda?code=4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA%3D%3D.CwBhCYzBGW9qCTSqs5xA.H4sIAAAAAAAAA2P8xwAEf0GE2AtmBob%2F%2FwFvM%2BjKEgAAAA%3D%3D&bn=Test%20My%20Ship');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Import Detailed Engineered V4 Build', function() {
|
||||||
|
|
||||||
|
beforeEach(reset);
|
||||||
|
|
||||||
|
it('imports a valid v4 build', function() {
|
||||||
|
const importData = require('./fixtures/asp-test-detailed-export-v4');
|
||||||
|
pasteText(JSON.stringify(importData));
|
||||||
|
|
||||||
|
expect(modal.state.importValid).toBeTruthy();
|
||||||
|
expect(modal.state.errorMsg).toEqual(null);
|
||||||
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
|
clickProceed();
|
||||||
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/asp?code=0pftiFflfddsnf5------020202033c044002v62f2i.AwRj4yvI.CwRgDBldHnJA.H4sIAAAAAAAAA2P858DAwPCXEUhwHPvx%2F78YG5AltB7I%2F8%2F0TwImJboDSPJ%2F%2B%2Ff%2Fv%2FKlX%2F%2F%2Fi3AwMTBIfARK%2FGf%2BJwVSxArStVAYqOjvz%2F%2F%2FJVo5GRhE2IBc4SKQSSz%2FDGEmCa398P8%2F%2F2%2BgTf%2F%2FAwDFxwtofAAAAA%3D%3D&bn=Multi-purpose%20Asp%20Explorer');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('imports a valid v4 build with modifications', function() {
|
||||||
|
const importData = require('./fixtures/courier-test-detailed-export-v4');
|
||||||
|
pasteText(JSON.stringify(importData));
|
||||||
|
|
||||||
|
expect(modal.state.importValid).toBeTruthy();
|
||||||
|
expect(modal.state.errorMsg).toEqual(null);
|
||||||
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
|
clickProceed();
|
||||||
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/imperial_courier?code=0patzF5l0das8f31a1a270202000e402t0101-2f.AwRj4zKA.CwRgDBldLiQ%3D.H4sIAAAAAAAAA12OP0tCYRjFj9fuVbvF1du9ekkT8s%2FkIg4NElyIBBd321yaGvwUQTS3N7UFfYygIT9EoyQUJA36ns47XJCWA%2B%2Fz%2Bz3Pe3ImBbDNKaqNPSBoGrL4ngfomKpFGiJ%2BLgHteR1IPjxJT5pF11uSeXNsJVcRfgdC92syWUuK0iMdKZqrjJ%2F0aoA71lJ5oKf38knWcCiptCPdhJIerdS00vlK0qktlqoj983UmqqHjQ33VsW8eazFmaTyULP2hQ4lX8LBme6g%2F6v0TTdbxJ2KhdEIaCw15MF%2FNB0L%2BS2hwEwyFM8KgP%2BqEpWWA3Qu9Z3z9kPWHzakt7Dt%2BAeD7ghSTgEAAA%3D%3D&bn=Multi-purpose%20Imperial%20Courier');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -209,26 +238,38 @@ describe('Import Modal', function() {
|
|||||||
expect(modal.state.singleBuild).toBe(true);
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
clickProceed();
|
clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/federal_corvette/2putsFklndzsxf50x0x7l28281919040404040402020l06p05sf63c5ifhv66g2f.AwRj4zNaKA==.CwRgDBldUExuBiQqA===.H4sIAAAAAAAAAx2Rzy4DURTGz7TuzHRu47ZjWreKlg5iQ9KFZ9CENyBWtWo8gIUFsamteAIJi0qEWIhdN11ZEN1IwyNYVKRpcXzH5su553f_XyfvKiLTYma-TkScyHVcokoYEdmbBNDsiDla-WUOT5LgyfAshHdvyGyjFFHUQCSrBU8TLT4gYq4DNL_LhNTFN3PwiqdZQyX2C-sekep-Mrs1RIbnDppsIogD1UAtN7JEM9eIzZg8hmhsEU32gFmrdgB_UARvjYEr4QMUMffoxGnV-M8X3hZ_lAO-gmWq2Eq2IVtDOzZ2Hbbuws6KxCKmKUUydgRb3woSiUXMs6Cs7Qt6FCQSi5hxkNKhj6qhfcPU_kU4wYrFMseSOmFXMKbuwZsViUWMlq1sbhvJ_lKyfqTqEJGJyoC5eIpU9x2TRnUswYXyF77BW4Z3qQuv05GDTpfvcDzvSbxJ5DtV_aHS1I4clyB2A5_b-pAL8x_enn626gEAAA==?bn=Imported%20Federal%20Corvette');
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/federal_corvette?code=2putsFklndzsxf50x0x7l28281919040404040402020l06p05sf63c5ifrv66g2f.AwRj4zNaKA%3D%3D.CwRgDBldUExuBiQqA%3D%3D%3D.H4sIAAAAAAAAA02Svy9DURTHT1vvtfoat30eXlvV0ufXQmLAIDHSRDcJAzHV1PgDDAaJpVbxF0gYKhFiEFuXTgbCIsKfYJCItHWP75E83vLNue%2F7Od977zs3pBeJ6DsE6TcNIlVn5lgFSw7rfrEikL6mSVS0HSL3MgxoqM3sTGtm%2BxA2R3RGSLSTfWzD32kxu043kVNFDxt6wU8ajVpEY7coh5uARrYR0n3aYY4%2FY6lmkc4xveafqZOHpHejRMb9J7NZQqN9Ascto4fjet0P7iQgRhV7mo5LlLtAUnIe34rVDaKBF9AThUJhla3%2FHqMRB76XBV7v8vEvOOoGx%2BJEgKz9BgvZEHJOyHNUakYujUuSW8KxWOkl%2F%2BzuMsR6QpkS8URUTYKTAagNta4EEvFE1INAqQD0IdCdQCKeiOoBk9%2BPYU87QL7i2tajkITKk0odSFxvAJrClawX%2BCkRT0RZYNjV5b%2BRbyLaOpMkafJa%2BBgufjFnjxBnvgFxKvgBnNYlP7jwiXcRnYQ%2F%2FoRlqCnTHAz41xha9F78CNahGXk8eZ3z%2FcyWjJcg7goeU%2BJdZsw%2FFW2pAaMCAAA%3D&bn=Imported%20Federal%20Corvette');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('imports a valid v4 build', function() {
|
||||||
|
const importData = require('./fixtures/companion-api-import-2');
|
||||||
|
pasteText(JSON.stringify(importData));
|
||||||
|
|
||||||
|
expect(modal.state.importValid).toBeTruthy();
|
||||||
|
expect(modal.state.errorMsg).toEqual(null);
|
||||||
|
expect(modal.state.singleBuild).toBe(true);
|
||||||
|
clickProceed();
|
||||||
|
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
|
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/beluga?code=0pktsFplCdpsnf70t0t2727270004040404043c4fmimlmm04mc0iv62i2f.AwRj4yukg%3D%3D%3D.CwRgDBldHi8IUA%3D%3D.H4sIAAAAAAAAA2P8Z8%2FAwPCXEUiIKTMxMPCv%2F%2Ff%2FP8cFIPGf6Z8YTEr0GjMDg%2FJWICERBOTzn%2Fn7%2F7%2FIO5Ai5n9SIEWsQEIoSxAolfbt%2F3%2BJPk4GBhE7YQYGYVmgcuVnf4Aq%2FwMAIrEcGGsAAAA%3D&bn=Imported%20Beluga%20Liner');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Import E:D Shipyard Builds', function() {
|
describe('Import E:D Shipyard Builds', function() {
|
||||||
|
|
||||||
it('imports a valid builds', function() {
|
// it('imports a valid build', function() {
|
||||||
const imports = require('./fixtures/ed-shipyard-import-valid');
|
// const imports = require('./fixtures/ed-shipyard-import-valid');
|
||||||
|
//
|
||||||
for (let i = 0; i < imports.length; i++ ) {
|
// for (let i = 0; i < imports.length; i++ ) {
|
||||||
reset();
|
// reset();
|
||||||
let fixture = imports[i];
|
// let fixture = imports[i];
|
||||||
pasteText(fixture.buildText);
|
// pasteText(fixture.buildText);
|
||||||
expect(modal.state.importValid).toBeTruthy();
|
// expect(modal.state.importValid).toBeTruthy();
|
||||||
expect(modal.state.errorMsg).toEqual(null);
|
// expect(modal.state.errorMsg).toEqual(null);
|
||||||
clickProceed();
|
// clickProceed();
|
||||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
// expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/' + fixture.shipId + '/' + fixture.buildCode + '?bn=' + encodeURIComponent(fixture.buildName));
|
// expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/' + fixture.shipId + '?code=' + encodeURIComponent(fixture.buildCode) + '&bn=' + encodeURIComponent(fixture.buildName));
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('catches invalid builds', function() {
|
it('catches invalid builds', function() {
|
||||||
const imports = require('./fixtures/ed-shipyard-import-invalid');
|
const imports = require('./fixtures/ed-shipyard-import-invalid');
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "coriolis_shipyard",
|
"name": "coriolis_shipyard",
|
||||||
"version": "2.2.2",
|
"version": "2.2.4",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EDCD/coriolis"
|
"url": "https://github.com/EDCD/coriolis"
|
||||||
|
|||||||
@@ -44,16 +44,25 @@ export default class HardpointSlot extends Slot {
|
|||||||
let validMods = Modifications.validity[m.grp] || [];
|
let validMods = Modifications.validity[m.grp] || [];
|
||||||
let showModuleResistances = Persist.showModuleResistances();
|
let showModuleResistances = Persist.showModuleResistances();
|
||||||
|
|
||||||
|
// Modifications tooltip shows blueprint and grade, if available
|
||||||
|
let modTT = translate('modified');
|
||||||
|
if (m && m.blueprint) {
|
||||||
|
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
||||||
|
if (m.blueprint.special && m.blueprint.special.id) {
|
||||||
|
modTT += ', ' + translate(m.blueprint.special.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>
|
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
<div className={'l'}>
|
<div className={'l'}>
|
||||||
{m.mount && m.mount == 'F' ? <span onMouseOver={termtip.bind(null, 'fixed')} onMouseOut={tooltip.bind(null, null)}><MountFixed /></span> : ''}
|
{m.mount && m.mount == 'F' ? <span onMouseOver={termtip.bind(null, 'fixed')} onMouseOut={tooltip.bind(null, null)}><MountFixed /></span> : ''}
|
||||||
{m.mount && m.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : ''}
|
{m.mount && m.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : ''}
|
||||||
{m.mount && m.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : ''}
|
{m.mount && m.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : ''}
|
||||||
{m.type && m.type.match('K') ? <span onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /></span> : ''}
|
{m.getDamageType() && m.getDamageType().match('K') ? <span onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /></span> : ''}
|
||||||
{m.type && m.type.match('T') ? <span onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /></span> : ''}
|
{m.getDamageType() && m.getDamageType().match('T') ? <span onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /></span> : ''}
|
||||||
{m.type && m.type.match('E') ? <span onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /></span> : ''}
|
{m.getDamageType() && m.getDamageType().match('E') ? <span onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /></span> : ''}
|
||||||
{classRating} {translate(m.name || m.grp)}{ m.mods && Object.keys(m.mods).length > 0 ? <span className='r' onMouseOver={termtip.bind(null, 'modified')} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : null }
|
{classRating} {translate(m.name || m.grp)}{ m.mods && Object.keys(m.mods).length > 0 ? <span className='r' onMouseOver={termtip.bind(null, modTT)} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : null }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={'r'}>{formats.round(m.getMass())}{u.T}</div>
|
<div className={'r'}>{formats.round(m.getMass())}{u.T}</div>
|
||||||
|
|||||||
@@ -26,10 +26,16 @@ export default class InternalSlot extends Slot {
|
|||||||
let validMods = Modifications.validity[m.grp] || [];
|
let validMods = Modifications.validity[m.grp] || [];
|
||||||
let showModuleResistances = Persist.showModuleResistances();
|
let showModuleResistances = Persist.showModuleResistances();
|
||||||
|
|
||||||
|
// Modifications tooltip shows blueprint and grade, if available
|
||||||
|
let modTT = translate('modified');
|
||||||
|
if (m && m.blueprint) {
|
||||||
|
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
||||||
|
}
|
||||||
|
|
||||||
let mass = m.getMass() || m.cargo || m.fuel || 0;
|
let mass = m.getMass() || m.cargo || m.fuel || 0;
|
||||||
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>
|
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
<div className={'l'}>{classRating} {translate(m.name || m.grp)}{m.mods && Object.keys(m.mods).length > 0 ? <span onMouseOver={termtip.bind(null, 'modified')} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : ''}</div>
|
<div className={'l'}>{classRating} {translate(m.name || m.grp)}{m.mods && Object.keys(m.mods).length > 0 ? <span onMouseOver={termtip.bind(null, modTT)} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : ''}</div>
|
||||||
<div className={'r'}>{formats.round(mass)}{u.T}</div>
|
<div className={'r'}>{formats.round(mass)}{u.T}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ export default class StandardSlot extends TranslatedComponent {
|
|||||||
let showModuleResistances = Persist.showModuleResistances();
|
let showModuleResistances = Persist.showModuleResistances();
|
||||||
let mass = m.getMass() || m.cargo || m.fuel || 0;
|
let mass = m.getMass() || m.cargo || m.fuel || 0;
|
||||||
|
|
||||||
|
// Modifications tooltip shows blueprint and grade, if available
|
||||||
|
let modTT = translate('modified');
|
||||||
|
if (m && m.blueprint) {
|
||||||
|
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
||||||
|
}
|
||||||
|
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
// If not selected then sure that modifications flag is unset
|
// If not selected then sure that modifications flag is unset
|
||||||
this._modificationsSelected = false;
|
this._modificationsSelected = false;
|
||||||
@@ -81,7 +87,7 @@ export default class StandardSlot extends TranslatedComponent {
|
|||||||
<div className={cn('details-container', { warning: warning && warning(slot.m) })}>
|
<div className={cn('details-container', { warning: warning && warning(slot.m) })}>
|
||||||
<div className={'sz'}>{slot.maxClass}</div>
|
<div className={'sz'}>{slot.maxClass}</div>
|
||||||
<div>
|
<div>
|
||||||
<div className={'l'}>{classRating} {translate(m.name || m.grp)}{m.mods && Object.keys(m.mods).length > 0 ? <span className='r' onMouseOver={termtip.bind(null, 'modified')} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : null }</div>
|
<div className={'l'}>{classRating} {translate(m.name || m.grp)}{m.mods && Object.keys(m.mods).length > 0 ? <span className='r' onMouseOver={termtip.bind(null, modTT)} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : null }</div>
|
||||||
<div className={'r'}>{formats.round(mass)}{units.T}</div>
|
<div className={'r'}>{formats.round(mass)}{units.T}</div>
|
||||||
<div/>
|
<div/>
|
||||||
<div className={'cb'}>
|
<div className={'cb'}>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import Persist from '../stores/Persist';
|
|||||||
import Ship from '../shipyard/Ship';
|
import Ship from '../shipyard/Ship';
|
||||||
import { toDetailedBuild } from '../shipyard/Serializer';
|
import { toDetailedBuild } from '../shipyard/Serializer';
|
||||||
import { outfitURL } from '../utils/UrlGenerators';
|
import { outfitURL } from '../utils/UrlGenerators';
|
||||||
import { FloppyDisk, Bin, Switch, Download, Reload, Fuel } from '../components/SvgIcons';
|
import { FloppyDisk, Bin, Switch, Download, Reload, Fuel, LinkIcon } from '../components/SvgIcons';
|
||||||
import ShipSummaryTable from '../components/ShipSummaryTable';
|
import ShipSummaryTable from '../components/ShipSummaryTable';
|
||||||
import StandardSlotSection from '../components/StandardSlotSection';
|
import StandardSlotSection from '../components/StandardSlotSection';
|
||||||
import HardpointsSlotSection from '../components/HardpointsSlotSection';
|
import HardpointsSlotSection from '../components/HardpointsSlotSection';
|
||||||
@@ -20,6 +20,7 @@ import LineChart from '../components/LineChart';
|
|||||||
import PowerManagement from '../components/PowerManagement';
|
import PowerManagement from '../components/PowerManagement';
|
||||||
import CostSection from '../components/CostSection';
|
import CostSection from '../components/CostSection';
|
||||||
import ModalExport from '../components/ModalExport';
|
import ModalExport from '../components/ModalExport';
|
||||||
|
import ModalPermalink from '../components/ModalPermalink';
|
||||||
import Slider from '../components/Slider';
|
import Slider from '../components/Slider';
|
||||||
|
|
||||||
const SPEED_SERIES = ['boost', '4 Pips', '2 Pips', '0 Pips'];
|
const SPEED_SERIES = ['boost', '4 Pips', '2 Pips', '0 Pips'];
|
||||||
@@ -270,6 +271,13 @@ export default class OutfittingPage extends Page {
|
|||||||
this.resizeListener.remove();
|
this.resizeListener.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the short URL
|
||||||
|
*/
|
||||||
|
_genShortlink() {
|
||||||
|
this.context.showModal(<ModalPermalink url={window.location.href}/>);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the Page
|
* Render the Page
|
||||||
* @return {React.Component} The page contents
|
* @return {React.Component} The page contents
|
||||||
@@ -289,8 +297,6 @@ export default class OutfittingPage extends Page {
|
|||||||
sStr = ship.getStandardString() + '.' + ship.getModificationsString(),
|
sStr = ship.getStandardString() + '.' + ship.getModificationsString(),
|
||||||
iStr = ship.getInternalString() + '.' + ship.getModificationsString();
|
iStr = ship.getInternalString() + '.' + ship.getModificationsString();
|
||||||
|
|
||||||
Router.replace(outfitURL(ship.id, code, buildName));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id='outfit' className={'page'} style={{ fontSize: (sizeRatio * 0.9) + 'em' }}>
|
<div id='outfit' className={'page'} style={{ fontSize: (sizeRatio * 0.9) + 'em' }}>
|
||||||
<div id='overview'>
|
<div id='overview'>
|
||||||
@@ -315,6 +321,9 @@ export default class OutfittingPage extends Page {
|
|||||||
<button onClick={buildName && this._exportBuild} disabled={!buildName} onMouseOver={termtip.bind(null, 'export')} onMouseOut={hide}>
|
<button onClick={buildName && this._exportBuild} disabled={!buildName} onMouseOver={termtip.bind(null, 'export')} onMouseOut={hide}>
|
||||||
<Download className='lg'/>
|
<Download className='lg'/>
|
||||||
</button>
|
</button>
|
||||||
|
<button onClick={this._genShortlink} onMouseOver={termtip.bind(null, 'shortlink')} onMouseOut={hide}>
|
||||||
|
<LinkIcon className='lg' />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export default class Module {
|
|||||||
/**
|
/**
|
||||||
* Get a value for a given modification
|
* Get a value for a given modification
|
||||||
* @param {Number} name The name of the modification
|
* @param {Number} name The name of the modification
|
||||||
* @return {Number} The value of the modification, as an integer value scaled so that 1.23% == 123
|
* @return {object} The value of the modification. If it is a numeric value then it is returned as an integer value scaled so that 1.23% == 123
|
||||||
*/
|
*/
|
||||||
getModValue(name) {
|
getModValue(name) {
|
||||||
return this.mods && this.mods[name] ? this.mods[name] : null;
|
return this.mods && this.mods[name] ? this.mods[name] : null;
|
||||||
@@ -37,7 +37,7 @@ export default class Module {
|
|||||||
/**
|
/**
|
||||||
* Set a value for a given modification ID
|
* Set a value for a given modification ID
|
||||||
* @param {Number} name The name of the modification
|
* @param {Number} name The name of the modification
|
||||||
* @param {Number} value The value of the modification, as an integer scaled so that -2.34% == -234
|
* @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
|
||||||
*/
|
*/
|
||||||
setModValue(name, value) {
|
setModValue(name, value) {
|
||||||
if (!this.mods) {
|
if (!this.mods) {
|
||||||
@@ -46,11 +46,15 @@ export default class Module {
|
|||||||
|
|
||||||
if (value == null || value == 0) {
|
if (value == null || value == 0) {
|
||||||
delete this.mods[name];
|
delete this.mods[name];
|
||||||
|
} else {
|
||||||
|
if (isNaN(value)) {
|
||||||
|
this.mods[name] = value;
|
||||||
} else {
|
} else {
|
||||||
// Round just to be sure
|
// Round just to be sure
|
||||||
this.mods[name] = Math.round(value);
|
this.mods[name] = Math.round(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to obtain a modified value using standard multipliers
|
* Helper to obtain a modified value using standard multipliers
|
||||||
@@ -533,7 +537,6 @@ export default class Module {
|
|||||||
return this._getModifiedValue('cells');
|
return this._getModifiedValue('cells');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the jitter for this module, taking in to account modifications
|
* Get the jitter for this module, taking in to account modifications
|
||||||
* @return {Number} the jitter for this module
|
* @return {Number} the jitter for this module
|
||||||
@@ -541,4 +544,12 @@ export default class Module {
|
|||||||
getJitter() {
|
getJitter() {
|
||||||
return this._getModifiedValue('jitter', true);
|
return this._getModifiedValue('jitter', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the damage type for this module, taking in to account modifications
|
||||||
|
* @return {string} the damage types for this module; any combination of E T and K
|
||||||
|
*/
|
||||||
|
getDamageType() {
|
||||||
|
return this.getModValue('type') || this.type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,59 @@ export function internal(id) {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a standard module based on Class, Rating, Group and/or name.
|
||||||
|
* At least one of Group name or unique module name must be provided
|
||||||
|
*
|
||||||
|
* @param {String} groupName [Optional] Full name or abbreviated name for module group
|
||||||
|
* @param {integer} clss module Class
|
||||||
|
* @param {String} rating module Rating
|
||||||
|
* @param {String} name [Optional] Long/unique name for module -e.g. 'Advanced Discover Scanner'
|
||||||
|
* @return {Object} The module if found, null if not found
|
||||||
|
*/
|
||||||
|
export function findStandard(groupName, clss, rating, name) {
|
||||||
|
let groups = {};
|
||||||
|
|
||||||
|
if (groupName) {
|
||||||
|
if (Modules.standard[groupName]) {
|
||||||
|
groups[groupName] = Modules.standard[groupName];
|
||||||
|
} else {
|
||||||
|
let grpCode = ModuleNameToGroup[groupName.toLowerCase()];
|
||||||
|
if (grpCode && Modules.standard[grpCode]) {
|
||||||
|
groups[grpCode] = Modules.standard[grpCode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (name) {
|
||||||
|
groups = Modules.standard;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let g in groups) {
|
||||||
|
let group = groups[g];
|
||||||
|
for (let i = 0, l = group.length; i < l; i++) {
|
||||||
|
if (group[i].class == clss && group[i].rating == rating && ((!name && !group[i].name) || group[i].name == name)) {
|
||||||
|
return group[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a standard Module ID based on Class, Rating, Group and/or name.
|
||||||
|
* At least one of Group name or unique module name must be provided
|
||||||
|
*
|
||||||
|
* @param {String} groupName [Optional] Full name or abbreviated name for module group
|
||||||
|
* @param {integer} clss module Class
|
||||||
|
* @param {String} rating Module Rating
|
||||||
|
* @param {String} name [Optional] Long/unique name for module -e.g. 'Advanced Discover Scanner'
|
||||||
|
* @return {String} The id of the module if found, null if not found
|
||||||
|
*/
|
||||||
|
export function findStandardId(groupName, clss, rating, name) {
|
||||||
|
let i = this.findStandard(groupName, clss, rating, name);
|
||||||
|
return i ? i.id : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds an internal module based on Class, Rating, Group and/or name.
|
* Finds an internal module based on Class, Rating, Group and/or name.
|
||||||
* At least one ofGroup name or unique module name must be provided
|
* At least one ofGroup name or unique module name must be provided
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import { outfitURL } from '../utils/UrlGenerators';
|
|||||||
|
|
||||||
const STANDARD = ['powerPlant', 'thrusters', 'frameShiftDrive', 'lifeSupport', 'powerDistributor', 'sensors', 'fuelTank'];
|
const STANDARD = ['powerPlant', 'thrusters', 'frameShiftDrive', 'lifeSupport', 'powerDistributor', 'sensors', 'fuelTank'];
|
||||||
|
|
||||||
|
const STANDARD_GROUPS = {'powerPlant': 'pp', 'thrusters': 't', 'frameShiftDrive': 'fsd', 'lifeSupport': 'ls', 'powerDistributor': 'pd', 'sensors': 's', 'fuelTank': 'ft'};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates ship-loadout JSON Schema standard object
|
* Generates ship-loadout JSON Schema standard object
|
||||||
* @param {Object} standard model
|
* @param {Object} standard model
|
||||||
@@ -30,6 +32,10 @@ function standardToSchema(standard) {
|
|||||||
o.modifications = standard.m.mods;
|
o.modifications = standard.m.mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (standard.m.blueprint && Object.keys(standard.m.blueprint).length > 0) {
|
||||||
|
o.blueprint = standard.m.blueprint;
|
||||||
|
}
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -62,6 +68,10 @@ function slotToSchema(slot) {
|
|||||||
if (slot.m.mods && Object.keys(slot.m.mods).length > 0) {
|
if (slot.m.mods && Object.keys(slot.m.mods).length > 0) {
|
||||||
o.modifications = slot.m.mods;
|
o.modifications = slot.m.mods;
|
||||||
}
|
}
|
||||||
|
if (slot.m.blueprint && Object.keys(slot.m.blueprint).length > 0) {
|
||||||
|
o.blueprint = slot.m.blueprint;
|
||||||
|
}
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -137,6 +147,7 @@ export function fromDetailedBuild(detailedBuild) {
|
|||||||
let ship = new Ship(shipId, shipData.properties, shipData.slots);
|
let ship = new Ship(shipId, shipData.properties, shipData.slots);
|
||||||
let bulkheads = ModuleUtils.bulkheadIndex(stn.bulkheads);
|
let bulkheads = ModuleUtils.bulkheadIndex(stn.bulkheads);
|
||||||
let modifications = new Array(stn.bulkheads.modifications);
|
let modifications = new Array(stn.bulkheads.modifications);
|
||||||
|
let blueprints = new Array(stn.bulkheads.blueprint);
|
||||||
|
|
||||||
if (bulkheads < 0) {
|
if (bulkheads < 0) {
|
||||||
throw 'Invalid bulkheads: ' + stn.bulkheads;
|
throw 'Invalid bulkheads: ' + stn.bulkheads;
|
||||||
@@ -149,13 +160,13 @@ export function fromDetailedBuild(detailedBuild) {
|
|||||||
priorities.push(stn[c].priority === undefined ? 0 : stn[c].priority - 1);
|
priorities.push(stn[c].priority === undefined ? 0 : stn[c].priority - 1);
|
||||||
enabled.push(stn[c].enabled === undefined ? true : stn[c].enabled);
|
enabled.push(stn[c].enabled === undefined ? true : stn[c].enabled);
|
||||||
modifications.push(stn[c].modifications);
|
modifications.push(stn[c].modifications);
|
||||||
return stn[c].class + stn[c].rating;
|
blueprints.push(stn[c].blueprint);
|
||||||
|
return ModuleUtils.findStandardId(STANDARD_GROUPS[c], stn[c].class, stn[c].rating, stn[c].name);
|
||||||
});
|
});
|
||||||
|
|
||||||
let internal = comps.internal.map(c => c ? ModuleUtils.findInternalId(c.group, c.class, c.rating, c.name) : 0);
|
let internal = comps.internal.map(c => c ? ModuleUtils.findInternalId(c.group, c.class, c.rating, c.name) : 0);
|
||||||
|
|
||||||
let hardpoints = comps.hardpoints
|
let hardpoints = comps.hardpoints.map(c => c ? ModuleUtils.findHardpointId(c.group, c.class, c.rating, c.name, MountMap[c.mount], c.missile) : 0)
|
||||||
.map(c => c ? ModuleUtils.findHardpointId(c.group, c.class, c.rating, c.name, MountMap[c.mount], c.missile) : 0)
|
|
||||||
.concat(comps.utility.map(c => c ? ModuleUtils.findHardpointId(c.group, c.class, c.rating, c.name, MountMap[c.mount]) : 0));
|
.concat(comps.utility.map(c => c ? ModuleUtils.findHardpointId(c.group, c.class, c.rating, c.name, MountMap[c.mount]) : 0));
|
||||||
|
|
||||||
// The ordering of these arrays must match the order in which they are read in Ship.buildWith
|
// The ordering of these arrays must match the order in which they are read in Ship.buildWith
|
||||||
@@ -170,12 +181,17 @@ export function fromDetailedBuild(detailedBuild) {
|
|||||||
comps.internal.map(c => (!c || c.enabled === undefined) ? true : c.enabled * 1)
|
comps.internal.map(c => (!c || c.enabled === undefined) ? true : c.enabled * 1)
|
||||||
);
|
);
|
||||||
modifications = modifications.concat(
|
modifications = modifications.concat(
|
||||||
comps.hardpoints.map(c => (c && c.m ? c.m.modifications : null)),
|
comps.hardpoints.map(c => (c ? c.modifications : null)),
|
||||||
comps.utility.map(c => (c && c.m ? c.m.modifications : null)),
|
comps.utility.map(c => (c ? c.modifications : null)),
|
||||||
comps.internal.map(c => (c && c.m ? c.m.modifications : null))
|
comps.internal.map(c => (c ? c.modifications : null))
|
||||||
|
);
|
||||||
|
blueprints = blueprints.concat(
|
||||||
|
comps.hardpoints.map(c => (c ? c.blueprint : null)),
|
||||||
|
comps.utility.map(c => (c ? c.blueprint : null)),
|
||||||
|
comps.internal.map(c => (c ? c.blueprint : null))
|
||||||
);
|
);
|
||||||
|
|
||||||
ship.buildWith({ bulkheads, standard, hardpoints, internal }, priorities, enabled, modifications);
|
ship.buildWith({ bulkheads, standard, hardpoints, internal }, priorities, enabled, modifications, blueprints);
|
||||||
|
|
||||||
return ship;
|
return ship;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,12 +3,20 @@ import * as ModuleUtils from './ModuleUtils';
|
|||||||
import * as Utils from '../utils/UtilityFunctions';
|
import * as Utils from '../utils/UtilityFunctions';
|
||||||
import Module from './Module';
|
import Module from './Module';
|
||||||
import LZString from 'lz-string';
|
import LZString from 'lz-string';
|
||||||
|
import * as _ from 'lodash';
|
||||||
import isEqual from 'lodash/lang';
|
import isEqual from 'lodash/lang';
|
||||||
import { Modifications } from 'coriolis-data/dist';
|
import { Modifications } from 'coriolis-data/dist';
|
||||||
const zlib = require('zlib');
|
const zlib = require('zlib');
|
||||||
|
|
||||||
const UNIQUE_MODULES = ['psg', 'sg', 'bsg', 'rf', 'fs', 'fh'];
|
const UNIQUE_MODULES = ['psg', 'sg', 'bsg', 'rf', 'fs', 'fh'];
|
||||||
|
|
||||||
|
// Constants for modifications struct
|
||||||
|
const SLOT_ID_DONE = -1;
|
||||||
|
const MODIFICATION_ID_DONE = -1;
|
||||||
|
const MODIFICATION_ID_BLUEPRINT = -2;
|
||||||
|
const MODIFICATION_ID_GRADE = -3;
|
||||||
|
const MODIFICATION_ID_SPECIAL = -4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the power usage type of a slot and it's particular module
|
* Returns the power usage type of a slot and it's particular module
|
||||||
* @param {Object} slot The Slot
|
* @param {Object} slot The Slot
|
||||||
@@ -472,9 +480,10 @@ export default class Ship {
|
|||||||
* @param {array} priorities Slot priorities
|
* @param {array} priorities Slot priorities
|
||||||
* @param {Array} enabled Slot active/inactive
|
* @param {Array} enabled Slot active/inactive
|
||||||
* @param {Array} mods Modifications
|
* @param {Array} mods Modifications
|
||||||
|
* @param {Array} blueprints Blueprints for modifications
|
||||||
* @return {this} The current ship instance for chaining
|
* @return {this} The current ship instance for chaining
|
||||||
*/
|
*/
|
||||||
buildWith(comps, priorities, enabled, mods) {
|
buildWith(comps, priorities, enabled, mods, blueprints) {
|
||||||
let internal = this.internal,
|
let internal = this.internal,
|
||||||
standard = this.standard,
|
standard = this.standard,
|
||||||
hps = this.hardpoints,
|
hps = this.hardpoints,
|
||||||
@@ -514,6 +523,7 @@ export default class Ship {
|
|||||||
this.bulkheads.m = null;
|
this.bulkheads.m = null;
|
||||||
this.useBulkhead(comps && comps.bulkheads ? comps.bulkheads : 0, true);
|
this.useBulkhead(comps && comps.bulkheads ? comps.bulkheads : 0, true);
|
||||||
this.bulkheads.m.mods = mods && mods[0] ? mods[0] : {};
|
this.bulkheads.m.mods = mods && mods[0] ? mods[0] : {};
|
||||||
|
this.bulkheads.m.blueprint = blueprints && blueprints[0] ? blueprints[0] : {};
|
||||||
this.cargoHatch.priority = priorities ? priorities[0] * 1 : 0;
|
this.cargoHatch.priority = priorities ? priorities[0] * 1 : 0;
|
||||||
this.cargoHatch.enabled = enabled ? enabled[0] * 1 : true;
|
this.cargoHatch.enabled = enabled ? enabled[0] * 1 : true;
|
||||||
|
|
||||||
@@ -526,7 +536,10 @@ export default class Ship {
|
|||||||
standard[i].discountedCost = 0;
|
standard[i].discountedCost = 0;
|
||||||
if (comps) {
|
if (comps) {
|
||||||
let module = ModuleUtils.standard(i, comps.standard[i]);
|
let module = ModuleUtils.standard(i, comps.standard[i]);
|
||||||
if (module != null) { module.mods = mods && mods[i + 1] ? mods[i + 1] : {}; }
|
if (module != null) {
|
||||||
|
module.mods = mods && mods[i + 1] ? mods[i + 1] : {};
|
||||||
|
module.blueprint = blueprints && blueprints[i + 1] ? blueprints[i + 1] : {};
|
||||||
|
}
|
||||||
this.use(standard[i], module, true);
|
this.use(standard[i], module, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -545,7 +558,10 @@ export default class Ship {
|
|||||||
|
|
||||||
if (comps && comps.hardpoints[i] !== 0) {
|
if (comps && comps.hardpoints[i] !== 0) {
|
||||||
let module = ModuleUtils.hardpoints(comps.hardpoints[i]);
|
let module = ModuleUtils.hardpoints(comps.hardpoints[i]);
|
||||||
if (module != null) { module.mods = mods && mods[cl + i] ? mods[cl + i] : {}; }
|
if (module != null) {
|
||||||
|
module.mods = mods && mods[cl + i] ? mods[cl + i] : {};
|
||||||
|
module.blueprint = blueprints && blueprints[cl + i] ? blueprints[cl + i] : {};
|
||||||
|
}
|
||||||
this.use(hps[i], module, true);
|
this.use(hps[i], module, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -562,7 +578,10 @@ export default class Ship {
|
|||||||
|
|
||||||
if (comps && comps.internal[i] !== 0) {
|
if (comps && comps.internal[i] !== 0) {
|
||||||
let module = ModuleUtils.internal(comps.internal[i]);
|
let module = ModuleUtils.internal(comps.internal[i]);
|
||||||
if (module != null) { module.mods = mods && mods[cl + i] ? mods[cl + i] : {}; }
|
if (module != null) {
|
||||||
|
module.mods = mods && mods[cl + i] ? mods[cl + i] : {};
|
||||||
|
module.blueprint = blueprints && blueprints[cl + i] ? blueprints[cl + i] : {};
|
||||||
|
}
|
||||||
this.use(internal[i], module, true);
|
this.use(internal[i], module, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -596,6 +615,7 @@ export default class Ship {
|
|||||||
hardpoints = new Array(this.hardpoints.length),
|
hardpoints = new Array(this.hardpoints.length),
|
||||||
internal = new Array(this.internal.length),
|
internal = new Array(this.internal.length),
|
||||||
modifications = new Array(1 + this.standard.length + this.hardpoints.length + this.internal.length),
|
modifications = new Array(1 + this.standard.length + this.hardpoints.length + this.internal.length),
|
||||||
|
blueprints = new Array(1 + this.standard.length + this.hardpoints.length + this.internal.length),
|
||||||
parts = serializedString.split('.'),
|
parts = serializedString.split('.'),
|
||||||
priorities = null,
|
priorities = null,
|
||||||
enabled = null,
|
enabled = null,
|
||||||
@@ -615,7 +635,7 @@ export default class Ship {
|
|||||||
this.decodeModificationsString(modstr, modifications);
|
this.decodeModificationsString(modstr, modifications);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
this.decodeModificationsStruct(zlib.gunzipSync(new Buffer(Utils.fromUrlSafe(modstr), 'base64')), modifications);
|
this.decodeModificationsStruct(zlib.gunzipSync(new Buffer(Utils.fromUrlSafe(modstr), 'base64')), modifications, blueprints);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Could be out-of-date URL; ignore
|
// Could be out-of-date URL; ignore
|
||||||
}
|
}
|
||||||
@@ -633,7 +653,8 @@ export default class Ship {
|
|||||||
},
|
},
|
||||||
priorities,
|
priorities,
|
||||||
enabled,
|
enabled,
|
||||||
modifications
|
modifications,
|
||||||
|
blueprints,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -909,22 +930,22 @@ export default class Ship {
|
|||||||
totalDpe += dpe;
|
totalDpe += dpe;
|
||||||
totalDps += dps;
|
totalDps += dps;
|
||||||
totalSDps += sdps;
|
totalSDps += sdps;
|
||||||
if (slot.m.type === 'E') {
|
if (slot.m.getDamageType() === 'E') {
|
||||||
totalExplDpe += dpe;
|
totalExplDpe += dpe;
|
||||||
totalExplDps += dps;
|
totalExplDps += dps;
|
||||||
totalExplSDps += sdps;
|
totalExplSDps += sdps;
|
||||||
}
|
}
|
||||||
if (slot.m.type === 'K') {
|
if (slot.m.getDamageType() === 'K') {
|
||||||
totalKinDpe += dpe;
|
totalKinDpe += dpe;
|
||||||
totalKinDps += dps;
|
totalKinDps += dps;
|
||||||
totalKinSDps += sdps;
|
totalKinSDps += sdps;
|
||||||
}
|
}
|
||||||
if (slot.m.type === 'T') {
|
if (slot.m.getDamageType() === 'T') {
|
||||||
totalThermDpe += dpe;
|
totalThermDpe += dpe;
|
||||||
totalThermDps += dps;
|
totalThermDps += dps;
|
||||||
totalThermSDps += sdps;
|
totalThermSDps += sdps;
|
||||||
}
|
}
|
||||||
if (slot.m.type === 'EK') {
|
if (slot.m.getDamageType() === 'EK') {
|
||||||
totalExplDpe += dpe / 2;
|
totalExplDpe += dpe / 2;
|
||||||
totalKinDpe += dpe / 2;
|
totalKinDpe += dpe / 2;
|
||||||
totalExplDps += dps / 2;
|
totalExplDps += dps / 2;
|
||||||
@@ -932,7 +953,7 @@ export default class Ship {
|
|||||||
totalExplSDps += sdps / 2;
|
totalExplSDps += sdps / 2;
|
||||||
totalKinSDps += sdps / 2;
|
totalKinSDps += sdps / 2;
|
||||||
}
|
}
|
||||||
if (slot.m.type === 'ET') {
|
if (slot.m.getDamageType() === 'ET') {
|
||||||
totalExplDpe += dpe / 2;
|
totalExplDpe += dpe / 2;
|
||||||
totalThermDpe += dpe / 2;
|
totalThermDpe += dpe / 2;
|
||||||
totalExplDps += dps / 2;
|
totalExplDps += dps / 2;
|
||||||
@@ -940,7 +961,7 @@ export default class Ship {
|
|||||||
totalExplSDps += sdps / 2;
|
totalExplSDps += sdps / 2;
|
||||||
totalThermSDps += sdps / 2;
|
totalThermSDps += sdps / 2;
|
||||||
}
|
}
|
||||||
if (slot.m.type === 'KT') {
|
if (slot.m.getDamageType() === 'KT') {
|
||||||
totalKinDpe += dpe / 2;
|
totalKinDpe += dpe / 2;
|
||||||
totalThermDpe += dpe / 2;
|
totalThermDpe += dpe / 2;
|
||||||
totalKinDps += dps / 2;
|
totalKinDps += dps / 2;
|
||||||
@@ -1224,52 +1245,6 @@ export default class Ship {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the modifications string in a human-readable format
|
|
||||||
* @return {this} The ship instance (for chaining operations)
|
|
||||||
*/
|
|
||||||
debugupdateModificationsString() {
|
|
||||||
let allMods = new Array();
|
|
||||||
|
|
||||||
let bulkheadMods = new Array();
|
|
||||||
if (this.bulkheads.m && this.bulkheads.m.mods) {
|
|
||||||
for (let modKey in this.bulkheads.m.mods) {
|
|
||||||
bulkheadMods.push(Modifications.modifications.indexOf(modKey) + ':' + this.bulkheads.m.getModValue(modKey));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allMods.push(bulkheadMods.join(';'));
|
|
||||||
|
|
||||||
for (let slot of this.standard) {
|
|
||||||
let slotMods = new Array();
|
|
||||||
if (slot.m && slot.m.mods) {
|
|
||||||
for (let modKey in slot.m.mods) {
|
|
||||||
slotMods.push(Modifications.modifications.indexOf(modKey) + ':' + slot.m.getModValue(modKey));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allMods.push(slotMods.join(';'));
|
|
||||||
}
|
|
||||||
for (let slot of this.hardpoints) {
|
|
||||||
let slotMods = new Array();
|
|
||||||
if (slot.m && slot.m.mods) {
|
|
||||||
for (let modKey in slot.m.mods) {
|
|
||||||
slotMods.push(Modifications.modifications.indexOf(modKey) + ':' + slot.m.getModValue(modKey));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allMods.push(slotMods.join(';'));
|
|
||||||
}
|
|
||||||
for (let slot of this.internal) {
|
|
||||||
let slotMods = new Array();
|
|
||||||
if (slot.m && slot.m.mods) {
|
|
||||||
for (let modKey in slot.m.mods) {
|
|
||||||
slotMods.push(Modifications.modifications.indexOf(modKey) + ':' + slot.m.getModValue(modKey));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allMods.push(slotMods.join(';'));
|
|
||||||
}
|
|
||||||
this.serialized.modifications = LZString.compressToBase64(allMods.join(',').replace(/,+$/, ''));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate the modifications array with modification values from the code
|
* Populate the modifications array with modification values from the code
|
||||||
* @param {String} code Serialized modification code
|
* @param {String} code Serialized modification code
|
||||||
@@ -1284,7 +1259,8 @@ export default class Ship {
|
|||||||
for (let j = 0; j < mods.length; j++) {
|
for (let j = 0; j < mods.length; j++) {
|
||||||
let modElements = mods[j].split(':');
|
let modElements = mods[j].split(':');
|
||||||
if (modElements[0].match('[0-9]+')) {
|
if (modElements[0].match('[0-9]+')) {
|
||||||
arr[i][Modifications.modifications[modElements[0]]] = Number(modElements[1]);
|
const modification = _.find(Modifications.modifications, function(o) { return o.id === modElements[0]; });
|
||||||
|
if (modification != null) arr[i][modification.name] = Number(modElements[1]);
|
||||||
} else {
|
} else {
|
||||||
arr[i][modElements[0]] = Number(modElements[1]);
|
arr[i][modElements[0]] = Number(modElements[1]);
|
||||||
}
|
}
|
||||||
@@ -1305,17 +1281,24 @@ export default class Ship {
|
|||||||
updateModificationsString() {
|
updateModificationsString() {
|
||||||
// Start off by gathering the information that we need
|
// Start off by gathering the information that we need
|
||||||
let slots = new Array();
|
let slots = new Array();
|
||||||
|
let blueprints = new Array();
|
||||||
|
let specials = new Array();
|
||||||
|
|
||||||
let bulkheadMods = new Array();
|
let bulkheadMods = new Array();
|
||||||
|
let bulkheadBlueprint = null;
|
||||||
|
let bulkheadBlueprintGrade = null;
|
||||||
if (this.bulkheads.m && this.bulkheads.m.mods) {
|
if (this.bulkheads.m && this.bulkheads.m.mods) {
|
||||||
for (let modKey in this.bulkheads.m.mods) {
|
for (let modKey in this.bulkheads.m.mods) {
|
||||||
// Filter out invalid modifications
|
// Filter out invalid modifications
|
||||||
if (Modifications.validity['bh'] && Modifications.validity['bh'].indexOf(modKey) != -1) {
|
if (Modifications.validity['bh'] && Modifications.validity['bh'].indexOf(modKey) != -1) {
|
||||||
bulkheadMods.push({ id: Modifications.modifications.indexOf(modKey), value: this.bulkheads.m.getModValue(modKey) });
|
bulkheadMods.push({ id: Modifications.modifications[modKey].id, value: this.bulkheads.m.getModValue(modKey) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bulkheadBlueprint = this.bulkheads.m.blueprint;
|
||||||
}
|
}
|
||||||
slots.push(bulkheadMods);
|
slots.push(bulkheadMods);
|
||||||
|
blueprints.push(bulkheadBlueprint)
|
||||||
|
specials.push(bulkheadBlueprint ? bulkheadBlueprint.special : null);
|
||||||
|
|
||||||
for (let slot of this.standard) {
|
for (let slot of this.standard) {
|
||||||
let slotMods = new Array();
|
let slotMods = new Array();
|
||||||
@@ -1323,11 +1306,13 @@ export default class Ship {
|
|||||||
for (let modKey in slot.m.mods) {
|
for (let modKey in slot.m.mods) {
|
||||||
// Filter out invalid modifications
|
// Filter out invalid modifications
|
||||||
if (Modifications.validity[slot.m.grp] && Modifications.validity[slot.m.grp].indexOf(modKey) != -1) {
|
if (Modifications.validity[slot.m.grp] && Modifications.validity[slot.m.grp].indexOf(modKey) != -1) {
|
||||||
slotMods.push({ id: Modifications.modifications.indexOf(modKey), value: slot.m.getModValue(modKey) });
|
slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slots.push(slotMods);
|
slots.push(slotMods);
|
||||||
|
blueprints.push(slot.m ? slot.m.blueprint : null);
|
||||||
|
specials.push(slot.m && slot.m.blueprint ? slot.m.blueprint.special : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let slot of this.hardpoints) {
|
for (let slot of this.hardpoints) {
|
||||||
@@ -1336,11 +1321,13 @@ export default class Ship {
|
|||||||
for (let modKey in slot.m.mods) {
|
for (let modKey in slot.m.mods) {
|
||||||
// Filter out invalid modifications
|
// Filter out invalid modifications
|
||||||
if (Modifications.validity[slot.m.grp] && Modifications.validity[slot.m.grp].indexOf(modKey) != -1) {
|
if (Modifications.validity[slot.m.grp] && Modifications.validity[slot.m.grp].indexOf(modKey) != -1) {
|
||||||
slotMods.push({ id: Modifications.modifications.indexOf(modKey), value: slot.m.getModValue(modKey) });
|
slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slots.push(slotMods);
|
slots.push(slotMods);
|
||||||
|
blueprints.push(slot.m ? slot.m.blueprint : null);
|
||||||
|
specials.push(slot.m && slot.m.blueprint ? slot.m.blueprint.special : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let slot of this.internal) {
|
for (let slot of this.internal) {
|
||||||
@@ -1349,18 +1336,27 @@ export default class Ship {
|
|||||||
for (let modKey in slot.m.mods) {
|
for (let modKey in slot.m.mods) {
|
||||||
// Filter out invalid modifications
|
// Filter out invalid modifications
|
||||||
if (Modifications.validity[slot.m.grp] && Modifications.validity[slot.m.grp].indexOf(modKey) != -1) {
|
if (Modifications.validity[slot.m.grp] && Modifications.validity[slot.m.grp].indexOf(modKey) != -1) {
|
||||||
slotMods.push({ id: Modifications.modifications.indexOf(modKey), value: slot.m.getModValue(modKey) });
|
slotMods.push({ id: Modifications.modifications[modKey].id, value: slot.m.getModValue(modKey) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slots.push(slotMods);
|
slots.push(slotMods);
|
||||||
|
blueprints.push(slot.m ? slot.m.blueprint : null);
|
||||||
|
specials.push(slot.m && slot.m.blueprint ? slot.m.blueprint.special : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now work out the size of the binary buffer from our modifications array
|
// Now work out the size of the binary buffer from our modifications array
|
||||||
let bufsize = 0;
|
let bufsize = 0;
|
||||||
for (let slot of slots) {
|
for (let slot of slots) {
|
||||||
if (slot.length > 0) {
|
if (slot.length > 0) {
|
||||||
bufsize = bufsize + 1 + (5 * slot.length) + 1;
|
// Length is 1 for the slot ID, 10 for the blueprint name and grade, 5 for each modification, and 1 for the end marker
|
||||||
|
bufsize = bufsize + 1 + 10 + (5 * slot.length) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let special of specials) {
|
||||||
|
if (special) {
|
||||||
|
// Length is 5 for each special
|
||||||
|
bufsize += 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1373,18 +1369,37 @@ export default class Ship {
|
|||||||
for (let slot of slots) {
|
for (let slot of slots) {
|
||||||
if (slot.length > 0) {
|
if (slot.length > 0) {
|
||||||
buffer.writeInt8(i, curpos++);
|
buffer.writeInt8(i, curpos++);
|
||||||
for (let slotMod of slot) {
|
if (blueprints[i]) {
|
||||||
buffer.writeInt8(slotMod.id, curpos++);
|
buffer.writeInt8(MODIFICATION_ID_BLUEPRINT, curpos++);
|
||||||
buffer.writeInt32LE(slotMod.value, curpos);
|
buffer.writeInt32LE(blueprints[i].id, curpos);
|
||||||
// console.log('ENCODE Slot ' + i + ': ' + Modifications.modifications[slotMod.id] + ' = ' + slotMod.value);
|
curpos += 4;
|
||||||
|
buffer.writeInt8(MODIFICATION_ID_GRADE, curpos++);
|
||||||
|
buffer.writeInt32LE(blueprints[i].grade, curpos);
|
||||||
curpos += 4;
|
curpos += 4;
|
||||||
}
|
}
|
||||||
buffer.writeInt8(-1, curpos++);
|
if (specials[i]) {
|
||||||
|
buffer.writeInt8(MODIFICATION_ID_SPECIAL, curpos++);
|
||||||
|
buffer.writeInt32LE(specials[i].id, curpos);
|
||||||
|
curpos += 4;
|
||||||
|
}
|
||||||
|
for (let slotMod of slot) {
|
||||||
|
buffer.writeInt8(slotMod.id, curpos++);
|
||||||
|
if (isNaN(slotMod.value)) {
|
||||||
|
// Need to write the string with exactly four characters, so pad with whitespace
|
||||||
|
buffer.write((" " + slotMod.value).slice(-4), curpos, 4);
|
||||||
|
} else {
|
||||||
|
buffer.writeInt32LE(slotMod.value, curpos);
|
||||||
|
}
|
||||||
|
// const modification = _.find(Modifications.modifications, function(o) { return o.id === slotMod.id; });
|
||||||
|
// console.log('ENCODE Slot ' + i + ': ' + modification.name + ' = ' + slotMod.value);
|
||||||
|
curpos += 4;
|
||||||
|
}
|
||||||
|
buffer.writeInt8(MODIFICATION_ID_DONE, curpos++);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (curpos > 0) {
|
if (curpos > 0) {
|
||||||
buffer.writeInt8(-1, curpos++);
|
buffer.writeInt8(SLOT_ID_DONE, curpos++);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.serialized.modifications = zlib.gzipSync(buffer).toString('base64');
|
this.serialized.modifications = zlib.gzipSync(buffer).toString('base64');
|
||||||
@@ -1398,22 +1413,41 @@ export default class Ship {
|
|||||||
* Populate the modifications array with modification values from the code.
|
* Populate the modifications array with modification values from the code.
|
||||||
* See updateModificationsString() for details of the structure.
|
* See updateModificationsString() for details of the structure.
|
||||||
* @param {String} buffer Buffer holding modification info
|
* @param {String} buffer Buffer holding modification info
|
||||||
* @param {Array} arr Modification array
|
* @param {Array} modArr Modification array
|
||||||
|
* @param {Array} bluprintArr Blueprint array
|
||||||
*/
|
*/
|
||||||
decodeModificationsStruct(buffer, arr) {
|
decodeModificationsStruct(buffer, modArr, blueprintArr) {
|
||||||
let curpos = 0;
|
let curpos = 0;
|
||||||
let slot = buffer.readInt8(curpos++);
|
let slot = buffer.readInt8(curpos++);
|
||||||
while (slot != -1) {
|
while (slot != SLOT_ID_DONE) {
|
||||||
let modifications = {};
|
let modifications = {};
|
||||||
|
let blueprint = {};
|
||||||
let modificationId = buffer.readInt8(curpos++);
|
let modificationId = buffer.readInt8(curpos++);
|
||||||
while (modificationId != -1) {
|
while (modificationId != MODIFICATION_ID_DONE) {
|
||||||
let modificationValue = buffer.readInt32LE(curpos);
|
let modificationValue;
|
||||||
|
if (modificationId === 40) {
|
||||||
|
// Type is special, in that it's a character string
|
||||||
|
modificationValue = buffer.toString('utf8', curpos, curpos + 4).trim();
|
||||||
|
} else {
|
||||||
|
modificationValue = buffer.readInt32LE(curpos);
|
||||||
|
}
|
||||||
curpos += 4;
|
curpos += 4;
|
||||||
// console.log('DECODE Slot ' + slot + ': ' + Modifications.modifications[modificationId] + ' = ' + modificationValue);
|
// There are a number of 'special' modification IDs, check for them here
|
||||||
modifications[Modifications.modifications[modificationId]] = modificationValue;
|
if (modificationId === MODIFICATION_ID_BLUEPRINT) {
|
||||||
|
blueprint = Object.assign(blueprint, _.find(Modifications.blueprints, function(o) { return o.id === modificationValue; }));
|
||||||
|
} else if (modificationId === MODIFICATION_ID_GRADE) {
|
||||||
|
blueprint.grade = modificationValue;
|
||||||
|
} else if (modificationId === MODIFICATION_ID_SPECIAL) {
|
||||||
|
blueprint.special = _.find(Modifications.specials, function(o) { return o.id === modificationValue; });
|
||||||
|
} else {
|
||||||
|
const modification = _.find(Modifications.modifications, function(o) { return o.id === modificationId; });
|
||||||
|
// console.log('DECODE Slot ' + slot + ': ' + modification.name + ' = ' + modificationValue);
|
||||||
|
modifications[modification.name] = modificationValue;
|
||||||
|
}
|
||||||
modificationId = buffer.readInt8(curpos++);
|
modificationId = buffer.readInt8(curpos++);
|
||||||
}
|
}
|
||||||
arr[slot] = modifications;
|
modArr[slot] = modifications;
|
||||||
|
blueprintArr[slot] = blueprint;
|
||||||
slot = buffer.readInt8(curpos++);
|
slot = buffer.readInt8(curpos++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ const SHIP_FD_NAME_TO_CORIOLIS_NAME = {
|
|||||||
'CobraMkIII': 'cobra_mk_iii',
|
'CobraMkIII': 'cobra_mk_iii',
|
||||||
'CobraMkIV': 'cobra_mk_iv',
|
'CobraMkIV': 'cobra_mk_iv',
|
||||||
'Cutter': 'imperial_cutter',
|
'Cutter': 'imperial_cutter',
|
||||||
'DiamondBack': 'diamondback_explorer',
|
'DiamondBackXL': 'diamondback_explorer',
|
||||||
'DiamondBackXL': 'diamondback',
|
'DiamondBack': 'diamondback',
|
||||||
'Eagle': 'eagle',
|
'Eagle': 'eagle',
|
||||||
'Empire_Courier': 'imperial_courier',
|
'Empire_Courier': 'imperial_courier',
|
||||||
'Empire_Eagle': 'imperial_eagle',
|
'Empire_Eagle': 'imperial_eagle',
|
||||||
@@ -149,13 +149,13 @@ export function shipFromJson(json) {
|
|||||||
throw 'Unknown bulkheads "' + armourJson.name + '"';
|
throw 'Unknown bulkheads "' + armourJson.name + '"';
|
||||||
}
|
}
|
||||||
ship.bulkheads.enabled = true;
|
ship.bulkheads.enabled = true;
|
||||||
if (armourJson.modifiers) _addModifications(ship.bulkheads.m, armourJson.modifiers);
|
if (armourJson.modifiers) _addModifications(ship.bulkheads.m, armourJson.modifiers, armourJson.recipeName, armourJson.recipeLevel);
|
||||||
|
|
||||||
// Add the standard modules
|
// Add the standard modules
|
||||||
// Power plant
|
// Power plant
|
||||||
const powerplantJson = json.modules.PowerPlant.module;
|
const powerplantJson = json.modules.PowerPlant.module;
|
||||||
const powerplant = _moduleFromEdId(powerplantJson.id);
|
const powerplant = _moduleFromEdId(powerplantJson.id);
|
||||||
if (powerplantJson.modifiers) _addModifications(powerplant, powerplantJson.modifiers);
|
if (powerplantJson.modifiers) _addModifications(powerplant, powerplantJson.modifiers, powerplantJson.recipeName, powerplantJson.recipeLevel);
|
||||||
ship.use(ship.standard[0], powerplant, true);
|
ship.use(ship.standard[0], powerplant, true);
|
||||||
ship.standard[0].enabled = powerplantJson.on === true;
|
ship.standard[0].enabled = powerplantJson.on === true;
|
||||||
ship.standard[0].priority = powerplantJson.priority;
|
ship.standard[0].priority = powerplantJson.priority;
|
||||||
@@ -163,7 +163,7 @@ export function shipFromJson(json) {
|
|||||||
// Thrusters
|
// Thrusters
|
||||||
const thrustersJson = json.modules.MainEngines.module;
|
const thrustersJson = json.modules.MainEngines.module;
|
||||||
const thrusters = _moduleFromEdId(thrustersJson.id);
|
const thrusters = _moduleFromEdId(thrustersJson.id);
|
||||||
if (thrustersJson.modifiers) _addModifications(thrusters, thrustersJson.modifiers);
|
if (thrustersJson.modifiers) _addModifications(thrusters, thrustersJson.modifiers, thrustersJson.recipeName, thrustersJson.recipeLevel);
|
||||||
ship.use(ship.standard[1], thrusters, true);
|
ship.use(ship.standard[1], thrusters, true);
|
||||||
ship.standard[1].enabled = thrustersJson.on === true;
|
ship.standard[1].enabled = thrustersJson.on === true;
|
||||||
ship.standard[1].priority = thrustersJson.priority;
|
ship.standard[1].priority = thrustersJson.priority;
|
||||||
@@ -171,7 +171,7 @@ export function shipFromJson(json) {
|
|||||||
// FSD
|
// FSD
|
||||||
const frameshiftdriveJson = json.modules.FrameShiftDrive.module;
|
const frameshiftdriveJson = json.modules.FrameShiftDrive.module;
|
||||||
const frameshiftdrive = _moduleFromEdId(frameshiftdriveJson.id);
|
const frameshiftdrive = _moduleFromEdId(frameshiftdriveJson.id);
|
||||||
if (frameshiftdriveJson.modifiers) _addModifications(frameshiftdrive, frameshiftdriveJson.modifiers);
|
if (frameshiftdriveJson.modifiers) _addModifications(frameshiftdrive, frameshiftdriveJson.modifiers, frameshiftdriveJson.recipeName, frameshiftdriveJson.recipeLevel);
|
||||||
ship.use(ship.standard[2], frameshiftdrive, true);
|
ship.use(ship.standard[2], frameshiftdrive, true);
|
||||||
ship.standard[2].enabled = frameshiftdriveJson.on === true;
|
ship.standard[2].enabled = frameshiftdriveJson.on === true;
|
||||||
ship.standard[2].priority = frameshiftdriveJson.priority;
|
ship.standard[2].priority = frameshiftdriveJson.priority;
|
||||||
@@ -179,7 +179,7 @@ export function shipFromJson(json) {
|
|||||||
// Life support
|
// Life support
|
||||||
const lifesupportJson = json.modules.LifeSupport.module;
|
const lifesupportJson = json.modules.LifeSupport.module;
|
||||||
const lifesupport = _moduleFromEdId(lifesupportJson.id);
|
const lifesupport = _moduleFromEdId(lifesupportJson.id);
|
||||||
if (lifesupportJson.modifiers)_addModifications(lifesupport, lifesupportJson.modifiers);
|
if (lifesupportJson.modifiers)_addModifications(lifesupport, lifesupportJson.modifiers, lifesupportJson.recipeName, lifesupportJson.recipeLevel);
|
||||||
ship.use(ship.standard[3], lifesupport, true);
|
ship.use(ship.standard[3], lifesupport, true);
|
||||||
ship.standard[3].enabled = lifesupportJson.on === true;
|
ship.standard[3].enabled = lifesupportJson.on === true;
|
||||||
ship.standard[3].priority = lifesupportJson.priority;
|
ship.standard[3].priority = lifesupportJson.priority;
|
||||||
@@ -187,7 +187,7 @@ export function shipFromJson(json) {
|
|||||||
// Power distributor
|
// Power distributor
|
||||||
const powerdistributorJson = json.modules.PowerDistributor.module;
|
const powerdistributorJson = json.modules.PowerDistributor.module;
|
||||||
const powerdistributor = _moduleFromEdId(powerdistributorJson.id);
|
const powerdistributor = _moduleFromEdId(powerdistributorJson.id);
|
||||||
if (powerdistributorJson.modifiers) _addModifications(powerdistributor, powerdistributorJson.modifiers);
|
if (powerdistributorJson.modifiers) _addModifications(powerdistributor, powerdistributorJson.modifiers, powerdistributorJson.recipeName, powerdistributorJson.recipeLevel);
|
||||||
ship.use(ship.standard[4], powerdistributor, true);
|
ship.use(ship.standard[4], powerdistributor, true);
|
||||||
ship.standard[4].enabled = powerdistributorJson.on === true;
|
ship.standard[4].enabled = powerdistributorJson.on === true;
|
||||||
ship.standard[4].priority = powerdistributorJson.priority;
|
ship.standard[4].priority = powerdistributorJson.priority;
|
||||||
@@ -195,7 +195,7 @@ export function shipFromJson(json) {
|
|||||||
// Sensors
|
// Sensors
|
||||||
const sensorsJson = json.modules.Radar.module;
|
const sensorsJson = json.modules.Radar.module;
|
||||||
const sensors = _moduleFromEdId(sensorsJson.id);
|
const sensors = _moduleFromEdId(sensorsJson.id);
|
||||||
if (sensorsJson.modifiers) _addModifications(sensors, sensorsJson.modifiers);
|
if (sensorsJson.modifiers) _addModifications(sensors, sensorsJson.modifiers, sensorsJson.recipeName, sensorsJson.recipeLevel);
|
||||||
ship.use(ship.standard[5], sensors, true);
|
ship.use(ship.standard[5], sensors, true);
|
||||||
ship.standard[5].enabled = sensorsJson.on === true;
|
ship.standard[5].enabled = sensorsJson.on === true;
|
||||||
ship.standard[5].priority = sensorsJson.priority;
|
ship.standard[5].priority = sensorsJson.priority;
|
||||||
@@ -229,7 +229,7 @@ export function shipFromJson(json) {
|
|||||||
} else {
|
} else {
|
||||||
const hardpointJson = hardpointSlot.module;
|
const hardpointJson = hardpointSlot.module;
|
||||||
const hardpoint = _moduleFromEdId(hardpointJson.id);
|
const hardpoint = _moduleFromEdId(hardpointJson.id);
|
||||||
if (hardpointJson.modifiers) _addModifications(hardpoint, hardpointJson.modifiers);
|
if (hardpointJson.modifiers) _addModifications(hardpoint, hardpointJson.modifiers, hardpointJson.recipeName, hardpointJson.recipeLevel);
|
||||||
ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true);
|
ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true);
|
||||||
ship.hardpoints[hardpointArrayNum].enabled = hardpointJson.on === true;
|
ship.hardpoints[hardpointArrayNum].enabled = hardpointJson.on === true;
|
||||||
ship.hardpoints[hardpointArrayNum].priority = hardpointJson.priority;
|
ship.hardpoints[hardpointArrayNum].priority = hardpointJson.priority;
|
||||||
@@ -240,7 +240,7 @@ export function shipFromJson(json) {
|
|||||||
// Add internal compartments
|
// Add internal compartments
|
||||||
let internalSlotNum = 1;
|
let internalSlotNum = 1;
|
||||||
for (let i in shipTemplate.slots.internal) {
|
for (let i in shipTemplate.slots.internal) {
|
||||||
const internalClassNum = shipTemplate.slots.internal[i];
|
const internalClassNum = isNaN(shipTemplate.slots.internal[i]) ? shipTemplate.slots.internal[i].class : shipTemplate.slots.internal[i];
|
||||||
|
|
||||||
let internalSlot = null;
|
let internalSlot = null;
|
||||||
while (internalSlot === null && internalSlotNum < 99) {
|
while (internalSlot === null && internalSlotNum < 99) {
|
||||||
@@ -256,7 +256,7 @@ export function shipFromJson(json) {
|
|||||||
} else {
|
} else {
|
||||||
const internalJson = internalSlot.module;
|
const internalJson = internalSlot.module;
|
||||||
const internal = _moduleFromEdId(internalJson.id);
|
const internal = _moduleFromEdId(internalJson.id);
|
||||||
if (internalJson.modifiers) _addModifications(internal, internalJson.modifiers);
|
if (internalJson.modifiers) _addModifications(internal, internalJson.modifiers, internalJson.recipeName, internalJson.recipeLevel);
|
||||||
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;
|
||||||
@@ -271,10 +271,13 @@ export function shipFromJson(json) {
|
|||||||
* Add the modifications for a module
|
* Add the modifications for a module
|
||||||
* @param {Module} module the module
|
* @param {Module} module the module
|
||||||
* @param {Object} modifiers the modifiers
|
* @param {Object} modifiers the modifiers
|
||||||
|
* @param {Object} blueprint the blueprint of the modification
|
||||||
|
* @param {Object} grade the grade of the modification
|
||||||
*/
|
*/
|
||||||
function _addModifications(module, modifiers) {
|
function _addModifications(module, modifiers, blueprint, grade) {
|
||||||
if (!modifiers || !modifiers.modifiers) return;
|
if (!modifiers || !modifiers.modifiers) return;
|
||||||
|
|
||||||
|
var special;
|
||||||
for (const i in modifiers.modifiers) {
|
for (const i in modifiers.modifiers) {
|
||||||
// Look up the modifiers to find what we need to do
|
// Look up the modifiers to find what we need to do
|
||||||
const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name];
|
const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name];
|
||||||
@@ -282,6 +285,9 @@ function _addModifications(module, modifiers) {
|
|||||||
|
|
||||||
// Carry out the required changes
|
// Carry out the required changes
|
||||||
for (const action in modifierActions) {
|
for (const action in modifierActions) {
|
||||||
|
if (isNaN(modifierActions[action])) {
|
||||||
|
module.setModValue(action, modifierActions[action]);
|
||||||
|
} else {
|
||||||
const actionValue = modifierActions[action] * value;
|
const actionValue = modifierActions[action] * value;
|
||||||
let mod = module.getModValue(action) / 10000;
|
let mod = module.getModValue(action) / 10000;
|
||||||
if (!mod) {
|
if (!mod) {
|
||||||
@@ -291,6 +297,23 @@ function _addModifications(module, modifiers) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note the special if present
|
||||||
|
if (modifiers.modifiers[i].name && modifiers.modifiers[i].name.startsWith('special_')) {
|
||||||
|
special = Modifications.specials[modifiers.modifiers[i].name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the blueprint ID, grade and special
|
||||||
|
if (blueprint) {
|
||||||
|
module.blueprint = Object.assign({}, Modifications.blueprints[blueprint]);
|
||||||
|
if (grade) {
|
||||||
|
module.blueprint.grade = Number(grade);
|
||||||
|
}
|
||||||
|
if (special) {
|
||||||
|
module.blueprint.special = special;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Need to fix up a few items
|
// Need to fix up a few items
|
||||||
|
|
||||||
// Shield boosters are treated internally as straight modifiers, so rather than (for example)
|
// Shield boosters are treated internally as straight modifiers, so rather than (for example)
|
||||||
@@ -355,6 +378,12 @@ function _addModifications(module, modifiers) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bulkhead boost is based off the inherent boost of the module
|
||||||
|
if (module.grp == 'bh') {
|
||||||
|
const alteredBoost = (1 + module.hullboost) * (1 + module.getModValue('hullboost') / 10000) - 1;
|
||||||
|
module.setModValue('hullboost', (alteredBoost / module.hullboost - 1) * 10000);
|
||||||
|
}
|
||||||
|
|
||||||
// Jitter is an absolute number, so we need to divide it by 100
|
// Jitter is an absolute number, so we need to divide it by 100
|
||||||
if (module.getModValue('jitter')) {
|
if (module.getModValue('jitter')) {
|
||||||
module.setModValue('jitter', module.getModValue('jitter') / 100);
|
module.setModValue('jitter', module.getModValue('jitter') / 100);
|
||||||
|
|||||||
@@ -68,6 +68,7 @@
|
|||||||
"rating": { "$ref": "#/definitions/standardRatings" },
|
"rating": { "$ref": "#/definitions/standardRatings" },
|
||||||
"enabled": { "type": "boolean" },
|
"enabled": { "type": "boolean" },
|
||||||
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||||
|
"blueprint": { "type": "object" },
|
||||||
"modifications": { "type": "object" }
|
"modifications": { "type": "object" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -82,6 +83,7 @@
|
|||||||
"description": "The name identifing the thrusters (if applicable), e.g. 'Enhanced Performance'",
|
"description": "The name identifing the thrusters (if applicable), e.g. 'Enhanced Performance'",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"blueprint": { "type": "object" },
|
||||||
"modifications": { "type": "object" }
|
"modifications": { "type": "object" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -92,6 +94,7 @@
|
|||||||
"rating": { "$ref": "#/definitions/standardRatings" },
|
"rating": { "$ref": "#/definitions/standardRatings" },
|
||||||
"enabled": { "type": "boolean" },
|
"enabled": { "type": "boolean" },
|
||||||
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||||
|
"blueprint": { "type": "object" },
|
||||||
"modifications": { "type": "object" }
|
"modifications": { "type": "object" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -102,6 +105,7 @@
|
|||||||
"rating": { "$ref": "#/definitions/standardRatings" },
|
"rating": { "$ref": "#/definitions/standardRatings" },
|
||||||
"enabled": { "type": "boolean" },
|
"enabled": { "type": "boolean" },
|
||||||
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||||
|
"blueprint": { "type": "object" },
|
||||||
"modifications": { "type": "object" }
|
"modifications": { "type": "object" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -112,6 +116,7 @@
|
|||||||
"rating": { "$ref": "#/definitions/standardRatings" },
|
"rating": { "$ref": "#/definitions/standardRatings" },
|
||||||
"enabled": { "type": "boolean" },
|
"enabled": { "type": "boolean" },
|
||||||
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||||
|
"blueprint": { "type": "object" },
|
||||||
"modifications": { "type": "object" }
|
"modifications": { "type": "object" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -122,6 +127,7 @@
|
|||||||
"rating": { "$ref": "#/definitions/standardRatings" },
|
"rating": { "$ref": "#/definitions/standardRatings" },
|
||||||
"enabled": { "type": "boolean" },
|
"enabled": { "type": "boolean" },
|
||||||
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||||
|
"blueprint": { "type": "object" },
|
||||||
"modifications": { "type": "object" }
|
"modifications": { "type": "object" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -132,6 +138,7 @@
|
|||||||
"rating": { "$ref": "#/definitions/standardRatings" },
|
"rating": { "$ref": "#/definitions/standardRatings" },
|
||||||
"enabled": { "type": "boolean" },
|
"enabled": { "type": "boolean" },
|
||||||
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
"priority": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||||
|
"blueprint": { "type": "object" },
|
||||||
"modifications": { "type": "object" }
|
"modifications": { "type": "object" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,6 +162,7 @@
|
|||||||
"description": "The name identifying the component (if applicable), e.g. 'Advance Discovery Scanner', or 'Detailed Surface Scanner'",
|
"description": "The name identifying the component (if applicable), e.g. 'Advance Discovery Scanner', or 'Detailed Surface Scanner'",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"blueprint": { "type": "object" },
|
||||||
"modifications": { "type": "object" }
|
"modifications": { "type": "object" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -179,6 +187,7 @@
|
|||||||
"description": "The name identifing the component (if applicable), e.g. 'Retributor', or 'Mining Lance'",
|
"description": "The name identifing the component (if applicable), e.g. 'Retributor', or 'Mining Lance'",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"blueprint": { "type": "object" },
|
||||||
"modifications": { "type": "object" }
|
"modifications": { "type": "object" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -202,6 +211,7 @@
|
|||||||
"description": "The name identifing the component (if applicable), e.g. 'Point Defence', or 'Electronic Countermeasure'",
|
"description": "The name identifing the component (if applicable), e.g. 'Point Defence', or 'Electronic Countermeasure'",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"blueprint": { "type": "object" },
|
||||||
"modifications": { "type": "object" }
|
"modifications": { "type": "object" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user