@shipload/sdk 1.0.0-next.36 → 1.0.0-next.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/shipload.js CHANGED
@@ -3727,11 +3727,11 @@ var recipes = [
3727
3727
  outputMass: 960000,
3728
3728
  inputs: [
3729
3729
  {
3730
- itemId: 10008,
3730
+ itemId: 10009,
3731
3731
  quantity: 300
3732
3732
  },
3733
3733
  {
3734
- itemId: 10009,
3734
+ itemId: 10006,
3735
3735
  quantity: 300
3736
3736
  }
3737
3737
  ],
@@ -3739,7 +3739,7 @@ var recipes = [
3739
3739
  {
3740
3740
  sources: [
3741
3741
  {
3742
- inputIndex: 1,
3742
+ inputIndex: 0,
3743
3743
  statIndex: 0
3744
3744
  }
3745
3745
  ]
@@ -3747,8 +3747,8 @@ var recipes = [
3747
3747
  {
3748
3748
  sources: [
3749
3749
  {
3750
- inputIndex: 0,
3751
- statIndex: 1
3750
+ inputIndex: 1,
3751
+ statIndex: 0
3752
3752
  }
3753
3753
  ]
3754
3754
  }
@@ -5129,8 +5129,8 @@ const itemMetadata = {
5129
5129
  color: '#B877FF',
5130
5130
  },
5131
5131
  10105: {
5132
- name: 'Storage',
5133
- description: 'Expands cargo capacity based on hull material quality.',
5132
+ name: 'Cargo Bay',
5133
+ description: 'Expanded cargo storage with reinforced internal holds.',
5134
5134
  color: '#8B7355',
5135
5135
  },
5136
5136
  10106: {
@@ -5144,8 +5144,8 @@ const itemMetadata = {
5144
5144
  color: '#9be4ff',
5145
5145
  },
5146
5146
  10108: {
5147
- name: 'Battery',
5148
- description: 'Extends energy capacity. Stores additional charge produced by generators, letting builds chain more high-drain actions between recharges.',
5147
+ name: 'Battery Bank',
5148
+ description: 'Stores additional charge produced by generators.',
5149
5149
  color: '#4ADBFF',
5150
5150
  },
5151
5151
  10200: {
@@ -5564,7 +5564,7 @@ function endpointInRegion(seed, R, key) {
5564
5564
  const oy = ((h[4] << 24) | (h[5] << 16) | (h[6] << 8) | h[7]) >>> 0;
5565
5565
  return { x: R.rx * WH.RSIZE + (ox % WH.RSIZE), y: R.ry * WH.RSIZE + (oy % WH.RSIZE) };
5566
5566
  }
5567
- function dist(a, b) {
5567
+ function dist$1(a, b) {
5568
5568
  return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);
5569
5569
  }
5570
5570
  function wormholeOfRegion(seed, R) {
@@ -5576,7 +5576,7 @@ function wormholeOfRegion(seed, R) {
5576
5576
  return null;
5577
5577
  const A = endpointInRegion(seed, R, key);
5578
5578
  const B = endpointInRegion(seed, P, key);
5579
- if (dist(A, B) < WH.MIN_REACH)
5579
+ if (dist$1(A, B) < WH.MIN_REACH)
5580
5580
  return null;
5581
5581
  return { A, B };
5582
5582
  }
@@ -13018,6 +13018,9 @@ const clampUint32 = (v) => Math.min(Math.max(Math.floor(v), 0), 4294967295);
13018
13018
  function applySlotMultiplier(value, outputPct) {
13019
13019
  return clampUint16(Math.floor((value * outputPct) / 100));
13020
13020
  }
13021
+ function applySlotMultiplierUint32(value, outputPct) {
13022
+ return clampUint32(Math.floor((value * outputPct) / 100));
13023
+ }
13021
13024
  function getSlotAmp(layout, slotIndex) {
13022
13025
  return layout[slotIndex]?.outputPct ?? 100;
13023
13026
  }
@@ -13090,10 +13093,10 @@ function computeLoaderCapabilities(stats) {
13090
13093
  }
13091
13094
  function computeCrafterCapabilities(stats) {
13092
13095
  const rea = stats.reactivity;
13093
- const fin = stats.fineness;
13096
+ const con = stats.conductivity;
13094
13097
  return {
13095
13098
  speed: 100 + Math.floor((rea * 4) / 5),
13096
- drain: Math.max(5, 30 - Math.floor(fin / 33)),
13099
+ drain: Math.max(5, 30 - Math.floor(con / 33)),
13097
13100
  };
13098
13101
  }
13099
13102
  function computeHaulerCapabilities(stats) {
@@ -13106,14 +13109,21 @@ function computeHaulerCapabilities(stats) {
13106
13109
  drain: Math.max(3, 15 - Math.floor(reflectivity / 80)),
13107
13110
  };
13108
13111
  }
13109
- function computeStorageCapabilities(stats, baseCapacity) {
13110
- const strength = stats.strength;
13111
- const density = stats.density;
13112
- const hardness = stats.hardness;
13113
- const cohesion = stats.cohesion;
13112
+ function computeStorageCapabilities(stats) {
13113
+ const strength = stats.strength ?? 0;
13114
+ const density = stats.density ?? 0;
13115
+ const hardness = stats.hardness ?? 0;
13116
+ const cohesion = stats.cohesion ?? 0;
13114
13117
  const statSum = strength + density + hardness + cohesion;
13115
- const capacityBonus = Math.floor((baseCapacity * (10 + Math.floor((statSum * 10) / 2997))) / 100);
13116
- return { capacityBonus };
13118
+ return { capacity: 10000000 + Math.floor((statSum * 50000000) / 3996) };
13119
+ }
13120
+ function computeBatteryCapabilities(stats) {
13121
+ const volatility = stats.volatility ?? 0;
13122
+ const thermal = stats.thermal ?? 0;
13123
+ const plasticity = stats.plasticity ?? 0;
13124
+ const insulation = stats.insulation ?? 0;
13125
+ const statSum = volatility + thermal + plasticity + insulation;
13126
+ return { capacity: 2500 + Math.floor((statSum * 7500) / 3996) };
13117
13127
  }
13118
13128
  function computeBaseCapacity(itemId, stats) {
13119
13129
  switch (itemId) {
@@ -13158,7 +13168,7 @@ function computeEntityCapabilities(stats, itemId, modules, layout) {
13158
13168
  let totalGathDrain = 0;
13159
13169
  let maxGathDepth = 0;
13160
13170
  let hasGatherer = false;
13161
- let totalStorageBonus = 0;
13171
+ let totalStorageCapacity = 0;
13162
13172
  const baseCapacity = computeBaseCapacity(itemId, stats);
13163
13173
  let installedModuleMass = 0;
13164
13174
  let totalCrafterSpeed = 0;
@@ -13170,8 +13180,7 @@ function computeEntityCapabilities(stats, itemId, modules, layout) {
13170
13180
  let hasHauler = false;
13171
13181
  let totalWarpRange = 0;
13172
13182
  let hasWarp = false;
13173
- let totalBatteryStatSum = 0;
13174
- let batteryCount = 0;
13183
+ let totalBatteryCapacity = 0;
13175
13184
  const gathererLanes = [];
13176
13185
  const crafterLanes = [];
13177
13186
  const loaderLanes = [];
@@ -13224,8 +13233,8 @@ function computeEntityCapabilities(stats, itemId, modules, layout) {
13224
13233
  });
13225
13234
  }
13226
13235
  else if (modType === MODULE_STORAGE) {
13227
- const caps = computeStorageCapabilities(decodedStats, baseCapacity);
13228
- totalStorageBonus += caps.capacityBonus;
13236
+ const caps = computeStorageCapabilities(decodedStats);
13237
+ totalStorageCapacity += applySlotMultiplierUint32(caps.capacity, amp);
13229
13238
  }
13230
13239
  else if (modType === MODULE_CRAFTER) {
13231
13240
  hasCrafter = true;
@@ -13254,22 +13263,16 @@ function computeEntityCapabilities(stats, itemId, modules, layout) {
13254
13263
  totalWarpRange += applySlotMultiplier(caps.range, amp);
13255
13264
  }
13256
13265
  else if (modType === MODULE_BATTERY) {
13257
- batteryCount++;
13258
- const vol = decodedStats.volatility ?? 0;
13259
- const thm = decodedStats.thermal ?? 0;
13260
- const pla = decodedStats.plasticity ?? 0;
13261
- const ins = decodedStats.insulation ?? 0;
13262
- totalBatteryStatSum += vol + thm + pla + ins;
13266
+ const caps = computeBatteryCapabilities(decodedStats);
13267
+ totalBatteryCapacity += applySlotMultiplierUint32(caps.capacity, amp);
13263
13268
  }
13264
13269
  }
13265
- if (hasGenerator && batteryCount > 0) {
13266
- const genCapBase = totalGenCapacity;
13267
- const bonusPctNum = 10 * batteryCount + Math.floor((totalBatteryStatSum * 10) / 2997);
13268
- totalGenCapacity += Math.floor((genCapBase * bonusPctNum) / 100);
13270
+ if (hasGenerator && totalBatteryCapacity > 0) {
13271
+ totalGenCapacity += totalBatteryCapacity;
13269
13272
  }
13270
13273
  const result = {
13271
13274
  hullmass: computeBaseHullmass$1(stats) + installedModuleMass,
13272
- capacity: baseCapacity + totalStorageBonus,
13275
+ capacity: clampUint32(baseCapacity + totalStorageCapacity),
13273
13276
  };
13274
13277
  if (hasEngine) {
13275
13278
  result.engines = { thrust: totalThrust, drain: totalEngineDrain };
@@ -13919,6 +13922,145 @@ function validateDisplayName(input, opts = {}) {
13919
13922
  return { valid: true, name };
13920
13923
  }
13921
13924
 
13925
+ const key = (c) => `${c.x},${c.y}`;
13926
+ const sameCoord = (a, b) => a.x === b.x && a.y === b.y;
13927
+ const dist = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
13928
+ const MAX_LEGS = 12;
13929
+ function planRoute(params) {
13930
+ const { origin, dest, perLegReach, graph } = params;
13931
+ const corridorSlack = params.corridorSlack ?? perLegReach;
13932
+ const nodeBudget = params.nodeBudget ?? 5000;
13933
+ const maxLegs = params.maxLegs ?? MAX_LEGS;
13934
+ if (!graph.hasSystem(dest)) {
13935
+ return { ok: false, reason: 'empty-destination' };
13936
+ }
13937
+ const straightLine = dist(origin, dest);
13938
+ const heuristic = (c) => Math.ceil(dist(c, dest) / perLegReach);
13939
+ const gScore = new Map([[key(origin), 0]]);
13940
+ const cameFrom = new Map();
13941
+ const frontier = [
13942
+ { coord: origin, g: 0, f: heuristic(origin), remaining: straightLine },
13943
+ ];
13944
+ let furthest = origin;
13945
+ let furthestRemaining = dist(origin, dest);
13946
+ let expansions = 0;
13947
+ let cappedByMaxLegs = false;
13948
+ while (frontier.length > 0) {
13949
+ let bestIdx = 0;
13950
+ for (let i = 1; i < frontier.length; i++) {
13951
+ const a = frontier[i];
13952
+ const b = frontier[bestIdx];
13953
+ if (a.f < b.f || (a.f === b.f && a.remaining < b.remaining)) {
13954
+ bestIdx = i;
13955
+ }
13956
+ }
13957
+ const current = frontier.splice(bestIdx, 1)[0];
13958
+ if (sameCoord(current.coord, dest)) {
13959
+ return reconstruct(cameFrom, origin, dest);
13960
+ }
13961
+ if (current.remaining < furthestRemaining) {
13962
+ furthestRemaining = current.remaining;
13963
+ furthest = current.coord;
13964
+ }
13965
+ if (++expansions > nodeBudget)
13966
+ break;
13967
+ for (const n of graph.nearby(current.coord, perLegReach)) {
13968
+ const inCorridor = dist(origin, n.coord) + dist(n.coord, dest) <= straightLine + corridorSlack;
13969
+ if (!inCorridor)
13970
+ continue;
13971
+ const tentativeG = current.g + 1;
13972
+ if (tentativeG > maxLegs) {
13973
+ cappedByMaxLegs = true;
13974
+ continue;
13975
+ }
13976
+ const nk = key(n.coord);
13977
+ if (tentativeG < (gScore.get(nk) ?? Infinity)) {
13978
+ gScore.set(nk, tentativeG);
13979
+ cameFrom.set(nk, current.coord);
13980
+ const remaining = dist(n.coord, dest);
13981
+ frontier.push({
13982
+ coord: n.coord,
13983
+ g: tentativeG,
13984
+ f: tentativeG + Math.ceil(remaining / perLegReach),
13985
+ remaining,
13986
+ });
13987
+ }
13988
+ }
13989
+ }
13990
+ if (cappedByMaxLegs) {
13991
+ return {
13992
+ ok: false,
13993
+ reason: 'max-legs',
13994
+ furthest,
13995
+ partialWaypoints: reconstructWaypoints(cameFrom, origin, furthest),
13996
+ };
13997
+ }
13998
+ return {
13999
+ ok: false,
14000
+ reason: 'no-path',
14001
+ furthest,
14002
+ partialWaypoints: reconstructWaypoints(cameFrom, origin, furthest),
14003
+ };
14004
+ }
14005
+ function reconstructWaypoints(cameFrom, origin, target) {
14006
+ if (sameCoord(target, origin))
14007
+ return [];
14008
+ const path = [target];
14009
+ let cur = target;
14010
+ while (!sameCoord(cur, origin)) {
14011
+ const prev = cameFrom.get(key(cur));
14012
+ if (!prev)
14013
+ break;
14014
+ path.unshift(prev);
14015
+ cur = prev;
14016
+ }
14017
+ return path.slice(1);
14018
+ }
14019
+ function reconstruct(cameFrom, origin, dest) {
14020
+ const path = [dest];
14021
+ let cur = dest;
14022
+ let totalDistance = 0;
14023
+ while (!sameCoord(cur, origin)) {
14024
+ const prev = cameFrom.get(key(cur));
14025
+ if (!prev)
14026
+ break;
14027
+ totalDistance += dist(prev, cur);
14028
+ path.unshift(prev);
14029
+ cur = prev;
14030
+ }
14031
+ const waypoints = path.slice(1);
14032
+ return { ok: true, waypoints, legs: waypoints.length, totalDistance };
14033
+ }
14034
+ function sdkSystemGraph(seed) {
14035
+ const s = antelope.Checksum256.from(seed);
14036
+ return {
14037
+ hasSystem: (c) => hasSystem(s, { x: c.x, y: c.y }),
14038
+ nearby: (c, reachTiles) => findNearbyPlanets(s, { x: c.x, y: c.y }, reachTiles * PRECISION$1)
14039
+ .map((d) => ({
14040
+ coord: { x: Number(d.destination.x), y: Number(d.destination.y) },
14041
+ dist: Number(d.distance) / PRECISION$1,
14042
+ }))
14043
+ .filter((n) => !(n.coord.x === c.x && n.coord.y === c.y)),
14044
+ };
14045
+ }
14046
+
14047
+ function computePerLegReach(s, haulCount = 0) {
14048
+ const capacity = s.generator?.capacity;
14049
+ const drain = s.engines?.drain;
14050
+ if (capacity === undefined || drain === undefined || drain === 0n) {
14051
+ throw new Error('entity has no usable engine/generator (cannot compute per-leg reach)');
14052
+ }
14053
+ const haulDrain = s.hauler && haulCount > 0 ? s.hauler.drain * BigInt(haulCount) : 0n;
14054
+ return Number(capacity) / Number(drain + haulDrain);
14055
+ }
14056
+ function computeGroupPerLegReach(participants, haulCount) {
14057
+ const movers = participants.filter((p) => p.engines !== undefined && p.engines.drain !== 0n);
14058
+ if (movers.length === 0) {
14059
+ throw new Error('group has no moving entity (cannot compute per-leg reach)');
14060
+ }
14061
+ return Math.min(...movers.map((p) => computePerLegReach(p, haulCount)));
14062
+ }
14063
+
13922
14064
  function idiv(a, b) {
13923
14065
  return Math.floor(a / b);
13924
14066
  }
@@ -13957,6 +14099,8 @@ const computeHaulerCapacity = (fin) => Math.max(1, 1 + idiv(fin, 400));
13957
14099
  const computeHaulerEfficiency = (con) => 2000 + con * 6;
13958
14100
  const computeHaulerDrain$1 = (com) => Math.max(3, 15 - idiv(com, 80));
13959
14101
  const computeWarpRange = (stat) => 100 + stat * 3;
14102
+ const computeCargoBayCapacity = (strength, density, hardness, cohesion) => 10000000 + idiv((strength + density + hardness + cohesion) * 50000000, 3996);
14103
+ const computeBatteryBankCapacity = (volatility, thermal, plasticity, insulation) => 2500 + idiv((volatility + thermal + plasticity + insulation) * 7500, 3996);
13960
14104
  function entityDisplayName(itemId) {
13961
14105
  switch (itemId) {
13962
14106
  case ITEM_SHIP_T1_PACKED:
@@ -13988,11 +14132,13 @@ function moduleDisplayName(itemId) {
13988
14132
  case ITEM_CRAFTER_T1:
13989
14133
  return 'Crafter';
13990
14134
  case ITEM_STORAGE_T1:
13991
- return 'Storage';
14135
+ return 'Cargo Bay';
13992
14136
  case ITEM_HAULER_T1:
13993
14137
  return 'Hauler';
13994
14138
  case ITEM_WARP_T1:
13995
14139
  return 'Warp';
14140
+ case ITEM_BATTERY_T1:
14141
+ return 'Battery Bank';
13996
14142
  default:
13997
14143
  return 'Module';
13998
14144
  }
@@ -14034,17 +14180,16 @@ function formatModuleLine(slot, itemId, stats) {
14034
14180
  }
14035
14181
  case MODULE_CRAFTER: {
14036
14182
  const rea = decodeStat(stats, 0);
14037
- const com = decodeStat(stats, 1);
14038
- out += ` Speed ${computeCrafterSpeed(rea)} Drain ${computeCrafterDrain(com)}`;
14183
+ const con = decodeStat(stats, 1);
14184
+ out += ` Speed ${computeCrafterSpeed(rea)} Drain ${computeCrafterDrain(con)}`;
14039
14185
  break;
14040
14186
  }
14041
14187
  case MODULE_STORAGE: {
14042
14188
  const str = decodeStat(stats, 0);
14043
- const fin = decodeStat(stats, 2);
14044
- const sat = decodeStat(stats, 3);
14045
- const sum = str + fin + sat;
14046
- const pct = 10 + idiv(sum * 10, 2997);
14047
- out += ` +${pct}% capacity`;
14189
+ const den = decodeStat(stats, 1);
14190
+ const hrd = decodeStat(stats, 2);
14191
+ const com = decodeStat(stats, 3);
14192
+ out += ` Cargo Capacity ${computeCargoBayCapacity(str, den, hrd, com)}`;
14048
14193
  break;
14049
14194
  }
14050
14195
  case MODULE_HAULER: {
@@ -14059,6 +14204,14 @@ function formatModuleLine(slot, itemId, stats) {
14059
14204
  out += ` Range ${computeWarpRange(stat)}`;
14060
14205
  break;
14061
14206
  }
14207
+ case MODULE_BATTERY: {
14208
+ const vol = decodeStat(stats, 0);
14209
+ const thm = decodeStat(stats, 1);
14210
+ const pla = decodeStat(stats, 2);
14211
+ const ins = decodeStat(stats, 3);
14212
+ out += ` Energy Capacity ${computeBatteryBankCapacity(vol, thm, pla, ins)}`;
14213
+ break;
14214
+ }
14062
14215
  }
14063
14216
  return out;
14064
14217
  }
@@ -15381,19 +15534,21 @@ const capabilityNames = [
15381
15534
  'Crafter',
15382
15535
  'Launch',
15383
15536
  'Hauler',
15384
- 'Battery',
15385
15537
  ];
15386
15538
  const capabilityAttributes = [
15387
15539
  { capability: 'Hull', attribute: 'mass', description: 'Total mass of the hull' },
15388
- { capability: 'Storage', attribute: 'capacity', description: 'Maximum mass that can be stored' },
15389
15540
  {
15390
15541
  capability: 'Storage',
15391
- attribute: 'bonus',
15392
- description: 'Capacity bonus added by an installed Storage module',
15542
+ attribute: 'capacity',
15543
+ description: 'Cargo capacity added by hulls and installed Cargo Bay modules',
15393
15544
  },
15394
15545
  { capability: 'Movement', attribute: 'thrust', description: 'Propulsion force' },
15395
15546
  { capability: 'Movement', attribute: 'drain', description: 'Energy consumed per movement' },
15396
- { capability: 'Energy', attribute: 'capacity', description: 'Maximum energy storage' },
15547
+ {
15548
+ capability: 'Energy',
15549
+ attribute: 'capacity',
15550
+ description: 'Energy capacity from Generators and installed Battery Bank modules',
15551
+ },
15397
15552
  { capability: 'Energy', attribute: 'recharge', description: 'Energy regeneration rate' },
15398
15553
  { capability: 'Loader', attribute: 'mass', description: 'Weight of the loader unit itself' },
15399
15554
  { capability: 'Loader', attribute: 'thrust', description: 'Loading speed/force' },
@@ -15431,11 +15586,6 @@ const capabilityAttributes = [
15431
15586
  attribute: 'drain',
15432
15587
  description: 'Energy consumed per target during haul-beam operation',
15433
15588
  },
15434
- {
15435
- capability: 'Battery',
15436
- attribute: 'bonus',
15437
- description: 'Energy capacity bonus added by an installed Battery module',
15438
- },
15439
15589
  ];
15440
15590
  const invertedAttributes = new Set(['drain', 'mass']);
15441
15591
  function isInvertedAttribute(attribute) {
@@ -15476,10 +15626,10 @@ const SLOT_FORMULAS = {
15476
15626
  1: { capability: 'Crafter', attribute: 'drain' },
15477
15627
  },
15478
15628
  storage: {
15479
- 0: { capability: 'Storage', attribute: 'bonus' },
15480
- 1: { capability: 'Storage', attribute: 'bonus' },
15481
- 2: { capability: 'Storage', attribute: 'bonus' },
15482
- 3: { capability: 'Storage', attribute: 'bonus' },
15629
+ 0: { capability: 'Storage', attribute: 'capacity' },
15630
+ 1: { capability: 'Storage', attribute: 'capacity' },
15631
+ 2: { capability: 'Storage', attribute: 'capacity' },
15632
+ 3: { capability: 'Storage', attribute: 'capacity' },
15483
15633
  },
15484
15634
  hauler: {
15485
15635
  0: { capability: 'Hauler', attribute: 'capacity' },
@@ -15490,10 +15640,10 @@ const SLOT_FORMULAS = {
15490
15640
  0: { capability: 'Warp', attribute: 'range' },
15491
15641
  },
15492
15642
  battery: {
15493
- 0: { capability: 'Battery', attribute: 'bonus' },
15494
- 1: { capability: 'Battery', attribute: 'bonus' },
15495
- 2: { capability: 'Battery', attribute: 'bonus' },
15496
- 3: { capability: 'Battery', attribute: 'bonus' },
15643
+ 0: { capability: 'Energy', attribute: 'capacity' },
15644
+ 1: { capability: 'Energy', attribute: 'capacity' },
15645
+ 2: { capability: 'Energy', attribute: 'capacity' },
15646
+ 3: { capability: 'Energy', attribute: 'capacity' },
15497
15647
  },
15498
15648
  'ship-t1': ENTITY_HULL_SLOTS,
15499
15649
  'container-t1': ENTITY_HULL_SLOTS,
@@ -15737,7 +15887,7 @@ function resolveComponent(id, stats) {
15737
15887
  stats: resolvedStats,
15738
15888
  };
15739
15889
  }
15740
- function computeCapabilityGroup(moduleType, stats, tier) {
15890
+ function computeCapabilityGroup(moduleType, stats, tier, outputPct = 100) {
15741
15891
  switch (moduleType) {
15742
15892
  case MODULE_ENGINE: {
15743
15893
  const caps = computeEngineCapabilities(stats);
@@ -15803,13 +15953,28 @@ function computeCapabilityGroup(moduleType, stats, tier) {
15803
15953
  };
15804
15954
  }
15805
15955
  case MODULE_STORAGE: {
15806
- const str = stats.strength;
15807
- const den = stats.density;
15808
- const hrd = stats.hardness;
15809
- const com = stats.cohesion;
15810
- const statSum = str + den + hrd + com;
15811
- const pct = 10 + Math.floor((statSum * 10) / 2997);
15812
- return { capability: 'Storage', attributes: [{ label: 'Capacity Bonus', value: pct }] };
15956
+ const caps = computeStorageCapabilities(stats);
15957
+ return {
15958
+ capability: 'Storage',
15959
+ attributes: [
15960
+ {
15961
+ label: 'Cargo Capacity',
15962
+ value: applySlotMultiplierUint32(caps.capacity, outputPct),
15963
+ },
15964
+ ],
15965
+ };
15966
+ }
15967
+ case MODULE_BATTERY: {
15968
+ const caps = computeBatteryCapabilities(stats);
15969
+ return {
15970
+ capability: 'Energy',
15971
+ attributes: [
15972
+ {
15973
+ label: 'Energy Capacity',
15974
+ value: applySlotMultiplierUint32(caps.capacity, outputPct),
15975
+ },
15976
+ ],
15977
+ };
15813
15978
  }
15814
15979
  default:
15815
15980
  return undefined;
@@ -15894,9 +16059,10 @@ function resolveEntity(id, stats, modules) {
15894
16059
  catch {
15895
16060
  modName = itemMetadata[modItemId]?.name ?? 'Module';
15896
16061
  }
15897
- const group = computeCapabilityGroup(modType, decodedStats, modTier);
16062
+ const group = computeCapabilityGroup(modType, decodedStats, modTier, slot.outputPct);
15898
16063
  return {
15899
16064
  name: modName,
16065
+ capability: group?.capability,
15900
16066
  installed: true,
15901
16067
  attributes: group?.attributes,
15902
16068
  };
@@ -15980,9 +16146,15 @@ const TEMPLATES = {
15980
16146
  },
15981
16147
  storage: {
15982
16148
  id: 'module.storage.description',
15983
- template: 'boosts cargo capacity by {bonus}%',
15984
- params: [['bonus', 'Capacity Bonus']],
15985
- highlightKeys: ['bonus'],
16149
+ template: 'adds {capacity} cargo capacity',
16150
+ params: [['capacity', 'Cargo Capacity']],
16151
+ highlightKeys: ['capacity'],
16152
+ },
16153
+ energy: {
16154
+ id: 'module.energy-capacity.description',
16155
+ template: 'adds {capacity} energy capacity',
16156
+ params: [['capacity', 'Energy Capacity']],
16157
+ highlightKeys: ['capacity'],
15986
16158
  },
15987
16159
  hauler: {
15988
16160
  id: 'module.hauler.description',
@@ -16024,9 +16196,12 @@ function describeModuleForItem(resolved) {
16024
16196
  return describeModule({ capability: group.capability, attributes: group.attributes });
16025
16197
  }
16026
16198
  function describeModuleForSlot(slot) {
16027
- if (!slot.installed || !slot.name || !slot.attributes)
16199
+ if (!slot.installed || !slot.attributes)
16028
16200
  return null;
16029
- return describeModule({ capability: slot.name, attributes: slot.attributes });
16201
+ const capability = slot.capability ?? slot.name;
16202
+ if (!capability)
16203
+ return null;
16204
+ return describeModule({ capability, attributes: slot.attributes });
16030
16205
  }
16031
16206
  function renderDescription(desc, options) {
16032
16207
  const translate = options?.translate ?? ((_id, fallback) => fallback);
@@ -16181,11 +16356,11 @@ function buildModuleImmutable(itemId, quantity, stats, originX, originY) {
16181
16356
  }
16182
16357
  case MODULE_CRAFTER: {
16183
16358
  const rea = decodeStat(stats, 0);
16184
- const fin = decodeStat(stats, 1);
16359
+ const con = decodeStat(stats, 1);
16185
16360
  base.push({ first: 'reactivity', second: ['uint16', rea] });
16186
- base.push({ first: 'fineness', second: ['uint16', fin] });
16361
+ base.push({ first: 'conductivity', second: ['uint16', con] });
16187
16362
  base.push({ first: 'speed', second: ['uint16', computeCrafterSpeed(rea)] });
16188
- base.push({ first: 'drain', second: ['uint16', computeCrafterDrain(fin)] });
16363
+ base.push({ first: 'drain', second: ['uint16', computeCrafterDrain(con)] });
16189
16364
  break;
16190
16365
  }
16191
16366
  case MODULE_STORAGE: {
@@ -16193,14 +16368,28 @@ function buildModuleImmutable(itemId, quantity, stats, originX, originY) {
16193
16368
  const den = decodeStat(stats, 1);
16194
16369
  const hrd = decodeStat(stats, 2);
16195
16370
  const com = decodeStat(stats, 3);
16196
- const sum = str + den + hrd + com;
16197
16371
  base.push({ first: 'strength', second: ['uint16', str] });
16198
16372
  base.push({ first: 'density', second: ['uint16', den] });
16199
16373
  base.push({ first: 'hardness', second: ['uint16', hrd] });
16200
16374
  base.push({ first: 'cohesion', second: ['uint16', com] });
16201
16375
  base.push({
16202
- first: 'capacity_bonus_pct',
16203
- second: ['uint16', 10 + Math.floor((sum * 10) / 2997)],
16376
+ first: 'capacity',
16377
+ second: ['uint32', computeCargoBayCapacity(str, den, hrd, com)],
16378
+ });
16379
+ break;
16380
+ }
16381
+ case MODULE_BATTERY: {
16382
+ const vol = decodeStat(stats, 0);
16383
+ const thm = decodeStat(stats, 1);
16384
+ const pla = decodeStat(stats, 2);
16385
+ const ins = decodeStat(stats, 3);
16386
+ base.push({ first: 'volatility', second: ['uint16', vol] });
16387
+ base.push({ first: 'thermal', second: ['uint16', thm] });
16388
+ base.push({ first: 'plasticity', second: ['uint16', pla] });
16389
+ base.push({ first: 'insulation', second: ['uint16', ins] });
16390
+ base.push({
16391
+ first: 'capacity',
16392
+ second: ['uint32', computeBatteryBankCapacity(vol, thm, pla, ins)],
16204
16393
  });
16205
16394
  break;
16206
16395
  }
@@ -16286,6 +16475,8 @@ var index = /*#__PURE__*/Object.freeze({
16286
16475
  computeHaulerEfficiency: computeHaulerEfficiency,
16287
16476
  computeHaulerDrain: computeHaulerDrain$1,
16288
16477
  computeWarpRange: computeWarpRange,
16478
+ computeCargoBayCapacity: computeCargoBayCapacity,
16479
+ computeBatteryBankCapacity: computeBatteryBankCapacity,
16289
16480
  entityDisplayName: entityDisplayName,
16290
16481
  moduleDisplayName: moduleDisplayName,
16291
16482
  formatModuleLine: formatModuleLine,
@@ -16628,6 +16819,7 @@ exports.LOCATION_MAX_DEPTH = LOCATION_MAX_DEPTH;
16628
16819
  exports.LOCATION_MIN_DEPTH = LOCATION_MIN_DEPTH;
16629
16820
  exports.Location = Location;
16630
16821
  exports.LocationsManager = LocationsManager;
16822
+ exports.MAX_LEGS = MAX_LEGS;
16631
16823
  exports.MAX_ORBITAL_ALTITUDE = MAX_ORBITAL_ALTITUDE;
16632
16824
  exports.MAX_STARS_PER_STAT = MAX_STARS_PER_STAT;
16633
16825
  exports.MAX_STAR_RATING = MAX_STAR_RATING;
@@ -16789,6 +16981,7 @@ exports.computeBaseCapacity = computeBaseCapacity;
16789
16981
  exports.computeBaseCapacityShip = computeBaseCapacityShip;
16790
16982
  exports.computeBaseCapacityWarehouse = computeBaseCapacityWarehouse;
16791
16983
  exports.computeBaseHullmass = computeBaseHullmass;
16984
+ exports.computeBatteryCapabilities = computeBatteryCapabilities;
16792
16985
  exports.computeComponentStats = computeComponentStats;
16793
16986
  exports.computeContainerCapabilities = computeContainerCapabilities;
16794
16987
  exports.computeContainerT2Capabilities = computeContainerT2Capabilities;
@@ -16808,6 +17001,7 @@ exports.computeGathererYield = computeGathererYield;
16808
17001
  exports.computeGeneratorCap = computeGeneratorCap;
16809
17002
  exports.computeGeneratorCapabilities = computeGeneratorCapabilities;
16810
17003
  exports.computeGeneratorRech = computeGeneratorRech;
17004
+ exports.computeGroupPerLegReach = computeGroupPerLegReach;
16811
17005
  exports.computeHaulPenalty = computeHaulPenalty;
16812
17006
  exports.computeHaulerCapabilities = computeHaulerCapabilities;
16813
17007
  exports.computeHaulerCapacity = computeHaulerCapacity;
@@ -16818,6 +17012,7 @@ exports.computeLoaderCapabilities = computeLoaderCapabilities;
16818
17012
  exports.computeLoaderMass = computeLoaderMass;
16819
17013
  exports.computeLoaderThrust = computeLoaderThrust;
16820
17014
  exports.computeNftImageUrl = computeNftImageUrl;
17015
+ exports.computePerLegReach = computePerLegReach;
16821
17016
  exports.computeShipHullCapabilities = computeShipHullCapabilities;
16822
17017
  exports.computeStorageCapabilities = computeStorageCapabilities;
16823
17018
  exports.computeWarehouseHullCapabilities = computeWarehouseHullCapabilities;
@@ -16976,6 +17171,7 @@ exports.parseWireEntity = parseWireEntity;
16976
17171
  exports.partnerRegion = partnerRegion;
16977
17172
  exports.planParallelGather = planParallelGather;
16978
17173
  exports.planParallelTransfer = planParallelTransfer;
17174
+ exports.planRoute = planRoute;
16979
17175
  exports.projectEntity = projectEntity;
16980
17176
  exports.projectEntityAt = projectEntityAt;
16981
17177
  exports.projectRemainingAt = projectRemainingAt;
@@ -16999,6 +17195,7 @@ exports.rollupGatherer = rollupGatherer;
16999
17195
  exports.rollupLoaders = rollupLoaders;
17000
17196
  exports.rotation = rotation;
17001
17197
  exports.schedule = schedule;
17198
+ exports.sdkSystemGraph = sdkSystemGraph;
17002
17199
  exports.selectGatherLane = selectGatherLane;
17003
17200
  exports.setSubscriptionsDebug = setSubscriptionsDebug;
17004
17201
  exports.stackKey = stackKey;