@shipload/sdk 2.0.0-rc11 → 2.0.0-rc13
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.d.ts +70 -23
- package/lib/shipload.js +2365 -2117
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +2348 -2117
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/storage.ts +92 -2
- package/src/data/categories.ts +1 -1
- package/src/derivation/crafting.ts +76 -0
- package/src/derivation/index.ts +3 -1
- package/src/derivation/resources.ts +1 -7
- package/src/derivation/stratum.ts +9 -11
- package/src/derivation/tiers.ts +54 -0
- package/src/errors.ts +5 -0
- package/src/index-module.ts +12 -4
- package/src/market/items.ts +69 -10
- package/src/scheduling/projection.ts +95 -75
- package/src/types.ts +2 -1
- package/src/utils/system.ts +8 -4
package/lib/shipload.m.js
CHANGED
|
@@ -2132,6 +2132,11 @@ const SHIP_CARGO_NOT_LOADED = 'Cannot unload cargo that is not loaded.';
|
|
|
2132
2132
|
const WAREHOUSE_NOT_FOUND = 'Cannot find warehouse for given id.';
|
|
2133
2133
|
const WAREHOUSE_ALREADY_AT_LOCATION = 'Warehouse already exists at this location.';
|
|
2134
2134
|
const WAREHOUSE_CAPACITY_EXCEEDED = 'Warehouse capacity would be exceeded.';
|
|
2135
|
+
const ENTITY_CAPACITY_EXCEEDED = 'Entity cargo capacity would be exceeded.';
|
|
2136
|
+
const RECIPE_INPUTS_INSUFFICIENT = 'Insufficient inputs for recipe.';
|
|
2137
|
+
const RECIPE_INPUTS_INVALID = 'Input cargo does not match recipe requirements.';
|
|
2138
|
+
const RECIPE_INPUTS_EXCESS = 'Provided inputs exceed recipe requirements.';
|
|
2139
|
+
const RECIPE_INPUTS_MIXED = 'All stacks for a recipe input must be the same resource.';
|
|
2135
2140
|
|
|
2136
2141
|
const PRECISION$1 = 10000;
|
|
2137
2142
|
const CRAFT_ENERGY_DIVISOR = 150000;
|
|
@@ -2155,7 +2160,8 @@ var TaskType;
|
|
|
2155
2160
|
TaskType[TaskType["WARP"] = 6] = "WARP";
|
|
2156
2161
|
TaskType[TaskType["CRAFT"] = 7] = "CRAFT";
|
|
2157
2162
|
TaskType[TaskType["DEPLOY"] = 8] = "DEPLOY";
|
|
2158
|
-
TaskType[TaskType["
|
|
2163
|
+
TaskType[TaskType["WRAP"] = 9] = "WRAP";
|
|
2164
|
+
TaskType[TaskType["UNWRAP"] = 10] = "UNWRAP";
|
|
2159
2165
|
})(TaskType || (TaskType = {}));
|
|
2160
2166
|
var LocationType;
|
|
2161
2167
|
(function (LocationType) {
|
|
@@ -2256,7 +2262,7 @@ const DEPTH_THRESHOLD_T4 = 30000;
|
|
|
2256
2262
|
const DEPTH_THRESHOLD_T5 = 55000;
|
|
2257
2263
|
const LOCATION_MIN_DEPTH = 500;
|
|
2258
2264
|
const LOCATION_MAX_DEPTH = 65535;
|
|
2259
|
-
const YIELD_THRESHOLD = Math.floor(0.
|
|
2265
|
+
const YIELD_THRESHOLD = Math.floor(0.001 * 0xffffffff);
|
|
2260
2266
|
const PLANET_SUBTYPE_GAS_GIANT = 0;
|
|
2261
2267
|
const PLANET_SUBTYPE_ROCKY = 1;
|
|
2262
2268
|
const PLANET_SUBTYPE_TERRESTRIAL = 2;
|
|
@@ -2374,12 +2380,6 @@ function getEligibleResources(locationType, subtype, stratum) {
|
|
|
2374
2380
|
return stratum >= threshold;
|
|
2375
2381
|
});
|
|
2376
2382
|
}
|
|
2377
|
-
function depthScaleFactor(stratum) {
|
|
2378
|
-
if (stratum <= 1)
|
|
2379
|
-
return 1.0;
|
|
2380
|
-
const logScale = Math.log(stratum) / Math.log(65535);
|
|
2381
|
-
return 1.0 + logScale * 2.0;
|
|
2382
|
-
}
|
|
2383
2383
|
|
|
2384
2384
|
function deriveLocationSize(loc) {
|
|
2385
2385
|
if (loc.type.toNumber() === LocationType.EMPTY)
|
|
@@ -4568,10 +4568,14 @@ function isGatherableLocation(locationType) {
|
|
|
4568
4568
|
}
|
|
4569
4569
|
function getLocationTypeName(type) {
|
|
4570
4570
|
switch (type) {
|
|
4571
|
-
case LocationType.EMPTY:
|
|
4572
|
-
|
|
4573
|
-
case LocationType.
|
|
4574
|
-
|
|
4571
|
+
case LocationType.EMPTY:
|
|
4572
|
+
return 'Empty';
|
|
4573
|
+
case LocationType.PLANET:
|
|
4574
|
+
return 'Planet';
|
|
4575
|
+
case LocationType.ASTEROID:
|
|
4576
|
+
return 'Asteroid';
|
|
4577
|
+
case LocationType.NEBULA:
|
|
4578
|
+
return 'Nebula';
|
|
4575
4579
|
}
|
|
4576
4580
|
}
|
|
4577
4581
|
function uint16(hash, offset) {
|
|
@@ -4901,1930 +4905,48 @@ var itemsData = [
|
|
|
4901
4905
|
}
|
|
4902
4906
|
];
|
|
4903
4907
|
|
|
4904
|
-
const
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
const
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
return items;
|
|
4924
|
-
}
|
|
4925
|
-
|
|
4926
|
-
function calc_orbital_altitude(mass) {
|
|
4927
|
-
if (mass <= BASE_ORBITAL_MASS) {
|
|
4928
|
-
return MIN_ORBITAL_ALTITUDE;
|
|
4929
|
-
}
|
|
4930
|
-
const ratio = mass / BASE_ORBITAL_MASS;
|
|
4931
|
-
const capRatio = 10.0;
|
|
4932
|
-
let scale = Math.log(ratio) / Math.log(capRatio);
|
|
4933
|
-
scale = Math.min(scale, 1.0);
|
|
4934
|
-
return MIN_ORBITAL_ALTITUDE + Math.floor((MAX_ORBITAL_ALTITUDE - MIN_ORBITAL_ALTITUDE) * scale);
|
|
4935
|
-
}
|
|
4936
|
-
function distanceBetweenCoordinates(origin, destination) {
|
|
4937
|
-
return distanceBetweenPoints(origin.x, origin.y, destination.x, destination.y);
|
|
4938
|
-
}
|
|
4939
|
-
function distanceBetweenPoints(x1, y1, x2, y2) {
|
|
4940
|
-
const x = Math.pow(x1 - x2, 2);
|
|
4941
|
-
const y = Math.pow(y1 - y2, 2);
|
|
4942
|
-
return UInt64.from(Math.sqrt(x + y) * PRECISION$1);
|
|
4943
|
-
}
|
|
4944
|
-
function lerp(origin, destination, time) {
|
|
4945
|
-
return {
|
|
4946
|
-
x: (1 - time) * Number(origin.x) + time * Number(destination.x),
|
|
4947
|
-
y: (1 - time) * Number(origin.y) + time * Number(destination.y),
|
|
4948
|
-
};
|
|
4949
|
-
}
|
|
4950
|
-
function rotation(origin, destination) {
|
|
4951
|
-
return Math.atan2(destination.y - origin.y, destination.x - origin.x) * (180 / Math.PI) + 90;
|
|
4952
|
-
}
|
|
4953
|
-
function findNearbyPlanets(seed, origin, maxDistance = 20 * PRECISION$1) {
|
|
4954
|
-
const nearbySystems = [];
|
|
4955
|
-
const max = UInt64.from(maxDistance / PRECISION$1);
|
|
4956
|
-
const xMin = Int64.from(origin.x).subtracting(max);
|
|
4957
|
-
const xMax = Int64.from(origin.x).adding(max);
|
|
4958
|
-
const yMin = Int64.from(origin.y).subtracting(max);
|
|
4959
|
-
const yMax = Int64.from(origin.y).adding(max);
|
|
4960
|
-
for (let x = Number(xMin); x <= Number(xMax); x++) {
|
|
4961
|
-
for (let y = Number(yMin); y <= Number(yMax); y++) {
|
|
4962
|
-
const samePlace = x === Number(origin.x) && y === Number(origin.y);
|
|
4963
|
-
if (!samePlace) {
|
|
4964
|
-
const distance = distanceBetweenPoints(origin.x, origin.y, x, y);
|
|
4965
|
-
if (Number(distance) <= Number(maxDistance)) {
|
|
4966
|
-
const system = hasSystem(seed, { x, y });
|
|
4967
|
-
if (system) {
|
|
4968
|
-
nearbySystems.push({ origin, destination: { x, y }, distance });
|
|
4969
|
-
}
|
|
4970
|
-
}
|
|
4971
|
-
}
|
|
4972
|
-
}
|
|
4973
|
-
}
|
|
4974
|
-
return nearbySystems;
|
|
4975
|
-
}
|
|
4976
|
-
function calc_rechargetime(capacity, energy, recharge) {
|
|
4977
|
-
const cap = UInt32.from(capacity);
|
|
4978
|
-
const eng = UInt32.from(energy);
|
|
4979
|
-
if (eng.gte(cap))
|
|
4980
|
-
return UInt32.zero;
|
|
4981
|
-
return cap.subtracting(eng).dividing(recharge);
|
|
4982
|
-
}
|
|
4983
|
-
function calc_ship_rechargetime(ship) {
|
|
4984
|
-
if (!ship.generator)
|
|
4985
|
-
return UInt32.from(0);
|
|
4986
|
-
return calc_rechargetime(ship.generator.capacity, ship.energy ?? UInt16.from(0), ship.generator.recharge);
|
|
4987
|
-
}
|
|
4988
|
-
function calc_flighttime(distance, acceleration) {
|
|
4989
|
-
return UInt32.from(2 * Math.sqrt(Number(distance) / acceleration));
|
|
4990
|
-
}
|
|
4991
|
-
function calc_loader_flighttime(ship, mass, altitude) {
|
|
4992
|
-
const z = altitude ?? ship.coordinates.z?.toNumber() ?? calc_orbital_altitude(Number(mass));
|
|
4993
|
-
return calc_flighttime(z, calc_loader_acceleration(ship, mass));
|
|
4994
|
-
}
|
|
4995
|
-
function calc_loader_acceleration(ship, mass) {
|
|
4996
|
-
const thrust = ship.loaders ? Number(ship.loaders.thrust) : 0;
|
|
4997
|
-
const loaderMass = ship.loaders ? Number(ship.loaders.mass) : 0;
|
|
4998
|
-
return calc_acceleration(thrust, Number(mass) + loaderMass);
|
|
4999
|
-
}
|
|
5000
|
-
function calc_ship_flighttime(ship, mass, distance) {
|
|
5001
|
-
const acceleration = calc_ship_acceleration(ship, mass);
|
|
5002
|
-
return calc_flighttime(distance, acceleration);
|
|
5003
|
-
}
|
|
5004
|
-
function calc_ship_acceleration(ship, mass) {
|
|
5005
|
-
const thrust = ship.engines ? Number(ship.engines.thrust) : 0;
|
|
5006
|
-
return calc_acceleration(thrust, Number(mass));
|
|
5007
|
-
}
|
|
5008
|
-
function calc_acceleration(thrust, mass) {
|
|
5009
|
-
return (thrust / mass) * PRECISION$1;
|
|
5010
|
-
}
|
|
5011
|
-
function calc_ship_mass(ship, cargos) {
|
|
5012
|
-
const mass = UInt64.from(0);
|
|
5013
|
-
mass.add(ship.hullmass);
|
|
5014
|
-
if (ship.loaders && ship.loaders.quantity.gt(UInt32.zero)) {
|
|
5015
|
-
mass.add(ship.loaders.mass.multiplying(ship.loaders.quantity));
|
|
5016
|
-
}
|
|
5017
|
-
for (const cargo of cargos) {
|
|
5018
|
-
mass.add(getItem(cargo.item_id).mass.multiplying(cargo.quantity));
|
|
5019
|
-
}
|
|
5020
|
-
return mass;
|
|
5021
|
-
}
|
|
5022
|
-
function calc_energyusage(distance, drain) {
|
|
5023
|
-
return UInt64.from(distance).dividing(PRECISION$1).multiplying(drain);
|
|
5024
|
-
}
|
|
5025
|
-
function calculateTransferTime(ship, cargos, quantities) {
|
|
5026
|
-
let mass = UInt64.from(0);
|
|
5027
|
-
for (const cargo of cargos) {
|
|
5028
|
-
const qty = quantities?.get(Number(cargo.item_id)) ?? 0;
|
|
5029
|
-
if (qty > 0) {
|
|
5030
|
-
const good_mass = getItem(cargo.item_id).mass;
|
|
5031
|
-
const cargo_mass = good_mass.multiplying(qty);
|
|
5032
|
-
mass = UInt64.from(mass).adding(cargo_mass);
|
|
5033
|
-
}
|
|
5034
|
-
}
|
|
5035
|
-
if (mass.equals(UInt64.zero)) {
|
|
5036
|
-
return UInt32.from(0);
|
|
5037
|
-
}
|
|
5038
|
-
if (!ship.loaders)
|
|
5039
|
-
return UInt32.from(0);
|
|
5040
|
-
mass = UInt64.from(mass).adding(ship.loaders.mass);
|
|
5041
|
-
const transfer_time = calc_loader_flighttime(ship, mass);
|
|
5042
|
-
return transfer_time.dividing(ship.loaders.quantity);
|
|
5043
|
-
}
|
|
5044
|
-
function calculateRefuelingTime(ship) {
|
|
5045
|
-
return calc_ship_rechargetime(ship);
|
|
5046
|
-
}
|
|
5047
|
-
function calculateFlightTime(ship, cargos, distance) {
|
|
5048
|
-
const mass = calc_ship_mass(ship, cargos);
|
|
5049
|
-
return calc_ship_flighttime(ship, mass, distance);
|
|
5050
|
-
}
|
|
5051
|
-
function calculateLoadTimeBreakdown(ship, cargos, loadQuantities, unloadQuantities) {
|
|
5052
|
-
let mass_unload = UInt64.from(0);
|
|
5053
|
-
let mass_load = UInt64.from(0);
|
|
5054
|
-
for (const cargo of cargos) {
|
|
5055
|
-
const goodId = Number(cargo.item_id);
|
|
5056
|
-
const loadQty = loadQuantities?.get(goodId) ?? 0;
|
|
5057
|
-
const unloadQty = unloadQuantities?.get(goodId) ?? 0;
|
|
5058
|
-
if (loadQty > 0 || unloadQty > 0) {
|
|
5059
|
-
const good = getItem(cargo.item_id);
|
|
5060
|
-
if (loadQty > 0) {
|
|
5061
|
-
const cargo_mass = good.mass.multiplying(loadQty);
|
|
5062
|
-
mass_load = UInt64.from(mass_load).adding(cargo_mass);
|
|
5063
|
-
}
|
|
5064
|
-
if (unloadQty > 0) {
|
|
5065
|
-
const cargo_mass = good.mass.multiplying(unloadQty);
|
|
5066
|
-
mass_unload = UInt64.from(mass_unload).adding(cargo_mass);
|
|
5067
|
-
}
|
|
5068
|
-
}
|
|
5069
|
-
}
|
|
5070
|
-
let unloadTime = 0;
|
|
5071
|
-
let loadTime = 0;
|
|
5072
|
-
if (mass_unload.gt(UInt64.zero) && ship.loaders) {
|
|
5073
|
-
const totalMass = UInt64.from(mass_unload).adding(ship.loaders.mass);
|
|
5074
|
-
unloadTime = Number(calc_loader_flighttime(ship, totalMass));
|
|
5075
|
-
}
|
|
5076
|
-
if (mass_load.gt(UInt64.zero) && ship.loaders) {
|
|
5077
|
-
const totalMass = UInt64.from(mass_load).adding(ship.loaders.mass);
|
|
5078
|
-
loadTime = Number(calc_loader_flighttime(ship, totalMass));
|
|
5079
|
-
}
|
|
5080
|
-
const numLoaders = ship.loaders ? Number(ship.loaders.quantity) : 0;
|
|
5081
|
-
const totalTime = numLoaders > 0 ? (unloadTime + loadTime) / numLoaders : 0;
|
|
5082
|
-
const unloadTimePerLoader = numLoaders > 0 ? unloadTime / numLoaders : 0;
|
|
5083
|
-
const loadTimePerLoader = numLoaders > 0 ? loadTime / numLoaders : 0;
|
|
5084
|
-
return {
|
|
5085
|
-
unloadTime: unloadTimePerLoader,
|
|
5086
|
-
loadTime: loadTimePerLoader,
|
|
5087
|
-
totalTime,
|
|
5088
|
-
unloadMass: Number(mass_unload),
|
|
5089
|
-
loadMass: Number(mass_load),
|
|
5090
|
-
};
|
|
4908
|
+
const ITEM_ENGINE_T1 = 10100;
|
|
4909
|
+
const ITEM_GENERATOR_T1 = 10101;
|
|
4910
|
+
const ITEM_GATHERER_T1 = 10102;
|
|
4911
|
+
const ITEM_LOADER_T1 = 10103;
|
|
4912
|
+
const ITEM_MANUFACTURING_T1 = 10104;
|
|
4913
|
+
const ITEM_STORAGE_T1 = 10105;
|
|
4914
|
+
const ITEM_HAULER_T1 = 10106;
|
|
4915
|
+
const MODULE_ANY = 0;
|
|
4916
|
+
const MODULE_ENGINE = 1;
|
|
4917
|
+
const MODULE_GENERATOR = 2;
|
|
4918
|
+
const MODULE_GATHERER = 3;
|
|
4919
|
+
const MODULE_LOADER = 4;
|
|
4920
|
+
const MODULE_WARP = 5;
|
|
4921
|
+
const MODULE_CRAFTER = 6;
|
|
4922
|
+
const MODULE_LAUNCHER = 7;
|
|
4923
|
+
const MODULE_STORAGE = 8;
|
|
4924
|
+
const MODULE_HAULER = 9;
|
|
4925
|
+
function moduleAccepts(slotType, moduleType) {
|
|
4926
|
+
return slotType === MODULE_ANY || slotType === moduleType;
|
|
5091
4927
|
}
|
|
5092
|
-
function
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
unloadTime = calc_loader_flighttime(ship, totalMass).dividing(ship.loaders.quantity);
|
|
4928
|
+
function getModuleCapabilityType(itemId) {
|
|
4929
|
+
switch (itemId) {
|
|
4930
|
+
case ITEM_ENGINE_T1:
|
|
4931
|
+
return MODULE_ENGINE;
|
|
4932
|
+
case ITEM_GENERATOR_T1:
|
|
4933
|
+
return MODULE_GENERATOR;
|
|
4934
|
+
case ITEM_GATHERER_T1:
|
|
4935
|
+
return MODULE_GATHERER;
|
|
4936
|
+
case ITEM_LOADER_T1:
|
|
4937
|
+
return MODULE_LOADER;
|
|
4938
|
+
case ITEM_MANUFACTURING_T1:
|
|
4939
|
+
return MODULE_CRAFTER;
|
|
4940
|
+
case ITEM_STORAGE_T1:
|
|
4941
|
+
return MODULE_STORAGE;
|
|
4942
|
+
case ITEM_HAULER_T1:
|
|
4943
|
+
return MODULE_HAULER;
|
|
4944
|
+
default:
|
|
4945
|
+
return 0xff;
|
|
5111
4946
|
}
|
|
5112
|
-
return {
|
|
5113
|
-
flightTime,
|
|
5114
|
-
rechargeTime,
|
|
5115
|
-
loadTime,
|
|
5116
|
-
unloadTime,
|
|
5117
|
-
total: flightTime.adding(rechargeTime).adding(loadTime).adding(unloadTime),
|
|
5118
|
-
};
|
|
5119
|
-
}
|
|
5120
|
-
function estimateDealTravelTime(ship, shipMass, distance, loadMass) {
|
|
5121
|
-
const needsRecharge = !hasEnergyForDistance$1(ship, distance);
|
|
5122
|
-
const estimate = estimateTravelTime(ship, shipMass, distance, {
|
|
5123
|
-
needsRecharge,
|
|
5124
|
-
loadMass,
|
|
5125
|
-
});
|
|
5126
|
-
return estimate.total;
|
|
5127
4947
|
}
|
|
5128
|
-
function
|
|
5129
|
-
|
|
5130
|
-
return false;
|
|
5131
|
-
const energyNeeded = UInt64.from(distance).dividing(PRECISION$1).multiplying(ship.engines.drain);
|
|
5132
|
-
return UInt64.from(ship.energy ?? 0).gte(energyNeeded);
|
|
5133
|
-
}
|
|
5134
|
-
function getFlightOrigin(entity, flightTaskIndex) {
|
|
5135
|
-
if (!entity.schedule)
|
|
5136
|
-
return entity.coordinates;
|
|
5137
|
-
let origin = entity.coordinates;
|
|
5138
|
-
for (let i = 0; i < flightTaskIndex && i < entity.schedule.tasks.length; i++) {
|
|
5139
|
-
const task = entity.schedule.tasks[i];
|
|
5140
|
-
if (task.type.equals(TaskType.TRAVEL) && task.coordinates) {
|
|
5141
|
-
origin = task.coordinates;
|
|
5142
|
-
}
|
|
5143
|
-
}
|
|
5144
|
-
return origin;
|
|
5145
|
-
}
|
|
5146
|
-
function getDestinationLocation(entity) {
|
|
5147
|
-
if (!entity.schedule)
|
|
5148
|
-
return undefined;
|
|
5149
|
-
for (let i = entity.schedule.tasks.length - 1; i >= 0; i--) {
|
|
5150
|
-
const task = entity.schedule.tasks[i];
|
|
5151
|
-
if (task.type.equals(TaskType.TRAVEL) && task.coordinates) {
|
|
5152
|
-
return task.coordinates;
|
|
5153
|
-
}
|
|
5154
|
-
}
|
|
5155
|
-
return undefined;
|
|
5156
|
-
}
|
|
5157
|
-
function getPositionAt(entity, taskIndex, taskProgress) {
|
|
5158
|
-
if (!entity.schedule || entity.schedule.tasks.length === 0 || taskIndex < 0) {
|
|
5159
|
-
return entity.coordinates;
|
|
5160
|
-
}
|
|
5161
|
-
const task = entity.schedule.tasks[taskIndex];
|
|
5162
|
-
if (!task.type.equals(TaskType.TRAVEL) || !task.coordinates) {
|
|
5163
|
-
return getFlightOrigin(entity, taskIndex);
|
|
5164
|
-
}
|
|
5165
|
-
const origin = getFlightOrigin(entity, taskIndex);
|
|
5166
|
-
const destination = task.coordinates;
|
|
5167
|
-
const interpolated = lerp(origin, destination, taskProgress);
|
|
5168
|
-
return {
|
|
5169
|
-
x: Math.round(interpolated.x),
|
|
5170
|
-
y: Math.round(interpolated.y),
|
|
5171
|
-
};
|
|
5172
|
-
}
|
|
5173
|
-
function calc_transfer_duration(source, dest, cargoMass) {
|
|
5174
|
-
if (cargoMass === 0) {
|
|
5175
|
-
return 0;
|
|
5176
|
-
}
|
|
5177
|
-
let totalThrust = 0;
|
|
5178
|
-
let totalLoaderMass = 0;
|
|
5179
|
-
let totalQuantity = 0;
|
|
5180
|
-
if (source.loaders) {
|
|
5181
|
-
const thrust = typeof source.loaders.thrust === 'number'
|
|
5182
|
-
? source.loaders.thrust
|
|
5183
|
-
: source.loaders.thrust.toNumber();
|
|
5184
|
-
const mass = typeof source.loaders.mass === 'number'
|
|
5185
|
-
? source.loaders.mass
|
|
5186
|
-
: source.loaders.mass.toNumber();
|
|
5187
|
-
const qty = typeof source.loaders.quantity === 'number'
|
|
5188
|
-
? source.loaders.quantity
|
|
5189
|
-
: source.loaders.quantity.toNumber();
|
|
5190
|
-
totalThrust += thrust * qty;
|
|
5191
|
-
totalLoaderMass += mass * qty;
|
|
5192
|
-
totalQuantity += qty;
|
|
5193
|
-
}
|
|
5194
|
-
if (dest.loaders) {
|
|
5195
|
-
const thrust = typeof dest.loaders.thrust === 'number'
|
|
5196
|
-
? dest.loaders.thrust
|
|
5197
|
-
: dest.loaders.thrust.toNumber();
|
|
5198
|
-
const mass = typeof dest.loaders.mass === 'number' ? dest.loaders.mass : dest.loaders.mass.toNumber();
|
|
5199
|
-
const qty = typeof dest.loaders.quantity === 'number'
|
|
5200
|
-
? dest.loaders.quantity
|
|
5201
|
-
: dest.loaders.quantity.toNumber();
|
|
5202
|
-
totalThrust += thrust * qty;
|
|
5203
|
-
totalLoaderMass += mass * qty;
|
|
5204
|
-
totalQuantity += qty;
|
|
5205
|
-
}
|
|
5206
|
-
if (totalThrust === 0 || totalQuantity === 0) {
|
|
5207
|
-
return 0;
|
|
5208
|
-
}
|
|
5209
|
-
const sourceZ = typeof source.location.z === 'number'
|
|
5210
|
-
? source.location.z
|
|
5211
|
-
: source.location.z?.toNumber() ?? 0;
|
|
5212
|
-
const destZ = typeof dest.location.z === 'number' ? dest.location.z : dest.location.z?.toNumber() ?? 0;
|
|
5213
|
-
const distance = Math.abs(sourceZ - destZ);
|
|
5214
|
-
const totalMass = cargoMass + totalLoaderMass;
|
|
5215
|
-
const acceleration = calc_acceleration(totalThrust, totalMass);
|
|
5216
|
-
const flightTime = 2 * Math.sqrt(distance / acceleration);
|
|
5217
|
-
return Math.floor(flightTime / totalQuantity);
|
|
5218
|
-
}
|
|
5219
|
-
|
|
5220
|
-
function capsHasMovement(caps) {
|
|
5221
|
-
return caps.engines !== undefined && caps.generator !== undefined;
|
|
5222
|
-
}
|
|
5223
|
-
function capsHasStorage(caps) {
|
|
5224
|
-
return caps.capacity !== undefined;
|
|
5225
|
-
}
|
|
5226
|
-
function capsHasLoaders(caps) {
|
|
5227
|
-
return caps.loaders !== undefined;
|
|
5228
|
-
}
|
|
5229
|
-
function capsHasGatherer(caps) {
|
|
5230
|
-
return caps.gatherer !== undefined;
|
|
5231
|
-
}
|
|
5232
|
-
function capsHasMass(caps) {
|
|
5233
|
-
return caps.hullmass !== undefined;
|
|
5234
|
-
}
|
|
5235
|
-
|
|
5236
|
-
function calcCargoItemMass(item) {
|
|
5237
|
-
const itemDef = getItem(item.item_id);
|
|
5238
|
-
let mass = UInt64.from(itemDef.mass).multiplying(item.quantity);
|
|
5239
|
-
for (const mod of item.modules) {
|
|
5240
|
-
if (mod.installed) {
|
|
5241
|
-
const modDef = getItem(mod.installed.item_id);
|
|
5242
|
-
mass = mass.adding(modDef.mass);
|
|
5243
|
-
}
|
|
5244
|
-
}
|
|
5245
|
-
return mass;
|
|
5246
|
-
}
|
|
5247
|
-
function calcCargoMass(entity) {
|
|
5248
|
-
let mass = UInt64.from(0);
|
|
5249
|
-
for (const item of entity.cargo) {
|
|
5250
|
-
mass = mass.adding(calcCargoItemMass(item));
|
|
5251
|
-
}
|
|
5252
|
-
return mass;
|
|
5253
|
-
}
|
|
5254
|
-
function availableCapacity$1(entity) {
|
|
5255
|
-
const cargoMass = calcCargoMass(entity);
|
|
5256
|
-
return entity.capacity.gt(cargoMass)
|
|
5257
|
-
? UInt64.from(entity.capacity).subtracting(cargoMass)
|
|
5258
|
-
: UInt64.from(0);
|
|
5259
|
-
}
|
|
5260
|
-
function availableCapacityFromMass(capacity, cargoMass) {
|
|
5261
|
-
const cap = UInt64.from(capacity);
|
|
5262
|
-
const mass = UInt64.from(cargoMass);
|
|
5263
|
-
return cap.gt(mass) ? cap.subtracting(mass) : UInt64.from(0);
|
|
5264
|
-
}
|
|
5265
|
-
function hasSpace$1(entity, goodMass, quantity) {
|
|
5266
|
-
const additional = goodMass.multiplying(quantity);
|
|
5267
|
-
return availableCapacity$1(entity).gte(additional);
|
|
5268
|
-
}
|
|
5269
|
-
function hasSpaceForMass(capacity, currentMass, additionalMass) {
|
|
5270
|
-
return UInt64.from(currentMass).adding(additionalMass).lte(capacity);
|
|
5271
|
-
}
|
|
5272
|
-
function isFull$1(entity) {
|
|
5273
|
-
return UInt64.from(entity.cargomass).gte(entity.capacity);
|
|
5274
|
-
}
|
|
5275
|
-
function isFullFromMass(capacity, cargoMass) {
|
|
5276
|
-
return UInt64.from(cargoMass).gte(capacity);
|
|
5277
|
-
}
|
|
5278
|
-
|
|
5279
|
-
function hasSchedule$1(entity) {
|
|
5280
|
-
return !!entity.schedule && entity.schedule.tasks.length > 0;
|
|
5281
|
-
}
|
|
5282
|
-
function isIdle(entity) {
|
|
5283
|
-
return !hasSchedule$1(entity);
|
|
5284
|
-
}
|
|
5285
|
-
function getTasks(entity) {
|
|
5286
|
-
return entity.schedule?.tasks || [];
|
|
5287
|
-
}
|
|
5288
|
-
function scheduleDuration(entity) {
|
|
5289
|
-
if (!entity.schedule)
|
|
5290
|
-
return 0;
|
|
5291
|
-
return entity.schedule.tasks.reduce((sum, task) => sum + task.duration.toNumber(), 0);
|
|
5292
|
-
}
|
|
5293
|
-
function scheduleElapsed(entity, now) {
|
|
5294
|
-
if (!entity.schedule)
|
|
5295
|
-
return 0;
|
|
5296
|
-
const started = entity.schedule.started.toDate();
|
|
5297
|
-
const elapsed = Math.floor((now.getTime() - started.getTime()) / 1000);
|
|
5298
|
-
return Math.max(0, elapsed);
|
|
5299
|
-
}
|
|
5300
|
-
function scheduleRemaining(entity, now) {
|
|
5301
|
-
if (!entity.schedule)
|
|
5302
|
-
return 0;
|
|
5303
|
-
const duration = scheduleDuration(entity);
|
|
5304
|
-
const elapsed = scheduleElapsed(entity, now);
|
|
5305
|
-
return Math.max(0, duration - elapsed);
|
|
5306
|
-
}
|
|
5307
|
-
function scheduleComplete(entity, now) {
|
|
5308
|
-
return hasSchedule$1(entity) && scheduleRemaining(entity, now) === 0;
|
|
5309
|
-
}
|
|
5310
|
-
function currentTaskIndex(entity, now) {
|
|
5311
|
-
if (!entity.schedule || entity.schedule.tasks.length === 0)
|
|
5312
|
-
return -1;
|
|
5313
|
-
const elapsed = scheduleElapsed(entity, now);
|
|
5314
|
-
let timeAccum = 0;
|
|
5315
|
-
for (let i = 0; i < entity.schedule.tasks.length; i++) {
|
|
5316
|
-
const taskDuration = entity.schedule.tasks[i].duration.toNumber();
|
|
5317
|
-
if (elapsed < timeAccum + taskDuration) {
|
|
5318
|
-
return i;
|
|
5319
|
-
}
|
|
5320
|
-
timeAccum += taskDuration;
|
|
5321
|
-
}
|
|
5322
|
-
return entity.schedule.tasks.length - 1;
|
|
5323
|
-
}
|
|
5324
|
-
function currentTask(entity, now) {
|
|
5325
|
-
const index = currentTaskIndex(entity, now);
|
|
5326
|
-
if (index < 0 || !entity.schedule)
|
|
5327
|
-
return undefined;
|
|
5328
|
-
return entity.schedule.tasks[index];
|
|
5329
|
-
}
|
|
5330
|
-
function currentTaskType(entity, now) {
|
|
5331
|
-
const task = currentTask(entity, now);
|
|
5332
|
-
if (!task)
|
|
5333
|
-
return undefined;
|
|
5334
|
-
return task.type.toNumber();
|
|
5335
|
-
}
|
|
5336
|
-
function getTaskStartTime(entity, index) {
|
|
5337
|
-
if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length)
|
|
5338
|
-
return 0;
|
|
5339
|
-
let timeAccum = 0;
|
|
5340
|
-
for (let i = 0; i < index; i++) {
|
|
5341
|
-
timeAccum += entity.schedule.tasks[i].duration.toNumber();
|
|
5342
|
-
}
|
|
5343
|
-
return timeAccum;
|
|
5344
|
-
}
|
|
5345
|
-
function getTaskElapsed(entity, index, now) {
|
|
5346
|
-
if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length)
|
|
5347
|
-
return 0;
|
|
5348
|
-
const elapsed = scheduleElapsed(entity, now);
|
|
5349
|
-
const taskStart = getTaskStartTime(entity, index);
|
|
5350
|
-
const taskDuration = entity.schedule.tasks[index].duration.toNumber();
|
|
5351
|
-
if (elapsed <= taskStart)
|
|
5352
|
-
return 0;
|
|
5353
|
-
const elapsedInTask = elapsed - taskStart;
|
|
5354
|
-
return Math.min(elapsedInTask, taskDuration);
|
|
5355
|
-
}
|
|
5356
|
-
function getTaskRemaining(entity, index, now) {
|
|
5357
|
-
if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length)
|
|
5358
|
-
return 0;
|
|
5359
|
-
const taskDuration = entity.schedule.tasks[index].duration.toNumber();
|
|
5360
|
-
const taskElapsed = getTaskElapsed(entity, index, now);
|
|
5361
|
-
return Math.max(0, taskDuration - taskElapsed);
|
|
5362
|
-
}
|
|
5363
|
-
function isTaskComplete(entity, index, now) {
|
|
5364
|
-
if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length)
|
|
5365
|
-
return false;
|
|
5366
|
-
const taskDuration = entity.schedule.tasks[index].duration.toNumber();
|
|
5367
|
-
const taskElapsed = getTaskElapsed(entity, index, now);
|
|
5368
|
-
return taskElapsed >= taskDuration;
|
|
5369
|
-
}
|
|
5370
|
-
function isTaskInProgress(entity, index, now) {
|
|
5371
|
-
if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length)
|
|
5372
|
-
return false;
|
|
5373
|
-
const taskElapsed = getTaskElapsed(entity, index, now);
|
|
5374
|
-
const taskDuration = entity.schedule.tasks[index].duration.toNumber();
|
|
5375
|
-
return taskElapsed > 0 && taskElapsed < taskDuration;
|
|
5376
|
-
}
|
|
5377
|
-
function currentTaskProgress(entity, now) {
|
|
5378
|
-
const task = currentTask(entity, now);
|
|
5379
|
-
if (!task)
|
|
5380
|
-
return 0;
|
|
5381
|
-
const index = currentTaskIndex(entity, now);
|
|
5382
|
-
const elapsed = getTaskElapsed(entity, index, now);
|
|
5383
|
-
const duration = task.duration.toNumber();
|
|
5384
|
-
if (duration === 0)
|
|
5385
|
-
return 1;
|
|
5386
|
-
return Math.min(1, elapsed / duration);
|
|
5387
|
-
}
|
|
5388
|
-
function scheduleProgress(entity, now) {
|
|
5389
|
-
const duration = scheduleDuration(entity);
|
|
5390
|
-
if (duration === 0)
|
|
5391
|
-
return hasSchedule$1(entity) ? 1 : 0;
|
|
5392
|
-
const elapsed = scheduleElapsed(entity, now);
|
|
5393
|
-
return Math.min(1, elapsed / duration);
|
|
5394
|
-
}
|
|
5395
|
-
function isTaskType(entity, taskType, now) {
|
|
5396
|
-
return currentTaskType(entity, now) === taskType;
|
|
5397
|
-
}
|
|
5398
|
-
function isInFlight(entity, now) {
|
|
5399
|
-
return isTaskType(entity, TaskType.TRAVEL, now);
|
|
5400
|
-
}
|
|
5401
|
-
function isRecharging(entity, now) {
|
|
5402
|
-
return isTaskType(entity, TaskType.RECHARGE, now);
|
|
5403
|
-
}
|
|
5404
|
-
function isLoading(entity, now) {
|
|
5405
|
-
return isTaskType(entity, TaskType.LOAD, now);
|
|
5406
|
-
}
|
|
5407
|
-
function isUnloading(entity, now) {
|
|
5408
|
-
return isTaskType(entity, TaskType.UNLOAD, now);
|
|
5409
|
-
}
|
|
5410
|
-
function isGathering(entity, now) {
|
|
5411
|
-
return isTaskType(entity, TaskType.GATHER, now);
|
|
5412
|
-
}
|
|
5413
|
-
|
|
5414
|
-
var schedule = /*#__PURE__*/Object.freeze({
|
|
5415
|
-
__proto__: null,
|
|
5416
|
-
hasSchedule: hasSchedule$1,
|
|
5417
|
-
isIdle: isIdle,
|
|
5418
|
-
getTasks: getTasks,
|
|
5419
|
-
scheduleDuration: scheduleDuration,
|
|
5420
|
-
scheduleElapsed: scheduleElapsed,
|
|
5421
|
-
scheduleRemaining: scheduleRemaining,
|
|
5422
|
-
scheduleComplete: scheduleComplete,
|
|
5423
|
-
currentTaskIndex: currentTaskIndex,
|
|
5424
|
-
currentTask: currentTask,
|
|
5425
|
-
currentTaskType: currentTaskType,
|
|
5426
|
-
getTaskStartTime: getTaskStartTime,
|
|
5427
|
-
getTaskElapsed: getTaskElapsed,
|
|
5428
|
-
getTaskRemaining: getTaskRemaining,
|
|
5429
|
-
isTaskComplete: isTaskComplete,
|
|
5430
|
-
isTaskInProgress: isTaskInProgress,
|
|
5431
|
-
currentTaskProgress: currentTaskProgress,
|
|
5432
|
-
scheduleProgress: scheduleProgress,
|
|
5433
|
-
isTaskType: isTaskType,
|
|
5434
|
-
isInFlight: isInFlight,
|
|
5435
|
-
isRecharging: isRecharging,
|
|
5436
|
-
isLoading: isLoading,
|
|
5437
|
-
isUnloading: isUnloading,
|
|
5438
|
-
isGathering: isGathering
|
|
5439
|
-
});
|
|
5440
|
-
|
|
5441
|
-
function getHullMass(entity) {
|
|
5442
|
-
return UInt32.from(entity.hullmass ?? 0);
|
|
5443
|
-
}
|
|
5444
|
-
function createProjectedEntity(entity) {
|
|
5445
|
-
const cargoMass = calcCargoMass(entity);
|
|
5446
|
-
const shipMass = getHullMass(entity);
|
|
5447
|
-
const loaders = entity.loaders;
|
|
5448
|
-
const engines = entity.engines;
|
|
5449
|
-
const generator = entity.generator;
|
|
5450
|
-
const hauler = entity.hauler;
|
|
5451
|
-
const capacity = entity.capacity;
|
|
5452
|
-
const projected = {
|
|
5453
|
-
location: Coordinates.from(entity.coordinates),
|
|
5454
|
-
energy: UInt16.from(entity.energy ?? 0),
|
|
5455
|
-
cargoMass,
|
|
5456
|
-
shipMass,
|
|
5457
|
-
capacity: capacity ? UInt64.from(capacity) : undefined,
|
|
5458
|
-
engines,
|
|
5459
|
-
generator,
|
|
5460
|
-
hauler,
|
|
5461
|
-
loaders,
|
|
5462
|
-
get totalMass() {
|
|
5463
|
-
let mass = UInt64.from(this.shipMass).adding(this.cargoMass);
|
|
5464
|
-
if (this.loaders) {
|
|
5465
|
-
mass = mass.adding(this.loaders.mass.multiplying(this.loaders.quantity));
|
|
5466
|
-
}
|
|
5467
|
-
return mass;
|
|
5468
|
-
},
|
|
5469
|
-
hasMovement() {
|
|
5470
|
-
return capsHasMovement(this.capabilities());
|
|
5471
|
-
},
|
|
5472
|
-
hasStorage() {
|
|
5473
|
-
return capsHasStorage(this.capabilities());
|
|
5474
|
-
},
|
|
5475
|
-
hasLoaders() {
|
|
5476
|
-
return capsHasLoaders(this.capabilities());
|
|
5477
|
-
},
|
|
5478
|
-
capabilities() {
|
|
5479
|
-
return {
|
|
5480
|
-
hullmass: this.shipMass,
|
|
5481
|
-
capacity: this.capacity ? UInt32.from(this.capacity) : undefined,
|
|
5482
|
-
engines: this.engines,
|
|
5483
|
-
generator: this.generator,
|
|
5484
|
-
loaders: this.loaders,
|
|
5485
|
-
};
|
|
5486
|
-
},
|
|
5487
|
-
state() {
|
|
5488
|
-
return {
|
|
5489
|
-
owner: entity.owner ?? Name.from(''),
|
|
5490
|
-
location: Types.coordinates.from(this.location),
|
|
5491
|
-
energy: this.energy,
|
|
5492
|
-
cargomass: UInt32.from(this.cargoMass),
|
|
5493
|
-
cargo: entity.cargo,
|
|
5494
|
-
};
|
|
5495
|
-
},
|
|
5496
|
-
};
|
|
5497
|
-
return projected;
|
|
5498
|
-
}
|
|
5499
|
-
function applyRechargeTask(projected, _task, options) {
|
|
5500
|
-
if (!projected.generator)
|
|
5501
|
-
return;
|
|
5502
|
-
if (options.complete) {
|
|
5503
|
-
projected.energy = UInt16.from(projected.generator.capacity);
|
|
5504
|
-
}
|
|
5505
|
-
else if (options.progress !== undefined) {
|
|
5506
|
-
const capacity = Number(projected.generator.capacity);
|
|
5507
|
-
const currentEnergy = Number(projected.energy);
|
|
5508
|
-
const rechargeAmount = (capacity - currentEnergy) * options.progress;
|
|
5509
|
-
projected.energy = UInt16.from(Math.min(capacity, currentEnergy + rechargeAmount));
|
|
5510
|
-
}
|
|
5511
|
-
}
|
|
5512
|
-
function applyFlightTask(projected, task, options) {
|
|
5513
|
-
if (!task.coordinates || !projected.engines)
|
|
5514
|
-
return;
|
|
5515
|
-
const origin = projected.location;
|
|
5516
|
-
const destination = Coordinates.from(task.coordinates);
|
|
5517
|
-
const distance = distanceBetweenCoordinates(origin, task.coordinates);
|
|
5518
|
-
const energyUsage = distance.dividing(PRECISION$1).multiplying(projected.engines.drain);
|
|
5519
|
-
if (options.complete) {
|
|
5520
|
-
projected.energy = projected.energy.gt(energyUsage)
|
|
5521
|
-
? UInt16.from(projected.energy.subtracting(energyUsage))
|
|
5522
|
-
: UInt16.from(0);
|
|
5523
|
-
projected.location = destination;
|
|
5524
|
-
}
|
|
5525
|
-
else if (options.progress !== undefined) {
|
|
5526
|
-
const interpolated = lerp(origin, destination, options.progress);
|
|
5527
|
-
projected.location = Coordinates.from({
|
|
5528
|
-
x: Math.round(interpolated.x),
|
|
5529
|
-
y: Math.round(interpolated.y),
|
|
5530
|
-
});
|
|
5531
|
-
const partialEnergy = UInt64.from(Math.floor(Number(energyUsage) * options.progress));
|
|
5532
|
-
projected.energy = projected.energy.gt(partialEnergy)
|
|
5533
|
-
? UInt16.from(projected.energy.subtracting(partialEnergy))
|
|
5534
|
-
: UInt16.from(0);
|
|
5535
|
-
}
|
|
5536
|
-
}
|
|
5537
|
-
function applyLoadTask(projected, task) {
|
|
5538
|
-
for (const item of task.cargo) {
|
|
5539
|
-
projected.cargoMass = projected.cargoMass.adding(calcCargoItemMass(item));
|
|
5540
|
-
}
|
|
5541
|
-
}
|
|
5542
|
-
function applyUnloadTask(projected, task) {
|
|
5543
|
-
for (const item of task.cargo) {
|
|
5544
|
-
const cargoMass = calcCargoItemMass(item);
|
|
5545
|
-
projected.cargoMass = projected.cargoMass.gt(cargoMass)
|
|
5546
|
-
? projected.cargoMass.subtracting(cargoMass)
|
|
5547
|
-
: UInt64.from(0);
|
|
5548
|
-
}
|
|
5549
|
-
}
|
|
5550
|
-
function applyEnergyCost(projected, task) {
|
|
5551
|
-
if (!task.energy_cost)
|
|
5552
|
-
return;
|
|
5553
|
-
const energyCost = UInt16.from(task.energy_cost);
|
|
5554
|
-
projected.energy = projected.energy.gt(energyCost)
|
|
5555
|
-
? UInt16.from(projected.energy.subtracting(energyCost))
|
|
5556
|
-
: UInt16.from(0);
|
|
5557
|
-
}
|
|
5558
|
-
function applyGatherTask(projected, task, options) {
|
|
5559
|
-
if (!options.complete)
|
|
5560
|
-
return;
|
|
5561
|
-
applyEnergyCost(projected, task);
|
|
5562
|
-
for (const item of task.cargo) {
|
|
5563
|
-
projected.cargoMass = projected.cargoMass.adding(calcCargoItemMass(item));
|
|
5564
|
-
}
|
|
5565
|
-
}
|
|
5566
|
-
function applyCraftTask(projected, task) {
|
|
5567
|
-
applyEnergyCost(projected, task);
|
|
5568
|
-
if (task.cargo.length > 0) {
|
|
5569
|
-
for (let i = 0; i < task.cargo.length - 1; i++) {
|
|
5570
|
-
const inputMass = calcCargoItemMass(task.cargo[i]);
|
|
5571
|
-
projected.cargoMass = projected.cargoMass.gt(inputMass)
|
|
5572
|
-
? projected.cargoMass.subtracting(inputMass)
|
|
5573
|
-
: UInt64.from(0);
|
|
5574
|
-
}
|
|
5575
|
-
const output = task.cargo[task.cargo.length - 1];
|
|
5576
|
-
projected.cargoMass = projected.cargoMass.adding(calcCargoItemMass(output));
|
|
5577
|
-
}
|
|
5578
|
-
}
|
|
5579
|
-
function applyDeployTask(projected, task) {
|
|
5580
|
-
applyEnergyCost(projected, task);
|
|
5581
|
-
if (task.cargo.length > 0) {
|
|
5582
|
-
const mass = calcCargoItemMass(task.cargo[0]);
|
|
5583
|
-
projected.cargoMass = projected.cargoMass.gt(mass)
|
|
5584
|
-
? projected.cargoMass.subtracting(mass)
|
|
5585
|
-
: UInt64.from(0);
|
|
5586
|
-
}
|
|
5587
|
-
}
|
|
5588
|
-
function projectEntity(entity) {
|
|
5589
|
-
const projected = createProjectedEntity(entity);
|
|
5590
|
-
if (!entity.schedule) {
|
|
5591
|
-
return projected;
|
|
5592
|
-
}
|
|
5593
|
-
for (const task of entity.schedule.tasks) {
|
|
5594
|
-
switch (task.type.toNumber()) {
|
|
5595
|
-
case TaskType.RECHARGE:
|
|
5596
|
-
applyRechargeTask(projected, task, { complete: true });
|
|
5597
|
-
break;
|
|
5598
|
-
case TaskType.TRAVEL:
|
|
5599
|
-
applyFlightTask(projected, task, { complete: true });
|
|
5600
|
-
break;
|
|
5601
|
-
case TaskType.LOAD:
|
|
5602
|
-
applyLoadTask(projected, task);
|
|
5603
|
-
break;
|
|
5604
|
-
case TaskType.UNLOAD:
|
|
5605
|
-
applyUnloadTask(projected, task);
|
|
5606
|
-
break;
|
|
5607
|
-
case TaskType.GATHER:
|
|
5608
|
-
applyGatherTask(projected, task, { complete: true });
|
|
5609
|
-
break;
|
|
5610
|
-
case TaskType.CRAFT:
|
|
5611
|
-
applyCraftTask(projected, task);
|
|
5612
|
-
break;
|
|
5613
|
-
case TaskType.DEPLOY:
|
|
5614
|
-
case TaskType.DEPLOY_SHIP:
|
|
5615
|
-
applyDeployTask(projected, task);
|
|
5616
|
-
break;
|
|
5617
|
-
}
|
|
5618
|
-
}
|
|
5619
|
-
return projected;
|
|
5620
|
-
}
|
|
5621
|
-
function projectEntityAt(entity, now) {
|
|
5622
|
-
const projected = createProjectedEntity(entity);
|
|
5623
|
-
if (!entity.schedule || entity.schedule.tasks.length === 0) {
|
|
5624
|
-
return projected;
|
|
5625
|
-
}
|
|
5626
|
-
for (let i = 0; i < entity.schedule.tasks.length; i++) {
|
|
5627
|
-
const task = entity.schedule.tasks[i];
|
|
5628
|
-
const taskComplete = isTaskComplete(entity, i, now);
|
|
5629
|
-
const taskInProgress = isTaskInProgress(entity, i, now);
|
|
5630
|
-
if (!taskComplete && !taskInProgress) {
|
|
5631
|
-
break;
|
|
5632
|
-
}
|
|
5633
|
-
const progress = taskInProgress
|
|
5634
|
-
? getTaskElapsed(entity, i, now) / task.duration.toNumber()
|
|
5635
|
-
: undefined;
|
|
5636
|
-
switch (task.type.toNumber()) {
|
|
5637
|
-
case TaskType.RECHARGE:
|
|
5638
|
-
applyRechargeTask(projected, task, { complete: taskComplete, progress });
|
|
5639
|
-
break;
|
|
5640
|
-
case TaskType.TRAVEL:
|
|
5641
|
-
applyFlightTask(projected, task, { complete: taskComplete, progress });
|
|
5642
|
-
break;
|
|
5643
|
-
case TaskType.LOAD:
|
|
5644
|
-
if (taskComplete) {
|
|
5645
|
-
applyLoadTask(projected, task);
|
|
5646
|
-
}
|
|
5647
|
-
break;
|
|
5648
|
-
case TaskType.UNLOAD:
|
|
5649
|
-
if (taskComplete) {
|
|
5650
|
-
applyUnloadTask(projected, task);
|
|
5651
|
-
}
|
|
5652
|
-
break;
|
|
5653
|
-
case TaskType.GATHER:
|
|
5654
|
-
if (taskComplete) {
|
|
5655
|
-
applyGatherTask(projected, task, { complete: true });
|
|
5656
|
-
}
|
|
5657
|
-
break;
|
|
5658
|
-
case TaskType.CRAFT:
|
|
5659
|
-
if (taskComplete) {
|
|
5660
|
-
applyCraftTask(projected, task);
|
|
5661
|
-
}
|
|
5662
|
-
break;
|
|
5663
|
-
case TaskType.DEPLOY:
|
|
5664
|
-
case TaskType.DEPLOY_SHIP:
|
|
5665
|
-
if (taskComplete) {
|
|
5666
|
-
applyDeployTask(projected, task);
|
|
5667
|
-
}
|
|
5668
|
-
break;
|
|
5669
|
-
}
|
|
5670
|
-
}
|
|
5671
|
-
return projected;
|
|
5672
|
-
}
|
|
5673
|
-
|
|
5674
|
-
class Location {
|
|
5675
|
-
constructor(coordinates) {
|
|
5676
|
-
this.coordinates = Coordinates.from(coordinates);
|
|
5677
|
-
}
|
|
5678
|
-
static from(coordinates) {
|
|
5679
|
-
return new Location(Coordinates.from(coordinates));
|
|
5680
|
-
}
|
|
5681
|
-
hasSystemAt(gameSeed) {
|
|
5682
|
-
const seed = Checksum256.from(gameSeed);
|
|
5683
|
-
if (this._hasSystem === undefined || !this._gameSeed?.equals(seed)) {
|
|
5684
|
-
this._gameSeed = seed;
|
|
5685
|
-
this._hasSystem = hasSystem(seed, this.coordinates);
|
|
5686
|
-
}
|
|
5687
|
-
return this._hasSystem;
|
|
5688
|
-
}
|
|
5689
|
-
getLocationTypeAt(gameSeed) {
|
|
5690
|
-
return getLocationType(gameSeed, this.coordinates);
|
|
5691
|
-
}
|
|
5692
|
-
isGatherableAt(gameSeed) {
|
|
5693
|
-
return isGatherableLocation(this.getLocationTypeAt(gameSeed));
|
|
5694
|
-
}
|
|
5695
|
-
findNearby(gameSeed, maxDistance = 20) {
|
|
5696
|
-
return findNearbyPlanets(Checksum256.from(gameSeed), this.coordinates, maxDistance);
|
|
5697
|
-
}
|
|
5698
|
-
equals(other) {
|
|
5699
|
-
const otherCoords = other instanceof Location ? other.coordinates : Coordinates.from(other);
|
|
5700
|
-
return this.coordinates.equals(otherCoords);
|
|
5701
|
-
}
|
|
5702
|
-
get epoch() {
|
|
5703
|
-
return this._epoch;
|
|
5704
|
-
}
|
|
5705
|
-
clearCache() {
|
|
5706
|
-
this._epoch = undefined;
|
|
5707
|
-
}
|
|
5708
|
-
}
|
|
5709
|
-
function toLocation(coords) {
|
|
5710
|
-
if (coords instanceof Location) {
|
|
5711
|
-
return coords;
|
|
5712
|
-
}
|
|
5713
|
-
return Location.from(coords);
|
|
5714
|
-
}
|
|
5715
|
-
|
|
5716
|
-
class ScheduleAccessor {
|
|
5717
|
-
constructor(entity) {
|
|
5718
|
-
this.entity = entity;
|
|
5719
|
-
}
|
|
5720
|
-
get hasSchedule() {
|
|
5721
|
-
return hasSchedule$1(this.entity);
|
|
5722
|
-
}
|
|
5723
|
-
get isIdle() {
|
|
5724
|
-
return isIdle(this.entity);
|
|
5725
|
-
}
|
|
5726
|
-
get tasks() {
|
|
5727
|
-
return getTasks(this.entity);
|
|
5728
|
-
}
|
|
5729
|
-
duration() {
|
|
5730
|
-
return scheduleDuration(this.entity);
|
|
5731
|
-
}
|
|
5732
|
-
elapsed(now) {
|
|
5733
|
-
return scheduleElapsed(this.entity, now);
|
|
5734
|
-
}
|
|
5735
|
-
remaining(now) {
|
|
5736
|
-
return scheduleRemaining(this.entity, now);
|
|
5737
|
-
}
|
|
5738
|
-
complete(now) {
|
|
5739
|
-
return scheduleComplete(this.entity, now);
|
|
5740
|
-
}
|
|
5741
|
-
currentTaskIndex(now) {
|
|
5742
|
-
return currentTaskIndex(this.entity, now);
|
|
5743
|
-
}
|
|
5744
|
-
currentTask(now) {
|
|
5745
|
-
return currentTask(this.entity, now);
|
|
5746
|
-
}
|
|
5747
|
-
currentTaskType(now) {
|
|
5748
|
-
return currentTaskType(this.entity, now);
|
|
5749
|
-
}
|
|
5750
|
-
taskStartTime(index) {
|
|
5751
|
-
return getTaskStartTime(this.entity, index);
|
|
5752
|
-
}
|
|
5753
|
-
taskElapsed(index, now) {
|
|
5754
|
-
return getTaskElapsed(this.entity, index, now);
|
|
5755
|
-
}
|
|
5756
|
-
taskRemaining(index, now) {
|
|
5757
|
-
return getTaskRemaining(this.entity, index, now);
|
|
5758
|
-
}
|
|
5759
|
-
taskComplete(index, now) {
|
|
5760
|
-
return isTaskComplete(this.entity, index, now);
|
|
5761
|
-
}
|
|
5762
|
-
taskInProgress(index, now) {
|
|
5763
|
-
return isTaskInProgress(this.entity, index, now);
|
|
5764
|
-
}
|
|
5765
|
-
currentTaskProgress(now) {
|
|
5766
|
-
return currentTaskProgress(this.entity, now);
|
|
5767
|
-
}
|
|
5768
|
-
progress(now) {
|
|
5769
|
-
return scheduleProgress(this.entity, now);
|
|
5770
|
-
}
|
|
5771
|
-
}
|
|
5772
|
-
function createScheduleAccessor(entity) {
|
|
5773
|
-
return new ScheduleAccessor(entity);
|
|
5774
|
-
}
|
|
5775
|
-
|
|
5776
|
-
class EntityInventory extends Types.cargo_item {
|
|
5777
|
-
get item() {
|
|
5778
|
-
if (!this._item) {
|
|
5779
|
-
this._item = getItem(this.item_id);
|
|
5780
|
-
}
|
|
5781
|
-
return this._item;
|
|
5782
|
-
}
|
|
5783
|
-
get good() {
|
|
5784
|
-
return this.item;
|
|
5785
|
-
}
|
|
5786
|
-
get name() {
|
|
5787
|
-
return this.item.name;
|
|
5788
|
-
}
|
|
5789
|
-
get unitMass() {
|
|
5790
|
-
return this.item.mass;
|
|
5791
|
-
}
|
|
5792
|
-
get totalMass() {
|
|
5793
|
-
return UInt64.from(this.unitMass).multiplying(this.quantity);
|
|
5794
|
-
}
|
|
5795
|
-
get hasCargo() {
|
|
5796
|
-
return UInt32.from(this.quantity).gt(UInt32.from(0));
|
|
5797
|
-
}
|
|
5798
|
-
get isEmpty() {
|
|
5799
|
-
return UInt32.from(this.quantity).equals(UInt32.from(0));
|
|
5800
|
-
}
|
|
5801
|
-
}
|
|
5802
|
-
|
|
5803
|
-
class InventoryAccessor {
|
|
5804
|
-
constructor(entity) {
|
|
5805
|
-
this.entity = entity;
|
|
5806
|
-
}
|
|
5807
|
-
get items() {
|
|
5808
|
-
if (!this._items) {
|
|
5809
|
-
this._items = this.entity.cargo.map((item) => new EntityInventory(item));
|
|
5810
|
-
}
|
|
5811
|
-
return this._items;
|
|
5812
|
-
}
|
|
5813
|
-
get totalMass() {
|
|
5814
|
-
return this.items.reduce((sum, c) => sum.adding(c.totalMass), UInt64.from(0));
|
|
5815
|
-
}
|
|
5816
|
-
forItem(goodId) {
|
|
5817
|
-
return this.items.find((c) => c.item_id.equals(goodId));
|
|
5818
|
-
}
|
|
5819
|
-
get sellable() {
|
|
5820
|
-
return this.items.filter((c) => c.hasCargo);
|
|
5821
|
-
}
|
|
5822
|
-
get hasSellable() {
|
|
5823
|
-
return this.items.some((c) => c.hasCargo);
|
|
5824
|
-
}
|
|
5825
|
-
get sellableCount() {
|
|
5826
|
-
return this.items.filter((c) => c.hasCargo).length;
|
|
5827
|
-
}
|
|
5828
|
-
}
|
|
5829
|
-
function createInventoryAccessor(entity) {
|
|
5830
|
-
return new InventoryAccessor(entity);
|
|
5831
|
-
}
|
|
5832
|
-
|
|
5833
|
-
function maxTravelDistance(entity) {
|
|
5834
|
-
return UInt32.from(entity.generator.capacity)
|
|
5835
|
-
.dividing(entity.engines.drain)
|
|
5836
|
-
.multiplying(PRECISION$1);
|
|
5837
|
-
}
|
|
5838
|
-
function calcEnergyUsage(entity, distance) {
|
|
5839
|
-
return distance.dividing(PRECISION$1).multiplying(entity.engines.drain);
|
|
5840
|
-
}
|
|
5841
|
-
function hasEnergyForDistance(entity, distance) {
|
|
5842
|
-
const usage = calcEnergyUsage(entity, distance);
|
|
5843
|
-
return UInt64.from(entity.energy).gte(usage);
|
|
5844
|
-
}
|
|
5845
|
-
function energyPercent(entity) {
|
|
5846
|
-
return (Number(entity.energy) / Number(entity.generator.capacity)) * 100;
|
|
5847
|
-
}
|
|
5848
|
-
function needsRecharge(entity) {
|
|
5849
|
-
return UInt64.from(entity.energy).lt(entity.generator.capacity);
|
|
5850
|
-
}
|
|
5851
|
-
|
|
5852
|
-
class Ship extends Types.entity_info {
|
|
5853
|
-
get name() {
|
|
5854
|
-
return this.entity_name;
|
|
5855
|
-
}
|
|
5856
|
-
get inv() {
|
|
5857
|
-
return (this._inv ?? (this._inv = new InventoryAccessor(this)));
|
|
5858
|
-
}
|
|
5859
|
-
get inventory() {
|
|
5860
|
-
return this.inv.items;
|
|
5861
|
-
}
|
|
5862
|
-
get sched() {
|
|
5863
|
-
return (this._sched ?? (this._sched = new ScheduleAccessor(this)));
|
|
5864
|
-
}
|
|
5865
|
-
get maxDistance() {
|
|
5866
|
-
if (!this.generator || !this.engines)
|
|
5867
|
-
return UInt32.from(0);
|
|
5868
|
-
return maxTravelDistance(this);
|
|
5869
|
-
}
|
|
5870
|
-
get isIdle() {
|
|
5871
|
-
return this.is_idle;
|
|
5872
|
-
}
|
|
5873
|
-
getFlightOrigin(flightTaskIndex) {
|
|
5874
|
-
return Coordinates.from(getFlightOrigin(this, flightTaskIndex));
|
|
5875
|
-
}
|
|
5876
|
-
destinationLocation() {
|
|
5877
|
-
const dest = getDestinationLocation(this);
|
|
5878
|
-
return dest ? Coordinates.from(dest) : undefined;
|
|
5879
|
-
}
|
|
5880
|
-
positionAt(now) {
|
|
5881
|
-
const taskIndex = this.sched.currentTaskIndex(now);
|
|
5882
|
-
const progress = this.sched.currentTaskProgress(now);
|
|
5883
|
-
return Coordinates.from(getPositionAt(this, taskIndex, progress));
|
|
5884
|
-
}
|
|
5885
|
-
isInFlight(now) {
|
|
5886
|
-
return isInFlight(this, now);
|
|
5887
|
-
}
|
|
5888
|
-
isRecharging(now) {
|
|
5889
|
-
return isRecharging(this, now);
|
|
5890
|
-
}
|
|
5891
|
-
isLoading(now) {
|
|
5892
|
-
return isLoading(this, now);
|
|
5893
|
-
}
|
|
5894
|
-
isUnloading(now) {
|
|
5895
|
-
return isUnloading(this, now);
|
|
5896
|
-
}
|
|
5897
|
-
isGathering(now) {
|
|
5898
|
-
return isGathering(this, now);
|
|
5899
|
-
}
|
|
5900
|
-
get hasEngines() {
|
|
5901
|
-
return this.engines !== undefined;
|
|
5902
|
-
}
|
|
5903
|
-
get hasGenerator() {
|
|
5904
|
-
return this.generator !== undefined;
|
|
5905
|
-
}
|
|
5906
|
-
get hasGatherer() {
|
|
5907
|
-
return this.gatherer !== undefined;
|
|
5908
|
-
}
|
|
5909
|
-
get hasWarp() {
|
|
5910
|
-
return this.warp !== undefined;
|
|
5911
|
-
}
|
|
5912
|
-
project() {
|
|
5913
|
-
return projectEntity(this);
|
|
5914
|
-
}
|
|
5915
|
-
projectAt(now) {
|
|
5916
|
-
return projectEntityAt(this, now);
|
|
5917
|
-
}
|
|
5918
|
-
get location() {
|
|
5919
|
-
return Location.from(this.coordinates);
|
|
5920
|
-
}
|
|
5921
|
-
get totalCargoMass() {
|
|
5922
|
-
return this.inv.totalMass;
|
|
5923
|
-
}
|
|
5924
|
-
get totalMass() {
|
|
5925
|
-
let mass = UInt64.from(this.hullmass ?? 0).adding(this.totalCargoMass);
|
|
5926
|
-
if (this.loaders) {
|
|
5927
|
-
mass = mass.adding(UInt64.from(this.loaders.mass).multiplying(this.loaders.quantity));
|
|
5928
|
-
}
|
|
5929
|
-
return mass;
|
|
5930
|
-
}
|
|
5931
|
-
get maxCapacity() {
|
|
5932
|
-
return UInt64.from(this.capacity);
|
|
5933
|
-
}
|
|
5934
|
-
hasSpace(goodMass, quantity) {
|
|
5935
|
-
return this.totalMass.adding(goodMass.multiplying(quantity)).lte(this.maxCapacity);
|
|
5936
|
-
}
|
|
5937
|
-
get availableCapacity() {
|
|
5938
|
-
return this.totalMass.gte(this.maxCapacity)
|
|
5939
|
-
? UInt64.from(0)
|
|
5940
|
-
: this.maxCapacity.subtracting(this.totalMass);
|
|
5941
|
-
}
|
|
5942
|
-
getCargoForItem(goodId) {
|
|
5943
|
-
return this.inv.forItem(goodId);
|
|
5944
|
-
}
|
|
5945
|
-
get sellableCargo() {
|
|
5946
|
-
return this.inv.sellable;
|
|
5947
|
-
}
|
|
5948
|
-
get hasSellableCargo() {
|
|
5949
|
-
return this.inv.hasSellable;
|
|
5950
|
-
}
|
|
5951
|
-
get sellableGoodsCount() {
|
|
5952
|
-
return this.inv.sellableCount;
|
|
5953
|
-
}
|
|
5954
|
-
get isFull() {
|
|
5955
|
-
return this.totalMass.gte(this.maxCapacity);
|
|
5956
|
-
}
|
|
5957
|
-
get energyPercent() {
|
|
5958
|
-
if (!this.generator || this.energy === undefined)
|
|
5959
|
-
return 0;
|
|
5960
|
-
return energyPercent(this);
|
|
5961
|
-
}
|
|
5962
|
-
get needsRecharge() {
|
|
5963
|
-
if (!this.generator || this.energy === undefined)
|
|
5964
|
-
return false;
|
|
5965
|
-
return needsRecharge(this);
|
|
5966
|
-
}
|
|
5967
|
-
hasEnergyFor(distance) {
|
|
5968
|
-
if (!this.engines || !this.generator || this.energy === undefined)
|
|
5969
|
-
return false;
|
|
5970
|
-
return hasEnergyForDistance(this, distance);
|
|
5971
|
-
}
|
|
5972
|
-
}
|
|
5973
|
-
|
|
5974
|
-
class Warehouse extends Types.entity_info {
|
|
5975
|
-
get name() {
|
|
5976
|
-
return this.entity_name;
|
|
5977
|
-
}
|
|
5978
|
-
get inv() {
|
|
5979
|
-
return (this._inv ?? (this._inv = new InventoryAccessor(this)));
|
|
5980
|
-
}
|
|
5981
|
-
get inventory() {
|
|
5982
|
-
return this.inv.items;
|
|
5983
|
-
}
|
|
5984
|
-
get sched() {
|
|
5985
|
-
return (this._sched ?? (this._sched = new ScheduleAccessor(this)));
|
|
5986
|
-
}
|
|
5987
|
-
get isIdle() {
|
|
5988
|
-
return this.is_idle;
|
|
5989
|
-
}
|
|
5990
|
-
isLoading(now) {
|
|
5991
|
-
return isLoading(this, now);
|
|
5992
|
-
}
|
|
5993
|
-
isUnloading(now) {
|
|
5994
|
-
return isUnloading(this, now);
|
|
5995
|
-
}
|
|
5996
|
-
get location() {
|
|
5997
|
-
return Location.from(this.coordinates);
|
|
5998
|
-
}
|
|
5999
|
-
get totalCargoMass() {
|
|
6000
|
-
return this.inv.totalMass;
|
|
6001
|
-
}
|
|
6002
|
-
get maxCapacity() {
|
|
6003
|
-
return UInt64.from(this.capacity);
|
|
6004
|
-
}
|
|
6005
|
-
get availableCapacity() {
|
|
6006
|
-
const cargo = this.totalCargoMass;
|
|
6007
|
-
return cargo.gte(this.maxCapacity) ? UInt64.from(0) : this.maxCapacity.subtracting(cargo);
|
|
6008
|
-
}
|
|
6009
|
-
hasSpace(goodMass, quantity) {
|
|
6010
|
-
return this.totalCargoMass.adding(goodMass.multiplying(quantity)).lte(this.maxCapacity);
|
|
6011
|
-
}
|
|
6012
|
-
get isFull() {
|
|
6013
|
-
return this.totalCargoMass.gte(this.maxCapacity);
|
|
6014
|
-
}
|
|
6015
|
-
getCargoForItem(goodId) {
|
|
6016
|
-
return this.inv.forItem(goodId);
|
|
6017
|
-
}
|
|
6018
|
-
get orbitalAltitude() {
|
|
6019
|
-
return this.coordinates.z?.toNumber() || 0;
|
|
6020
|
-
}
|
|
6021
|
-
get totalMass() {
|
|
6022
|
-
const hull = this.hullmass ? UInt64.from(this.hullmass) : UInt64.from(0);
|
|
6023
|
-
return hull.adding(this.totalCargoMass);
|
|
6024
|
-
}
|
|
6025
|
-
}
|
|
6026
|
-
|
|
6027
|
-
class Container extends Types.entity_info {
|
|
6028
|
-
get name() {
|
|
6029
|
-
return this.entity_name;
|
|
6030
|
-
}
|
|
6031
|
-
get sched() {
|
|
6032
|
-
return (this._sched ?? (this._sched = new ScheduleAccessor(this)));
|
|
6033
|
-
}
|
|
6034
|
-
get isIdle() {
|
|
6035
|
-
return this.is_idle;
|
|
6036
|
-
}
|
|
6037
|
-
isLoading(now) {
|
|
6038
|
-
return isLoading(this, now);
|
|
6039
|
-
}
|
|
6040
|
-
isUnloading(now) {
|
|
6041
|
-
return isUnloading(this, now);
|
|
6042
|
-
}
|
|
6043
|
-
get location() {
|
|
6044
|
-
return Location.from(this.coordinates);
|
|
6045
|
-
}
|
|
6046
|
-
get totalMass() {
|
|
6047
|
-
return UInt64.from(this.hullmass ?? 0).adding(this.cargomass);
|
|
6048
|
-
}
|
|
6049
|
-
get maxCapacity() {
|
|
6050
|
-
return UInt64.from(this.capacity);
|
|
6051
|
-
}
|
|
6052
|
-
get availableCapacity() {
|
|
6053
|
-
const cargo = UInt64.from(this.cargomass);
|
|
6054
|
-
return cargo.gte(this.maxCapacity) ? UInt64.from(0) : this.maxCapacity.subtracting(cargo);
|
|
6055
|
-
}
|
|
6056
|
-
hasSpace(additionalMass) {
|
|
6057
|
-
return UInt64.from(this.cargomass).adding(additionalMass).lte(this.maxCapacity);
|
|
6058
|
-
}
|
|
6059
|
-
get isFull() {
|
|
6060
|
-
return UInt64.from(this.cargomass).gte(this.maxCapacity);
|
|
6061
|
-
}
|
|
6062
|
-
get orbitalAltitude() {
|
|
6063
|
-
return this.coordinates.z?.toNumber() || 0;
|
|
6064
|
-
}
|
|
6065
|
-
}
|
|
6066
|
-
function computeContainerCapabilities(stats) {
|
|
6067
|
-
const density = stats['density'] ?? 500;
|
|
6068
|
-
const strength = stats['strength'] ?? 500;
|
|
6069
|
-
const ductility = stats['ductility'] ?? 500;
|
|
6070
|
-
const purity = stats['purity'] ?? 500;
|
|
6071
|
-
const hullmass = 25000 + 75 * density;
|
|
6072
|
-
const statSum = strength + ductility + purity;
|
|
6073
|
-
const exponent = statSum / 2997;
|
|
6074
|
-
const capacity = Math.floor(1000000 * Math.pow(10, exponent));
|
|
6075
|
-
return { hullmass, capacity };
|
|
6076
|
-
}
|
|
6077
|
-
function computeContainerT2Capabilities(stats) {
|
|
6078
|
-
const strength = stats['strength'] ?? 0;
|
|
6079
|
-
const density = stats['density'] ?? 0;
|
|
6080
|
-
const ductility = stats['ductility'] ?? 0;
|
|
6081
|
-
const purity = stats['purity'] ?? 0;
|
|
6082
|
-
const hullmass = 20000 + 50 * density;
|
|
6083
|
-
const statSum = strength + ductility + purity;
|
|
6084
|
-
const exponent = statSum / 2500;
|
|
6085
|
-
const capacity = Math.floor(1500000 * Math.pow(10, exponent));
|
|
6086
|
-
return { hullmass, capacity };
|
|
6087
|
-
}
|
|
6088
|
-
|
|
6089
|
-
class EntitiesManager extends BaseManager {
|
|
6090
|
-
async getEntity(type, id) {
|
|
6091
|
-
const result = await this.server.readonly('getentity', {
|
|
6092
|
-
entity_type: Name.from(type),
|
|
6093
|
-
entity_id: id,
|
|
6094
|
-
});
|
|
6095
|
-
const entityInfo = result;
|
|
6096
|
-
return this.wrapEntity(entityInfo);
|
|
6097
|
-
}
|
|
6098
|
-
async getEntities(owner, type) {
|
|
6099
|
-
const ownerName = this.resolveOwner(owner);
|
|
6100
|
-
const result = await this.server.readonly('getentities', {
|
|
6101
|
-
owner: ownerName,
|
|
6102
|
-
entity_type: type ? Name.from(type) : null,
|
|
6103
|
-
});
|
|
6104
|
-
const entities = result;
|
|
6105
|
-
return entities.map((entity) => this.wrapEntity(entity));
|
|
6106
|
-
}
|
|
6107
|
-
async getSummaries(owner, type) {
|
|
6108
|
-
const ownerName = this.resolveOwner(owner);
|
|
6109
|
-
const result = await this.server.readonly('getsummaries', {
|
|
6110
|
-
owner: ownerName,
|
|
6111
|
-
entity_type: type ? Name.from(type) : null,
|
|
6112
|
-
});
|
|
6113
|
-
return result;
|
|
6114
|
-
}
|
|
6115
|
-
async getShip(id) {
|
|
6116
|
-
return (await this.getEntity('ship', id));
|
|
6117
|
-
}
|
|
6118
|
-
async getWarehouse(id) {
|
|
6119
|
-
return (await this.getEntity('warehouse', id));
|
|
6120
|
-
}
|
|
6121
|
-
async getContainer(id) {
|
|
6122
|
-
return (await this.getEntity('container', id));
|
|
6123
|
-
}
|
|
6124
|
-
async getShips(owner) {
|
|
6125
|
-
return (await this.getEntities(owner, 'ship'));
|
|
6126
|
-
}
|
|
6127
|
-
async getWarehouses(owner) {
|
|
6128
|
-
return (await this.getEntities(owner, 'warehouse'));
|
|
6129
|
-
}
|
|
6130
|
-
async getContainers(owner) {
|
|
6131
|
-
return (await this.getEntities(owner, 'container'));
|
|
6132
|
-
}
|
|
6133
|
-
async getShipSummaries(owner) {
|
|
6134
|
-
return this.getSummaries(owner, 'ship');
|
|
6135
|
-
}
|
|
6136
|
-
async getWarehouseSummaries(owner) {
|
|
6137
|
-
return this.getSummaries(owner, 'warehouse');
|
|
6138
|
-
}
|
|
6139
|
-
async getContainerSummaries(owner) {
|
|
6140
|
-
return this.getSummaries(owner, 'container');
|
|
6141
|
-
}
|
|
6142
|
-
wrapEntity(entity) {
|
|
6143
|
-
if (entity.type.equals('ship')) {
|
|
6144
|
-
return new Ship(entity);
|
|
6145
|
-
}
|
|
6146
|
-
else if (entity.type.equals('warehouse')) {
|
|
6147
|
-
return new Warehouse(entity);
|
|
6148
|
-
}
|
|
6149
|
-
else {
|
|
6150
|
-
return new Container(entity);
|
|
6151
|
-
}
|
|
6152
|
-
}
|
|
6153
|
-
resolveOwner(owner) {
|
|
6154
|
-
if (typeof owner === 'object' && owner !== null && 'owner' in owner) {
|
|
6155
|
-
return owner.owner;
|
|
6156
|
-
}
|
|
6157
|
-
return Name.from(owner);
|
|
6158
|
-
}
|
|
6159
|
-
}
|
|
6160
|
-
|
|
6161
|
-
class Player extends Types.player_row {
|
|
6162
|
-
static fromState(state) {
|
|
6163
|
-
const playerRow = Types.player_row.from({
|
|
6164
|
-
owner: Name.from(state.owner),
|
|
6165
|
-
});
|
|
6166
|
-
return new Player(playerRow);
|
|
6167
|
-
}
|
|
6168
|
-
}
|
|
6169
|
-
|
|
6170
|
-
class PlayersManager extends BaseManager {
|
|
6171
|
-
async getPlayer(account) {
|
|
6172
|
-
const playerRow = await this.server.table('player').get(Name.from(account));
|
|
6173
|
-
if (!playerRow) {
|
|
6174
|
-
return undefined;
|
|
6175
|
-
}
|
|
6176
|
-
return new Player(playerRow);
|
|
6177
|
-
}
|
|
6178
|
-
}
|
|
6179
|
-
|
|
6180
|
-
class LocationsManager extends BaseManager {
|
|
6181
|
-
async hasSystem(location) {
|
|
6182
|
-
const game = await this.getGame();
|
|
6183
|
-
return hasSystem(game.config.seed, location);
|
|
6184
|
-
}
|
|
6185
|
-
async findNearbyPlanets(origin, maxDistance = 20) {
|
|
6186
|
-
const game = await this.getGame();
|
|
6187
|
-
return findNearbyPlanets(game.config.seed, origin, maxDistance);
|
|
6188
|
-
}
|
|
6189
|
-
async getLocationEntity(id) {
|
|
6190
|
-
const row = await this.server.table('location').get(UInt64.from(id));
|
|
6191
|
-
return row ?? undefined;
|
|
6192
|
-
}
|
|
6193
|
-
async getLocationEntityAt(coords) {
|
|
6194
|
-
const id = coordsToLocationId(coords);
|
|
6195
|
-
return this.getLocationEntity(id);
|
|
6196
|
-
}
|
|
6197
|
-
async getAllLocationEntities() {
|
|
6198
|
-
return this.server.table('location').all();
|
|
6199
|
-
}
|
|
6200
|
-
}
|
|
6201
|
-
|
|
6202
|
-
class EpochsManager extends BaseManager {
|
|
6203
|
-
async getCurrentHeight() {
|
|
6204
|
-
const game = await this.getGame();
|
|
6205
|
-
return getCurrentEpoch(game);
|
|
6206
|
-
}
|
|
6207
|
-
async getCurrent() {
|
|
6208
|
-
const game = await this.getGame();
|
|
6209
|
-
const epoch = await this.getCurrentHeight();
|
|
6210
|
-
return getEpochInfo(game, epoch);
|
|
6211
|
-
}
|
|
6212
|
-
async getByHeight(height) {
|
|
6213
|
-
const game = await this.getGame();
|
|
6214
|
-
return getEpochInfo(game, UInt64.from(height));
|
|
6215
|
-
}
|
|
6216
|
-
async getTimeRemaining() {
|
|
6217
|
-
const epochInfo = await this.getCurrent();
|
|
6218
|
-
const now = Date.now();
|
|
6219
|
-
const endTime = epochInfo.end.getTime();
|
|
6220
|
-
return Math.max(0, endTime - now);
|
|
6221
|
-
}
|
|
6222
|
-
async getProgress() {
|
|
6223
|
-
const epochInfo = await this.getCurrent();
|
|
6224
|
-
const now = Date.now();
|
|
6225
|
-
const startTime = epochInfo.start.getTime();
|
|
6226
|
-
const endTime = epochInfo.end.getTime();
|
|
6227
|
-
const duration = endTime - startTime;
|
|
6228
|
-
const elapsed = now - startTime;
|
|
6229
|
-
if (elapsed <= 0)
|
|
6230
|
-
return 0;
|
|
6231
|
-
if (elapsed >= duration)
|
|
6232
|
-
return 1;
|
|
6233
|
-
return elapsed / duration;
|
|
6234
|
-
}
|
|
6235
|
-
async fitsInCurrentEpoch(durationMs) {
|
|
6236
|
-
const remaining = await this.getTimeRemaining();
|
|
6237
|
-
return durationMs <= remaining;
|
|
6238
|
-
}
|
|
6239
|
-
}
|
|
6240
|
-
|
|
6241
|
-
class ActionsManager extends BaseManager {
|
|
6242
|
-
travel(shipId, destination, recharge = true) {
|
|
6243
|
-
const x = Int64.from(destination.x);
|
|
6244
|
-
const y = Int64.from(destination.y);
|
|
6245
|
-
return this.server.action('travel', {
|
|
6246
|
-
entity_type: EntityType.SHIP,
|
|
6247
|
-
id: UInt64.from(shipId),
|
|
6248
|
-
x,
|
|
6249
|
-
y,
|
|
6250
|
-
recharge,
|
|
6251
|
-
});
|
|
6252
|
-
}
|
|
6253
|
-
grouptravel(entities, destination, recharge = true) {
|
|
6254
|
-
const entityRefs = entities.map((e) => Types.entity_ref.from({
|
|
6255
|
-
entity_type: e.entityType,
|
|
6256
|
-
entity_id: UInt64.from(e.entityId),
|
|
6257
|
-
}));
|
|
6258
|
-
const x = Int64.from(destination.x);
|
|
6259
|
-
const y = Int64.from(destination.y);
|
|
6260
|
-
return this.server.action('grouptravel', {
|
|
6261
|
-
entities: entityRefs,
|
|
6262
|
-
x,
|
|
6263
|
-
y,
|
|
6264
|
-
recharge,
|
|
6265
|
-
});
|
|
6266
|
-
}
|
|
6267
|
-
resolve(entityId, entityType = EntityType.SHIP) {
|
|
6268
|
-
return this.server.action('resolve', {
|
|
6269
|
-
entity_type: entityType,
|
|
6270
|
-
id: UInt64.from(entityId),
|
|
6271
|
-
});
|
|
6272
|
-
}
|
|
6273
|
-
cancel(entityId, count, entityType = EntityType.SHIP) {
|
|
6274
|
-
return this.server.action('cancel', {
|
|
6275
|
-
entity_type: entityType,
|
|
6276
|
-
id: UInt64.from(entityId),
|
|
6277
|
-
count: UInt64.from(count),
|
|
6278
|
-
});
|
|
6279
|
-
}
|
|
6280
|
-
recharge(shipId) {
|
|
6281
|
-
return this.server.action('recharge', {
|
|
6282
|
-
entity_type: EntityType.SHIP,
|
|
6283
|
-
id: UInt64.from(shipId),
|
|
6284
|
-
});
|
|
6285
|
-
}
|
|
6286
|
-
transfer(sourceType, sourceId, destType, destId, goodId, quantity) {
|
|
6287
|
-
return this.server.action('transfer', {
|
|
6288
|
-
source_type: sourceType,
|
|
6289
|
-
source_id: UInt64.from(sourceId),
|
|
6290
|
-
dest_type: destType,
|
|
6291
|
-
dest_id: UInt64.from(destId),
|
|
6292
|
-
item_id: UInt16.from(goodId),
|
|
6293
|
-
quantity: UInt32.from(quantity),
|
|
6294
|
-
});
|
|
6295
|
-
}
|
|
6296
|
-
foundCompany(account, name) {
|
|
6297
|
-
return this.platform.action('foundcompany', {
|
|
6298
|
-
account: Name.from(account),
|
|
6299
|
-
name,
|
|
6300
|
-
});
|
|
6301
|
-
}
|
|
6302
|
-
join(account) {
|
|
6303
|
-
return this.server.action('join', {
|
|
6304
|
-
account: Name.from(account),
|
|
6305
|
-
});
|
|
6306
|
-
}
|
|
6307
|
-
gather(shipId, stratum, quantity) {
|
|
6308
|
-
return this.server.action('gather', {
|
|
6309
|
-
entity_type: EntityType.SHIP,
|
|
6310
|
-
id: UInt64.from(shipId),
|
|
6311
|
-
stratum: UInt16.from(stratum),
|
|
6312
|
-
quantity: UInt32.from(quantity),
|
|
6313
|
-
});
|
|
6314
|
-
}
|
|
6315
|
-
warp(shipId, destination) {
|
|
6316
|
-
const x = Int64.from(destination.x);
|
|
6317
|
-
const y = Int64.from(destination.y);
|
|
6318
|
-
return this.server.action('warp', {
|
|
6319
|
-
entity_type: EntityType.SHIP,
|
|
6320
|
-
id: UInt64.from(shipId),
|
|
6321
|
-
x,
|
|
6322
|
-
y,
|
|
6323
|
-
});
|
|
6324
|
-
}
|
|
6325
|
-
craft(entityType, entityId, recipeId, quantity, inputs) {
|
|
6326
|
-
const cargoInputs = inputs.map((i) => Types.cargo_item.from(i));
|
|
6327
|
-
return this.server.action('craft', {
|
|
6328
|
-
entity_type: entityType,
|
|
6329
|
-
id: UInt64.from(entityId),
|
|
6330
|
-
recipe_id: UInt16.from(recipeId),
|
|
6331
|
-
quantity: UInt32.from(quantity),
|
|
6332
|
-
inputs: cargoInputs,
|
|
6333
|
-
});
|
|
6334
|
-
}
|
|
6335
|
-
blend(entityType, entityId, inputs) {
|
|
6336
|
-
const cargoInputs = inputs.map((i) => Types.cargo_item.from(i));
|
|
6337
|
-
return this.server.action('blend', {
|
|
6338
|
-
entity_type: entityType,
|
|
6339
|
-
id: UInt64.from(entityId),
|
|
6340
|
-
inputs: cargoInputs,
|
|
6341
|
-
});
|
|
6342
|
-
}
|
|
6343
|
-
deploy(entityType, entityId, packedItemId, seed, entityName) {
|
|
6344
|
-
return this.server.action('deploy', {
|
|
6345
|
-
entity_type: entityType,
|
|
6346
|
-
id: UInt64.from(entityId),
|
|
6347
|
-
packed_item_id: UInt16.from(packedItemId),
|
|
6348
|
-
seed: UInt64.from(seed),
|
|
6349
|
-
entity_name: entityName,
|
|
6350
|
-
});
|
|
6351
|
-
}
|
|
6352
|
-
addmodule(entityType, entityId, moduleIndex, moduleCargoId, targetCargoId = UInt64.from(0)) {
|
|
6353
|
-
return this.server.action('addmodule', {
|
|
6354
|
-
entity_type: entityType,
|
|
6355
|
-
entity_id: UInt64.from(entityId),
|
|
6356
|
-
module_index: moduleIndex,
|
|
6357
|
-
module_cargo_id: UInt64.from(moduleCargoId),
|
|
6358
|
-
target_cargo_id: UInt64.from(targetCargoId),
|
|
6359
|
-
});
|
|
6360
|
-
}
|
|
6361
|
-
rmmodule(entityType, entityId, moduleIndex, targetCargoId = UInt64.from(0)) {
|
|
6362
|
-
return this.server.action('rmmodule', {
|
|
6363
|
-
entity_type: entityType,
|
|
6364
|
-
entity_id: UInt64.from(entityId),
|
|
6365
|
-
module_index: moduleIndex,
|
|
6366
|
-
target_cargo_id: UInt64.from(targetCargoId),
|
|
6367
|
-
});
|
|
6368
|
-
}
|
|
6369
|
-
joinGame(account, companyName) {
|
|
6370
|
-
return [this.foundCompany(account, companyName), this.join(account)];
|
|
6371
|
-
}
|
|
6372
|
-
}
|
|
6373
|
-
|
|
6374
|
-
class GameContext {
|
|
6375
|
-
constructor(client, server, platform) {
|
|
6376
|
-
this.client = client;
|
|
6377
|
-
this.server = server;
|
|
6378
|
-
this.platform = platform;
|
|
6379
|
-
}
|
|
6380
|
-
get entities() {
|
|
6381
|
-
if (!this._entities) {
|
|
6382
|
-
this._entities = new EntitiesManager(this);
|
|
6383
|
-
}
|
|
6384
|
-
return this._entities;
|
|
6385
|
-
}
|
|
6386
|
-
get players() {
|
|
6387
|
-
if (!this._players) {
|
|
6388
|
-
this._players = new PlayersManager(this);
|
|
6389
|
-
}
|
|
6390
|
-
return this._players;
|
|
6391
|
-
}
|
|
6392
|
-
get locations() {
|
|
6393
|
-
if (!this._locations) {
|
|
6394
|
-
this._locations = new LocationsManager(this);
|
|
6395
|
-
}
|
|
6396
|
-
return this._locations;
|
|
6397
|
-
}
|
|
6398
|
-
get epochs() {
|
|
6399
|
-
if (!this._epochs) {
|
|
6400
|
-
this._epochs = new EpochsManager(this);
|
|
6401
|
-
}
|
|
6402
|
-
return this._epochs;
|
|
6403
|
-
}
|
|
6404
|
-
get actions() {
|
|
6405
|
-
if (!this._actions) {
|
|
6406
|
-
this._actions = new ActionsManager(this);
|
|
6407
|
-
}
|
|
6408
|
-
return this._actions;
|
|
6409
|
-
}
|
|
6410
|
-
async getGame(reload = false) {
|
|
6411
|
-
if (!reload && this._gameCache) {
|
|
6412
|
-
return this._gameCache;
|
|
6413
|
-
}
|
|
6414
|
-
const game = await this.platform.table('games').get();
|
|
6415
|
-
if (!game) {
|
|
6416
|
-
throw new Error('Game not initialized');
|
|
6417
|
-
}
|
|
6418
|
-
this._gameCache = game;
|
|
6419
|
-
return game;
|
|
6420
|
-
}
|
|
6421
|
-
async getState(reload = false) {
|
|
6422
|
-
if (!reload && this._stateCache) {
|
|
6423
|
-
return this._stateCache;
|
|
6424
|
-
}
|
|
6425
|
-
const state = await this.server.table('state').get();
|
|
6426
|
-
if (!state) {
|
|
6427
|
-
throw new Error('Game state not initialized');
|
|
6428
|
-
}
|
|
6429
|
-
const game = this._gameCache;
|
|
6430
|
-
this._stateCache = GameState.from(state, game);
|
|
6431
|
-
return this._stateCache;
|
|
6432
|
-
}
|
|
6433
|
-
get cachedGame() {
|
|
6434
|
-
return this._gameCache;
|
|
6435
|
-
}
|
|
6436
|
-
get cachedState() {
|
|
6437
|
-
return this._stateCache;
|
|
6438
|
-
}
|
|
6439
|
-
}
|
|
6440
|
-
|
|
6441
|
-
class Shipload {
|
|
6442
|
-
constructor(chain, constructorOptions) {
|
|
6443
|
-
const { client, platformContract, serverContract } = constructorOptions || {};
|
|
6444
|
-
const apiClient = client || new APIClient({ url: chain.url });
|
|
6445
|
-
const platform$1 = platformContract
|
|
6446
|
-
? platformContract
|
|
6447
|
-
: new Contract$1({ client: apiClient });
|
|
6448
|
-
const server$1 = serverContract
|
|
6449
|
-
? serverContract
|
|
6450
|
-
: new Contract({ client: apiClient });
|
|
6451
|
-
this._context = new GameContext(apiClient, server$1, platform$1);
|
|
6452
|
-
}
|
|
6453
|
-
static async load(chain, shiploadOptions) {
|
|
6454
|
-
let platform$1 = new Contract$1({
|
|
6455
|
-
client: new APIClient({ url: chain.url }),
|
|
6456
|
-
});
|
|
6457
|
-
if (shiploadOptions?.platformContractName) {
|
|
6458
|
-
const client = shiploadOptions.client || new APIClient({ url: chain.url });
|
|
6459
|
-
const contractKit = new ContractKit({ client });
|
|
6460
|
-
platform$1 = await contractKit.load(shiploadOptions.platformContractName);
|
|
6461
|
-
}
|
|
6462
|
-
let server$1 = new Contract({
|
|
6463
|
-
client: new APIClient({ url: chain.url }),
|
|
6464
|
-
});
|
|
6465
|
-
if (shiploadOptions?.serverContractName) {
|
|
6466
|
-
const client = shiploadOptions.client || new APIClient({ url: chain.url });
|
|
6467
|
-
const contractKit = new ContractKit({ client });
|
|
6468
|
-
server$1 = await contractKit.load(shiploadOptions.serverContractName);
|
|
6469
|
-
}
|
|
6470
|
-
return new Shipload(chain, {
|
|
6471
|
-
...shiploadOptions,
|
|
6472
|
-
platformContract: platform$1,
|
|
6473
|
-
serverContract: server$1,
|
|
6474
|
-
});
|
|
6475
|
-
}
|
|
6476
|
-
get client() {
|
|
6477
|
-
return this._context.client;
|
|
6478
|
-
}
|
|
6479
|
-
get server() {
|
|
6480
|
-
return this._context.server;
|
|
6481
|
-
}
|
|
6482
|
-
get platform() {
|
|
6483
|
-
return this._context.platform;
|
|
6484
|
-
}
|
|
6485
|
-
get entities() {
|
|
6486
|
-
return this._context.entities;
|
|
6487
|
-
}
|
|
6488
|
-
get players() {
|
|
6489
|
-
return this._context.players;
|
|
6490
|
-
}
|
|
6491
|
-
get locations() {
|
|
6492
|
-
return this._context.locations;
|
|
6493
|
-
}
|
|
6494
|
-
get epochs() {
|
|
6495
|
-
return this._context.epochs;
|
|
6496
|
-
}
|
|
6497
|
-
get actions() {
|
|
6498
|
-
return this._context.actions;
|
|
6499
|
-
}
|
|
6500
|
-
async getGame(reload = false) {
|
|
6501
|
-
return this._context.getGame(reload);
|
|
6502
|
-
}
|
|
6503
|
-
async getState(reload = false) {
|
|
6504
|
-
return this._context.getState(reload);
|
|
6505
|
-
}
|
|
6506
|
-
}
|
|
6507
|
-
|
|
6508
|
-
function makeShip(state) {
|
|
6509
|
-
const info = {
|
|
6510
|
-
type: Name.from('ship'),
|
|
6511
|
-
id: UInt64.from(state.id),
|
|
6512
|
-
owner: Name.from(state.owner),
|
|
6513
|
-
entity_name: state.name,
|
|
6514
|
-
coordinates: Types.coordinates.from(state.coordinates),
|
|
6515
|
-
cargomass: UInt32.from(0),
|
|
6516
|
-
cargo: state.cargo || [],
|
|
6517
|
-
is_idle: !state.schedule,
|
|
6518
|
-
current_task_elapsed: UInt32.from(0),
|
|
6519
|
-
current_task_remaining: UInt32.from(0),
|
|
6520
|
-
pending_tasks: [],
|
|
6521
|
-
};
|
|
6522
|
-
if (state.hullmass !== undefined)
|
|
6523
|
-
info.hullmass = UInt32.from(state.hullmass);
|
|
6524
|
-
if (state.capacity !== undefined)
|
|
6525
|
-
info.capacity = UInt32.from(state.capacity);
|
|
6526
|
-
if (state.energy !== undefined)
|
|
6527
|
-
info.energy = UInt16.from(state.energy);
|
|
6528
|
-
if (state.engines)
|
|
6529
|
-
info.engines = state.engines;
|
|
6530
|
-
if (state.generator)
|
|
6531
|
-
info.generator = state.generator;
|
|
6532
|
-
if (state.loaders)
|
|
6533
|
-
info.loaders = state.loaders;
|
|
6534
|
-
if (state.schedule)
|
|
6535
|
-
info.schedule = state.schedule;
|
|
6536
|
-
const entityInfo = Types.entity_info.from(info);
|
|
6537
|
-
return new Ship(entityInfo);
|
|
6538
|
-
}
|
|
6539
|
-
function makeWarehouse(state) {
|
|
6540
|
-
const info = {
|
|
6541
|
-
type: Name.from('warehouse'),
|
|
6542
|
-
id: UInt64.from(state.id),
|
|
6543
|
-
owner: Name.from(state.owner),
|
|
6544
|
-
entity_name: state.name,
|
|
6545
|
-
coordinates: Types.coordinates.from(state.coordinates),
|
|
6546
|
-
capacity: UInt32.from(state.capacity),
|
|
6547
|
-
cargomass: UInt32.from(0),
|
|
6548
|
-
cargo: state.cargo || [],
|
|
6549
|
-
is_idle: !state.schedule,
|
|
6550
|
-
current_task_elapsed: UInt32.from(0),
|
|
6551
|
-
current_task_remaining: UInt32.from(0),
|
|
6552
|
-
pending_tasks: [],
|
|
6553
|
-
};
|
|
6554
|
-
if (state.hullmass !== undefined)
|
|
6555
|
-
info.hullmass = UInt32.from(state.hullmass);
|
|
6556
|
-
if (state.loaders)
|
|
6557
|
-
info.loaders = state.loaders;
|
|
6558
|
-
if (state.schedule)
|
|
6559
|
-
info.schedule = state.schedule;
|
|
6560
|
-
const entityInfo = Types.entity_info.from(info);
|
|
6561
|
-
return new Warehouse(entityInfo);
|
|
6562
|
-
}
|
|
6563
|
-
function makeContainer(state) {
|
|
6564
|
-
const entityInfo = Types.entity_info.from({
|
|
6565
|
-
type: Name.from('container'),
|
|
6566
|
-
id: UInt64.from(state.id),
|
|
6567
|
-
owner: Name.from(state.owner),
|
|
6568
|
-
entity_name: state.name,
|
|
6569
|
-
coordinates: Types.coordinates.from(state.coordinates),
|
|
6570
|
-
hullmass: UInt32.from(state.hullmass),
|
|
6571
|
-
capacity: UInt32.from(state.capacity),
|
|
6572
|
-
cargomass: UInt32.from(state.cargomass || 0),
|
|
6573
|
-
cargo: [],
|
|
6574
|
-
is_idle: !state.schedule,
|
|
6575
|
-
current_task_elapsed: UInt32.from(0),
|
|
6576
|
-
current_task_remaining: UInt32.from(0),
|
|
6577
|
-
pending_tasks: [],
|
|
6578
|
-
schedule: state.schedule,
|
|
6579
|
-
});
|
|
6580
|
-
return new Container(entityInfo);
|
|
6581
|
-
}
|
|
6582
|
-
|
|
6583
|
-
function deriveStratum(epochSeed, coords, stratum, locationType, subtype, _maxDepth) {
|
|
6584
|
-
const seed = Checksum256.from(epochSeed);
|
|
6585
|
-
const c = Coordinates.from(coords);
|
|
6586
|
-
const input = `stratum-${c.x}-${c.y}-${stratum}`;
|
|
6587
|
-
const hashResult = hash512(seed, input);
|
|
6588
|
-
const bytes = hashResult.array;
|
|
6589
|
-
const rawReserve = ((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]) >>> 0;
|
|
6590
|
-
let reserve = 0;
|
|
6591
|
-
if (rawReserve <= YIELD_THRESHOLD) {
|
|
6592
|
-
const baseReserve = (rawReserve % 333) + 1;
|
|
6593
|
-
const scale = depthScaleFactor(stratum);
|
|
6594
|
-
reserve = Math.floor(baseReserve * scale);
|
|
6595
|
-
}
|
|
6596
|
-
if (reserve === 0)
|
|
6597
|
-
return { itemId: 0, seed: 0n, richness: 0, reserve: 0 };
|
|
6598
|
-
const eligible = getEligibleResources(locationType, subtype, stratum);
|
|
6599
|
-
if (eligible.length === 0)
|
|
6600
|
-
return { itemId: 0, seed: 0n, richness: 0, reserve: 0 };
|
|
6601
|
-
const resourceRoll = ((bytes[4] << 24) | (bytes[5] << 16) | (bytes[6] << 8) | bytes[7]) >>> 0;
|
|
6602
|
-
let totalWeight = 0;
|
|
6603
|
-
for (const id of eligible) {
|
|
6604
|
-
totalWeight += getResourceWeight(id, stratum);
|
|
6605
|
-
}
|
|
6606
|
-
let selectedItemId = eligible[0];
|
|
6607
|
-
if (totalWeight > 0) {
|
|
6608
|
-
const roll = resourceRoll % totalWeight;
|
|
6609
|
-
let cumulative = 0;
|
|
6610
|
-
for (const id of eligible) {
|
|
6611
|
-
cumulative += getResourceWeight(id, stratum);
|
|
6612
|
-
if (roll < cumulative) {
|
|
6613
|
-
selectedItemId = id;
|
|
6614
|
-
break;
|
|
6615
|
-
}
|
|
6616
|
-
}
|
|
6617
|
-
}
|
|
6618
|
-
const seedBigInt = (BigInt(bytes[8]) << 56n) |
|
|
6619
|
-
(BigInt(bytes[9]) << 48n) |
|
|
6620
|
-
(BigInt(bytes[10]) << 40n) |
|
|
6621
|
-
(BigInt(bytes[11]) << 32n) |
|
|
6622
|
-
(BigInt(bytes[12]) << 24n) |
|
|
6623
|
-
(BigInt(bytes[13]) << 16n) |
|
|
6624
|
-
(BigInt(bytes[14]) << 8n) |
|
|
6625
|
-
BigInt(bytes[15]);
|
|
6626
|
-
const rawRichness = (bytes[16] << 8) | bytes[17];
|
|
6627
|
-
const normalized = rawRichness / 65535;
|
|
6628
|
-
const baseRichness = Math.floor(normalized * normalized * 999) + 1;
|
|
6629
|
-
let depthBonus = 0;
|
|
6630
|
-
if (stratum > 1) {
|
|
6631
|
-
depthBonus = (50 * Math.log(stratum)) / Math.log(65535);
|
|
6632
|
-
}
|
|
6633
|
-
const richness = Math.min(Math.floor(baseRichness + depthBonus), 1000);
|
|
6634
|
-
return { itemId: selectedItemId, seed: seedBigInt, richness, reserve };
|
|
6635
|
-
}
|
|
6636
|
-
function deriveResourceStats(seed) {
|
|
6637
|
-
const seedBytes = new Uint8Array(8);
|
|
6638
|
-
for (let i = 0; i < 8; i++) {
|
|
6639
|
-
seedBytes[i] = Number(seed & 0xffn);
|
|
6640
|
-
seed >>= 8n;
|
|
6641
|
-
}
|
|
6642
|
-
const hashResult = Checksum256.hash(Bytes.from(seedBytes));
|
|
6643
|
-
const hashBytes = hashResult.array;
|
|
6644
|
-
const extractU32 = (offset) => (hashBytes[offset] * 0x1000000 +
|
|
6645
|
-
(hashBytes[offset + 1] << 16) +
|
|
6646
|
-
(hashBytes[offset + 2] << 8) +
|
|
6647
|
-
hashBytes[offset + 3]) >>> 0;
|
|
6648
|
-
const weibull = (raw) => {
|
|
6649
|
-
const u = raw / 4294967296;
|
|
6650
|
-
let x = 0.27 * Math.sqrt(-Math.log(1 - u));
|
|
6651
|
-
if (x > 1)
|
|
6652
|
-
x = 1;
|
|
6653
|
-
let val = Math.floor(x * 999) + 1;
|
|
6654
|
-
if (val > 999)
|
|
6655
|
-
val = 999;
|
|
6656
|
-
return val;
|
|
6657
|
-
};
|
|
6658
|
-
return {
|
|
6659
|
-
stat1: weibull(extractU32(0)),
|
|
6660
|
-
stat2: weibull(extractU32(4)),
|
|
6661
|
-
stat3: weibull(extractU32(8)),
|
|
6662
|
-
};
|
|
6663
|
-
}
|
|
6664
|
-
|
|
6665
|
-
const METAL_STATS = [
|
|
6666
|
-
{
|
|
6667
|
-
key: 'strength',
|
|
6668
|
-
label: 'Strength',
|
|
6669
|
-
abbreviation: 'STR',
|
|
6670
|
-
purpose: 'Raw structural/mechanical force',
|
|
6671
|
-
},
|
|
6672
|
-
{
|
|
6673
|
-
key: 'tolerance',
|
|
6674
|
-
label: 'Tolerance',
|
|
6675
|
-
abbreviation: 'TOL',
|
|
6676
|
-
purpose: 'Ability to withstand heat, pressure, and stress extremes',
|
|
6677
|
-
},
|
|
6678
|
-
{
|
|
6679
|
-
key: 'density',
|
|
6680
|
-
label: 'Density',
|
|
6681
|
-
abbreviation: 'DEN',
|
|
6682
|
-
purpose: 'Mass per unit',
|
|
6683
|
-
inverted: true,
|
|
6684
|
-
},
|
|
6685
|
-
];
|
|
6686
|
-
const PRECIOUS_STATS = [
|
|
6687
|
-
{
|
|
6688
|
-
key: 'conductivity',
|
|
6689
|
-
label: 'Conductivity',
|
|
6690
|
-
abbreviation: 'CON',
|
|
6691
|
-
purpose: 'Efficiency of energy/signal transfer',
|
|
6692
|
-
},
|
|
6693
|
-
{
|
|
6694
|
-
key: 'ductility',
|
|
6695
|
-
label: 'Ductility',
|
|
6696
|
-
abbreviation: 'DUC',
|
|
6697
|
-
purpose: 'Ability to be worked into fine, precise shapes',
|
|
6698
|
-
},
|
|
6699
|
-
{
|
|
6700
|
-
key: 'reflectivity',
|
|
6701
|
-
label: 'Reflectivity',
|
|
6702
|
-
abbreviation: 'REF',
|
|
6703
|
-
purpose: 'Surface quality for heat management and precision optics',
|
|
6704
|
-
},
|
|
6705
|
-
];
|
|
6706
|
-
const GAS_STATS = [
|
|
6707
|
-
{
|
|
6708
|
-
key: 'volatility',
|
|
6709
|
-
label: 'Volatility',
|
|
6710
|
-
abbreviation: 'VOL',
|
|
6711
|
-
purpose: 'Energy release potential for propulsion and force',
|
|
6712
|
-
},
|
|
6713
|
-
{
|
|
6714
|
-
key: 'reactivity',
|
|
6715
|
-
label: 'Reactivity',
|
|
6716
|
-
abbreviation: 'REA',
|
|
6717
|
-
purpose: 'Chemical interaction speed for processing and penetration',
|
|
6718
|
-
},
|
|
6719
|
-
{
|
|
6720
|
-
key: 'thermal',
|
|
6721
|
-
label: 'Thermal',
|
|
6722
|
-
abbreviation: 'THM',
|
|
6723
|
-
purpose: 'Heat capacity for thermal management',
|
|
6724
|
-
},
|
|
6725
|
-
];
|
|
6726
|
-
const MINERAL_STATS = [
|
|
6727
|
-
{
|
|
6728
|
-
key: 'resonance',
|
|
6729
|
-
label: 'Resonance',
|
|
6730
|
-
abbreviation: 'RES',
|
|
6731
|
-
purpose: 'Energy field interaction — storage, focusing, projection',
|
|
6732
|
-
},
|
|
6733
|
-
{
|
|
6734
|
-
key: 'hardness',
|
|
6735
|
-
label: 'Hardness',
|
|
6736
|
-
abbreviation: 'HRD',
|
|
6737
|
-
purpose: 'Resistance to wear — cutting surfaces, penetration',
|
|
6738
|
-
},
|
|
6739
|
-
{
|
|
6740
|
-
key: 'clarity',
|
|
6741
|
-
label: 'Clarity',
|
|
6742
|
-
abbreviation: 'CLR',
|
|
6743
|
-
purpose: 'Crystalline perfection — precision optics',
|
|
6744
|
-
},
|
|
6745
|
-
];
|
|
6746
|
-
const ORGANIC_STATS = [
|
|
6747
|
-
{
|
|
6748
|
-
key: 'plasticity',
|
|
6749
|
-
label: 'Plasticity',
|
|
6750
|
-
abbreviation: 'PLA',
|
|
6751
|
-
purpose: 'Ease of reshaping — speeds processing',
|
|
6752
|
-
},
|
|
6753
|
-
{
|
|
6754
|
-
key: 'insulation',
|
|
6755
|
-
label: 'Insulation',
|
|
6756
|
-
abbreviation: 'INS',
|
|
6757
|
-
purpose: 'Energy containment — reduces energy loss',
|
|
6758
|
-
},
|
|
6759
|
-
{
|
|
6760
|
-
key: 'purity',
|
|
6761
|
-
label: 'Purity',
|
|
6762
|
-
abbreviation: 'PUR',
|
|
6763
|
-
purpose: 'Biological cleanliness — better composites and lubricants',
|
|
6764
|
-
},
|
|
6765
|
-
];
|
|
6766
|
-
const STAT_MAP = {
|
|
6767
|
-
metal: METAL_STATS,
|
|
6768
|
-
precious: PRECIOUS_STATS,
|
|
6769
|
-
gas: GAS_STATS,
|
|
6770
|
-
mineral: MINERAL_STATS,
|
|
6771
|
-
organic: ORGANIC_STATS,
|
|
6772
|
-
};
|
|
6773
|
-
function getStatDefinitions(category) {
|
|
6774
|
-
return STAT_MAP[category];
|
|
6775
|
-
}
|
|
6776
|
-
function getStatName(category, index) {
|
|
6777
|
-
return STAT_MAP[category][index];
|
|
6778
|
-
}
|
|
6779
|
-
function resolveStats(category, stats) {
|
|
6780
|
-
return {
|
|
6781
|
-
definitions: STAT_MAP[category],
|
|
6782
|
-
values: [stats.stat1, stats.stat2, stats.stat3],
|
|
6783
|
-
};
|
|
6784
|
-
}
|
|
6785
|
-
|
|
6786
|
-
const ITEM_ENGINE_T1 = 10100;
|
|
6787
|
-
const ITEM_GENERATOR_T1 = 10101;
|
|
6788
|
-
const ITEM_GATHERER_T1 = 10102;
|
|
6789
|
-
const ITEM_LOADER_T1 = 10103;
|
|
6790
|
-
const ITEM_MANUFACTURING_T1 = 10104;
|
|
6791
|
-
const ITEM_STORAGE_T1 = 10105;
|
|
6792
|
-
const ITEM_HAULER_T1 = 10106;
|
|
6793
|
-
const MODULE_ANY = 0;
|
|
6794
|
-
const MODULE_ENGINE = 1;
|
|
6795
|
-
const MODULE_GENERATOR = 2;
|
|
6796
|
-
const MODULE_GATHERER = 3;
|
|
6797
|
-
const MODULE_LOADER = 4;
|
|
6798
|
-
const MODULE_WARP = 5;
|
|
6799
|
-
const MODULE_CRAFTER = 6;
|
|
6800
|
-
const MODULE_LAUNCHER = 7;
|
|
6801
|
-
const MODULE_STORAGE = 8;
|
|
6802
|
-
const MODULE_HAULER = 9;
|
|
6803
|
-
function moduleAccepts(slotType, moduleType) {
|
|
6804
|
-
return slotType === MODULE_ANY || slotType === moduleType;
|
|
6805
|
-
}
|
|
6806
|
-
function getModuleCapabilityType(itemId) {
|
|
6807
|
-
switch (itemId) {
|
|
6808
|
-
case ITEM_ENGINE_T1:
|
|
6809
|
-
return MODULE_ENGINE;
|
|
6810
|
-
case ITEM_GENERATOR_T1:
|
|
6811
|
-
return MODULE_GENERATOR;
|
|
6812
|
-
case ITEM_GATHERER_T1:
|
|
6813
|
-
return MODULE_GATHERER;
|
|
6814
|
-
case ITEM_LOADER_T1:
|
|
6815
|
-
return MODULE_LOADER;
|
|
6816
|
-
case ITEM_MANUFACTURING_T1:
|
|
6817
|
-
return MODULE_CRAFTER;
|
|
6818
|
-
case ITEM_STORAGE_T1:
|
|
6819
|
-
return MODULE_STORAGE;
|
|
6820
|
-
case ITEM_HAULER_T1:
|
|
6821
|
-
return MODULE_HAULER;
|
|
6822
|
-
default:
|
|
6823
|
-
return 0xff;
|
|
6824
|
-
}
|
|
6825
|
-
}
|
|
6826
|
-
function isModuleItem(itemId) {
|
|
6827
|
-
return getModuleCapabilityType(itemId) !== 0xff;
|
|
4948
|
+
function isModuleItem(itemId) {
|
|
4949
|
+
return getModuleCapabilityType(itemId) !== 0xff;
|
|
6828
4950
|
}
|
|
6829
4951
|
|
|
6830
4952
|
const ITEM_MATTER_CONDUIT = 10005;
|
|
@@ -7241,211 +5363,2320 @@ const moduleRecipes = [
|
|
|
7241
5363
|
function getModuleRecipe(id) {
|
|
7242
5364
|
return moduleRecipes.find((r) => r.id === id);
|
|
7243
5365
|
}
|
|
7244
|
-
function getModuleRecipeByItemId(itemId) {
|
|
7245
|
-
return moduleRecipes.find((r) => r.itemId === itemId);
|
|
5366
|
+
function getModuleRecipeByItemId(itemId) {
|
|
5367
|
+
return moduleRecipes.find((r) => r.itemId === itemId);
|
|
5368
|
+
}
|
|
5369
|
+
function getComponentById(id) {
|
|
5370
|
+
return components.find((c) => c.id === id);
|
|
5371
|
+
}
|
|
5372
|
+
function getEntityRecipe(id) {
|
|
5373
|
+
return entityRecipes.find((r) => r.id === id);
|
|
5374
|
+
}
|
|
5375
|
+
function getEntityRecipeByItemId(itemId) {
|
|
5376
|
+
return entityRecipes.find((r) => r.packedItemId === itemId);
|
|
5377
|
+
}
|
|
5378
|
+
function getEntitySlotLayout(packedItemId) {
|
|
5379
|
+
const recipe = getEntityRecipeByItemId(packedItemId);
|
|
5380
|
+
return recipe?.moduleSlots ?? [];
|
|
5381
|
+
}
|
|
5382
|
+
function getAllCraftableItems() {
|
|
5383
|
+
const items = [];
|
|
5384
|
+
for (const comp of components) {
|
|
5385
|
+
items.push({
|
|
5386
|
+
type: 'component',
|
|
5387
|
+
id: comp.id,
|
|
5388
|
+
name: comp.name,
|
|
5389
|
+
description: comp.description,
|
|
5390
|
+
color: comp.color,
|
|
5391
|
+
});
|
|
5392
|
+
}
|
|
5393
|
+
for (const entity of entityRecipes) {
|
|
5394
|
+
items.push({
|
|
5395
|
+
type: 'entity',
|
|
5396
|
+
id: entity.id,
|
|
5397
|
+
name: entity.name,
|
|
5398
|
+
description: entity.description,
|
|
5399
|
+
color: entity.color,
|
|
5400
|
+
});
|
|
5401
|
+
}
|
|
5402
|
+
for (const mod of moduleRecipes) {
|
|
5403
|
+
items.push({
|
|
5404
|
+
type: 'module',
|
|
5405
|
+
id: mod.id,
|
|
5406
|
+
name: mod.name,
|
|
5407
|
+
description: mod.description,
|
|
5408
|
+
color: mod.color,
|
|
5409
|
+
});
|
|
5410
|
+
}
|
|
5411
|
+
return items;
|
|
5412
|
+
}
|
|
5413
|
+
function getComponentsForCategory(category) {
|
|
5414
|
+
return components.filter((c) => c.recipe.some((r) => r.category === category));
|
|
5415
|
+
}
|
|
5416
|
+
function getComponentsForStat(statKey) {
|
|
5417
|
+
return components.filter((c) => c.stats.some((s) => s.key === statKey));
|
|
5418
|
+
}
|
|
5419
|
+
|
|
5420
|
+
const METAL_STATS = [
|
|
5421
|
+
{
|
|
5422
|
+
key: 'strength',
|
|
5423
|
+
label: 'Strength',
|
|
5424
|
+
abbreviation: 'STR',
|
|
5425
|
+
purpose: 'Raw structural/mechanical force',
|
|
5426
|
+
},
|
|
5427
|
+
{
|
|
5428
|
+
key: 'tolerance',
|
|
5429
|
+
label: 'Tolerance',
|
|
5430
|
+
abbreviation: 'TOL',
|
|
5431
|
+
purpose: 'Ability to withstand heat, pressure, and stress extremes',
|
|
5432
|
+
},
|
|
5433
|
+
{
|
|
5434
|
+
key: 'density',
|
|
5435
|
+
label: 'Density',
|
|
5436
|
+
abbreviation: 'DEN',
|
|
5437
|
+
purpose: 'Mass per unit',
|
|
5438
|
+
inverted: true,
|
|
5439
|
+
},
|
|
5440
|
+
];
|
|
5441
|
+
const PRECIOUS_STATS = [
|
|
5442
|
+
{
|
|
5443
|
+
key: 'conductivity',
|
|
5444
|
+
label: 'Conductivity',
|
|
5445
|
+
abbreviation: 'CON',
|
|
5446
|
+
purpose: 'Efficiency of energy/signal transfer',
|
|
5447
|
+
},
|
|
5448
|
+
{
|
|
5449
|
+
key: 'ductility',
|
|
5450
|
+
label: 'Ductility',
|
|
5451
|
+
abbreviation: 'DUC',
|
|
5452
|
+
purpose: 'Ability to be worked into fine, precise shapes',
|
|
5453
|
+
},
|
|
5454
|
+
{
|
|
5455
|
+
key: 'reflectivity',
|
|
5456
|
+
label: 'Reflectivity',
|
|
5457
|
+
abbreviation: 'REF',
|
|
5458
|
+
purpose: 'Surface quality for heat management and precision optics',
|
|
5459
|
+
},
|
|
5460
|
+
];
|
|
5461
|
+
const GAS_STATS = [
|
|
5462
|
+
{
|
|
5463
|
+
key: 'volatility',
|
|
5464
|
+
label: 'Volatility',
|
|
5465
|
+
abbreviation: 'VOL',
|
|
5466
|
+
purpose: 'Energy release potential for propulsion and force',
|
|
5467
|
+
},
|
|
5468
|
+
{
|
|
5469
|
+
key: 'reactivity',
|
|
5470
|
+
label: 'Reactivity',
|
|
5471
|
+
abbreviation: 'REA',
|
|
5472
|
+
purpose: 'Chemical interaction speed for processing and penetration',
|
|
5473
|
+
},
|
|
5474
|
+
{
|
|
5475
|
+
key: 'thermal',
|
|
5476
|
+
label: 'Thermal',
|
|
5477
|
+
abbreviation: 'THM',
|
|
5478
|
+
purpose: 'Heat capacity for thermal management',
|
|
5479
|
+
},
|
|
5480
|
+
];
|
|
5481
|
+
const MINERAL_STATS = [
|
|
5482
|
+
{
|
|
5483
|
+
key: 'resonance',
|
|
5484
|
+
label: 'Resonance',
|
|
5485
|
+
abbreviation: 'RES',
|
|
5486
|
+
purpose: 'Energy field interaction — storage, focusing, projection',
|
|
5487
|
+
},
|
|
5488
|
+
{
|
|
5489
|
+
key: 'hardness',
|
|
5490
|
+
label: 'Hardness',
|
|
5491
|
+
abbreviation: 'HRD',
|
|
5492
|
+
purpose: 'Resistance to wear — cutting surfaces, penetration',
|
|
5493
|
+
},
|
|
5494
|
+
{
|
|
5495
|
+
key: 'clarity',
|
|
5496
|
+
label: 'Clarity',
|
|
5497
|
+
abbreviation: 'CLR',
|
|
5498
|
+
purpose: 'Crystalline perfection — precision optics',
|
|
5499
|
+
},
|
|
5500
|
+
];
|
|
5501
|
+
const ORGANIC_STATS = [
|
|
5502
|
+
{
|
|
5503
|
+
key: 'plasticity',
|
|
5504
|
+
label: 'Plasticity',
|
|
5505
|
+
abbreviation: 'PLA',
|
|
5506
|
+
purpose: 'Ease of reshaping — speeds processing',
|
|
5507
|
+
},
|
|
5508
|
+
{
|
|
5509
|
+
key: 'insulation',
|
|
5510
|
+
label: 'Insulation',
|
|
5511
|
+
abbreviation: 'INS',
|
|
5512
|
+
purpose: 'Energy containment — reduces energy loss',
|
|
5513
|
+
},
|
|
5514
|
+
{
|
|
5515
|
+
key: 'purity',
|
|
5516
|
+
label: 'Purity',
|
|
5517
|
+
abbreviation: 'PUR',
|
|
5518
|
+
purpose: 'Biological cleanliness — better composites and lubricants',
|
|
5519
|
+
},
|
|
5520
|
+
];
|
|
5521
|
+
const STAT_MAP = {
|
|
5522
|
+
metal: METAL_STATS,
|
|
5523
|
+
precious: PRECIOUS_STATS,
|
|
5524
|
+
gas: GAS_STATS,
|
|
5525
|
+
mineral: MINERAL_STATS,
|
|
5526
|
+
organic: ORGANIC_STATS,
|
|
5527
|
+
};
|
|
5528
|
+
function getStatDefinitions(category) {
|
|
5529
|
+
return STAT_MAP[category];
|
|
5530
|
+
}
|
|
5531
|
+
function getStatName(category, index) {
|
|
5532
|
+
return STAT_MAP[category][index];
|
|
5533
|
+
}
|
|
5534
|
+
function resolveStats(category, stats) {
|
|
5535
|
+
return {
|
|
5536
|
+
definitions: STAT_MAP[category],
|
|
5537
|
+
values: [stats.stat1, stats.stat2, stats.stat3],
|
|
5538
|
+
};
|
|
5539
|
+
}
|
|
5540
|
+
|
|
5541
|
+
const RESERVE_TIERS = {
|
|
5542
|
+
small: { min: 15, max: 60 },
|
|
5543
|
+
medium: { min: 100, max: 200 },
|
|
5544
|
+
large: { min: 400, max: 700 },
|
|
5545
|
+
massive: { min: 1000, max: 2500 },
|
|
5546
|
+
motherlode: { min: 4000, max: 10000 },
|
|
5547
|
+
};
|
|
5548
|
+
const SHALLOW_THRESHOLDS = {
|
|
5549
|
+
small: 0.8,
|
|
5550
|
+
medium: 0.991946,
|
|
5551
|
+
large: 0.999946,
|
|
5552
|
+
massive: 0.999996,
|
|
5553
|
+
};
|
|
5554
|
+
const DEEP_THRESHOLDS = {
|
|
5555
|
+
small: 0.5,
|
|
5556
|
+
medium: 0.95892,
|
|
5557
|
+
large: 0.99892,
|
|
5558
|
+
massive: 0.99992,
|
|
5559
|
+
};
|
|
5560
|
+
const TIER_ROLL_MAX = 0x10000;
|
|
5561
|
+
function lerp$1(a, b, t) {
|
|
5562
|
+
return a + (b - a) * t;
|
|
5563
|
+
}
|
|
5564
|
+
function rollTier(tierRoll, stratum) {
|
|
5565
|
+
const d = Math.min(stratum, 65535) / 65535;
|
|
5566
|
+
const smallMax = lerp$1(SHALLOW_THRESHOLDS.small, DEEP_THRESHOLDS.small, d) * TIER_ROLL_MAX;
|
|
5567
|
+
const mediumMax = lerp$1(SHALLOW_THRESHOLDS.medium, DEEP_THRESHOLDS.medium, d) * TIER_ROLL_MAX;
|
|
5568
|
+
const largeMax = lerp$1(SHALLOW_THRESHOLDS.large, DEEP_THRESHOLDS.large, d) * TIER_ROLL_MAX;
|
|
5569
|
+
const massiveMax = lerp$1(SHALLOW_THRESHOLDS.massive, DEEP_THRESHOLDS.massive, d) * TIER_ROLL_MAX;
|
|
5570
|
+
if (tierRoll < smallMax)
|
|
5571
|
+
return 'small';
|
|
5572
|
+
if (tierRoll < mediumMax)
|
|
5573
|
+
return 'medium';
|
|
5574
|
+
if (tierRoll < largeMax)
|
|
5575
|
+
return 'large';
|
|
5576
|
+
if (tierRoll < massiveMax)
|
|
5577
|
+
return 'massive';
|
|
5578
|
+
return 'motherlode';
|
|
5579
|
+
}
|
|
5580
|
+
function rollWithinTier(withinRoll, range) {
|
|
5581
|
+
const u = withinRoll / 65535;
|
|
5582
|
+
const skewed = u * u;
|
|
5583
|
+
return Math.floor(range.min + skewed * (range.max - range.min));
|
|
5584
|
+
}
|
|
5585
|
+
|
|
5586
|
+
function deriveStratum(epochSeed, coords, stratum, locationType, subtype, _maxDepth) {
|
|
5587
|
+
const seed = Checksum256.from(epochSeed);
|
|
5588
|
+
const c = Coordinates.from(coords);
|
|
5589
|
+
const input = `stratum-${c.x}-${c.y}-${stratum}`;
|
|
5590
|
+
const hashResult = hash512(seed, input);
|
|
5591
|
+
const bytes = hashResult.array;
|
|
5592
|
+
const rawReserve = ((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]) >>> 0;
|
|
5593
|
+
let reserve = 0;
|
|
5594
|
+
if (rawReserve <= YIELD_THRESHOLD) {
|
|
5595
|
+
const tierRoll = ((bytes[18] << 8) | bytes[19]) >>> 0;
|
|
5596
|
+
const withinRoll = ((bytes[20] << 8) | bytes[21]) >>> 0;
|
|
5597
|
+
const tier = rollTier(tierRoll, stratum);
|
|
5598
|
+
reserve = rollWithinTier(withinRoll, RESERVE_TIERS[tier]);
|
|
5599
|
+
}
|
|
5600
|
+
if (reserve === 0)
|
|
5601
|
+
return { itemId: 0, seed: 0n, richness: 0, reserve: 0 };
|
|
5602
|
+
const eligible = getEligibleResources(locationType, subtype, stratum);
|
|
5603
|
+
if (eligible.length === 0)
|
|
5604
|
+
return { itemId: 0, seed: 0n, richness: 0, reserve: 0 };
|
|
5605
|
+
const resourceRoll = ((bytes[4] << 24) | (bytes[5] << 16) | (bytes[6] << 8) | bytes[7]) >>> 0;
|
|
5606
|
+
let totalWeight = 0;
|
|
5607
|
+
for (const id of eligible) {
|
|
5608
|
+
totalWeight += getResourceWeight(id, stratum);
|
|
5609
|
+
}
|
|
5610
|
+
let selectedItemId = eligible[0];
|
|
5611
|
+
if (totalWeight > 0) {
|
|
5612
|
+
const roll = resourceRoll % totalWeight;
|
|
5613
|
+
let cumulative = 0;
|
|
5614
|
+
for (const id of eligible) {
|
|
5615
|
+
cumulative += getResourceWeight(id, stratum);
|
|
5616
|
+
if (roll < cumulative) {
|
|
5617
|
+
selectedItemId = id;
|
|
5618
|
+
break;
|
|
5619
|
+
}
|
|
5620
|
+
}
|
|
5621
|
+
}
|
|
5622
|
+
const seedBigInt = (BigInt(bytes[8]) << 56n) |
|
|
5623
|
+
(BigInt(bytes[9]) << 48n) |
|
|
5624
|
+
(BigInt(bytes[10]) << 40n) |
|
|
5625
|
+
(BigInt(bytes[11]) << 32n) |
|
|
5626
|
+
(BigInt(bytes[12]) << 24n) |
|
|
5627
|
+
(BigInt(bytes[13]) << 16n) |
|
|
5628
|
+
(BigInt(bytes[14]) << 8n) |
|
|
5629
|
+
BigInt(bytes[15]);
|
|
5630
|
+
const rawRichness = (bytes[16] << 8) | bytes[17];
|
|
5631
|
+
const normalized = rawRichness / 65535;
|
|
5632
|
+
const baseRichness = Math.floor(normalized * normalized * 999) + 1;
|
|
5633
|
+
let depthBonus = 0;
|
|
5634
|
+
if (stratum > 1) {
|
|
5635
|
+
depthBonus = (50 * Math.log(stratum)) / Math.log(65535);
|
|
5636
|
+
}
|
|
5637
|
+
const richness = Math.min(Math.floor(baseRichness + depthBonus), 1000);
|
|
5638
|
+
return { itemId: selectedItemId, seed: seedBigInt, richness, reserve };
|
|
5639
|
+
}
|
|
5640
|
+
function deriveResourceStats(seed) {
|
|
5641
|
+
const seedBytes = new Uint8Array(8);
|
|
5642
|
+
for (let i = 0; i < 8; i++) {
|
|
5643
|
+
seedBytes[i] = Number(seed & 0xffn);
|
|
5644
|
+
seed >>= 8n;
|
|
5645
|
+
}
|
|
5646
|
+
const hashResult = Checksum256.hash(Bytes.from(seedBytes));
|
|
5647
|
+
const hashBytes = hashResult.array;
|
|
5648
|
+
const extractU32 = (offset) => (hashBytes[offset] * 0x1000000 +
|
|
5649
|
+
(hashBytes[offset + 1] << 16) +
|
|
5650
|
+
(hashBytes[offset + 2] << 8) +
|
|
5651
|
+
hashBytes[offset + 3]) >>>
|
|
5652
|
+
0;
|
|
5653
|
+
const weibull = (raw) => {
|
|
5654
|
+
const u = raw / 4294967296;
|
|
5655
|
+
let x = 0.24 * Math.sqrt(-Math.log(1 - u));
|
|
5656
|
+
if (x > 1)
|
|
5657
|
+
x = 1;
|
|
5658
|
+
let val = Math.floor(x * 999) + 1;
|
|
5659
|
+
if (val > 999)
|
|
5660
|
+
val = 999;
|
|
5661
|
+
return val;
|
|
5662
|
+
};
|
|
5663
|
+
return {
|
|
5664
|
+
stat1: weibull(extractU32(0)),
|
|
5665
|
+
stat2: weibull(extractU32(4)),
|
|
5666
|
+
stat3: weibull(extractU32(8)),
|
|
5667
|
+
};
|
|
5668
|
+
}
|
|
5669
|
+
|
|
5670
|
+
function encodeStats(values) {
|
|
5671
|
+
let seed = 0n;
|
|
5672
|
+
for (let i = 0; i < values.length && i < 6; i++) {
|
|
5673
|
+
seed |= BigInt(values[i] & 0x3ff) << BigInt(i * 10);
|
|
5674
|
+
}
|
|
5675
|
+
return seed;
|
|
5676
|
+
}
|
|
5677
|
+
function decodeStat(seed, index) {
|
|
5678
|
+
return Number((seed >> BigInt(index * 10)) & 0x3ffn);
|
|
5679
|
+
}
|
|
5680
|
+
function decodeStats(seed, count) {
|
|
5681
|
+
const stats = [];
|
|
5682
|
+
for (let i = 0; i < count; i++) {
|
|
5683
|
+
stats.push(decodeStat(seed, i));
|
|
5684
|
+
}
|
|
5685
|
+
return stats;
|
|
5686
|
+
}
|
|
5687
|
+
function mapStatsToKeys(seed, statDefs) {
|
|
5688
|
+
const values = decodeStats(seed, statDefs.length);
|
|
5689
|
+
const result = {};
|
|
5690
|
+
for (let i = 0; i < statDefs.length; i++) {
|
|
5691
|
+
result[statDefs[i].key] = values[i];
|
|
5692
|
+
}
|
|
5693
|
+
return result;
|
|
5694
|
+
}
|
|
5695
|
+
function decodeCraftedItemStats(itemId, seed) {
|
|
5696
|
+
const comp = getComponentById(itemId);
|
|
5697
|
+
if (comp)
|
|
5698
|
+
return mapStatsToKeys(seed, comp.stats);
|
|
5699
|
+
const entityRecipe = entityRecipes.find((r) => r.packedItemId === itemId);
|
|
5700
|
+
if (entityRecipe)
|
|
5701
|
+
return mapStatsToKeys(seed, entityRecipe.stats);
|
|
5702
|
+
const moduleRecipe = moduleRecipes.find((r) => r.itemId === itemId);
|
|
5703
|
+
if (moduleRecipe)
|
|
5704
|
+
return mapStatsToKeys(seed, moduleRecipe.stats);
|
|
5705
|
+
return {};
|
|
5706
|
+
}
|
|
5707
|
+
function blendStacks(stacks, statKey) {
|
|
5708
|
+
let totalQty = 0;
|
|
5709
|
+
let weightedSum = 0;
|
|
5710
|
+
for (const stack of stacks) {
|
|
5711
|
+
const val = stack.stats[statKey] ?? 0;
|
|
5712
|
+
weightedSum += val * stack.quantity;
|
|
5713
|
+
totalQty += stack.quantity;
|
|
5714
|
+
}
|
|
5715
|
+
if (totalQty === 0)
|
|
5716
|
+
return 0;
|
|
5717
|
+
return Math.floor(weightedSum / totalQty);
|
|
5718
|
+
}
|
|
5719
|
+
function computeComponentStats(componentId, categoryStacks) {
|
|
5720
|
+
const comp = getComponentById(componentId);
|
|
5721
|
+
if (!comp)
|
|
5722
|
+
return [];
|
|
5723
|
+
return comp.stats.map((statDef) => {
|
|
5724
|
+
const matching = categoryStacks.find((cs) => cs.category === statDef.source);
|
|
5725
|
+
const value = matching ? blendStacks(matching.stacks, statDef.key) : 0;
|
|
5726
|
+
return { key: statDef.key, value: Math.max(1, Math.min(999, value)) };
|
|
5727
|
+
});
|
|
5728
|
+
}
|
|
5729
|
+
function blendComponentStacks(stacks) {
|
|
5730
|
+
if (stacks.length === 0)
|
|
5731
|
+
return {};
|
|
5732
|
+
const allKeys = new Set();
|
|
5733
|
+
for (const s of stacks) {
|
|
5734
|
+
for (const k of Object.keys(s.stats))
|
|
5735
|
+
allKeys.add(k);
|
|
5736
|
+
}
|
|
5737
|
+
const result = {};
|
|
5738
|
+
for (const key of allKeys) {
|
|
5739
|
+
result[key] = blendStacks(stacks.map((s) => ({ quantity: s.quantity, stats: s.stats })), key);
|
|
5740
|
+
}
|
|
5741
|
+
return result;
|
|
5742
|
+
}
|
|
5743
|
+
function computeEntityStats(entityRecipeId, componentStacks) {
|
|
5744
|
+
const recipe = getEntityRecipe(entityRecipeId) ?? getModuleRecipe(entityRecipeId);
|
|
5745
|
+
if (!recipe)
|
|
5746
|
+
return [];
|
|
5747
|
+
const blendedByComponent = {};
|
|
5748
|
+
for (const [compId, stacks] of Object.entries(componentStacks)) {
|
|
5749
|
+
blendedByComponent[Number(compId)] = blendComponentStacks(stacks);
|
|
5750
|
+
}
|
|
5751
|
+
return recipe.stats.map((stat) => {
|
|
5752
|
+
const blended = blendedByComponent[stat.sourceComponentId] ?? {};
|
|
5753
|
+
const value = blended[stat.sourceStatKey] ?? 0;
|
|
5754
|
+
return { key: stat.key, value: Math.max(1, Math.min(999, value)) };
|
|
5755
|
+
});
|
|
5756
|
+
}
|
|
5757
|
+
function decodeStackStats(itemId, seed) {
|
|
5758
|
+
if (itemId >= 10000) {
|
|
5759
|
+
return decodeCraftedItemStats(itemId, BigInt(seed.toString()));
|
|
5760
|
+
}
|
|
5761
|
+
const raw = deriveResourceStats(BigInt(seed.toString()));
|
|
5762
|
+
return { stat1: raw.stat1, stat2: raw.stat2, stat3: raw.stat3 };
|
|
5763
|
+
}
|
|
5764
|
+
const categoryItemMass = {
|
|
5765
|
+
metal: 30000,
|
|
5766
|
+
precious: 40000,
|
|
5767
|
+
gas: 15000,
|
|
5768
|
+
mineral: 22000,
|
|
5769
|
+
organic: 15000,
|
|
5770
|
+
};
|
|
5771
|
+
function computeInputMass(itemId, itemType) {
|
|
5772
|
+
if (itemType === 'component') {
|
|
5773
|
+
const comp = getComponentById(itemId);
|
|
5774
|
+
if (!comp)
|
|
5775
|
+
return 0;
|
|
5776
|
+
return comp.recipe.reduce((sum, input) => {
|
|
5777
|
+
const mass = input.category ? categoryItemMass[input.category] ?? 0 : 0;
|
|
5778
|
+
return sum + mass * input.quantity;
|
|
5779
|
+
}, 0);
|
|
5780
|
+
}
|
|
5781
|
+
if (itemType === 'module') {
|
|
5782
|
+
const mod = getModuleRecipe(itemId);
|
|
5783
|
+
if (!mod)
|
|
5784
|
+
return 0;
|
|
5785
|
+
return mod.recipe.reduce((sum, input) => {
|
|
5786
|
+
const comp = input.itemId ? getComponentById(input.itemId) : undefined;
|
|
5787
|
+
return sum + (comp?.mass ?? 0) * input.quantity;
|
|
5788
|
+
}, 0);
|
|
5789
|
+
}
|
|
5790
|
+
if (itemType === 'entity') {
|
|
5791
|
+
const ent = getEntityRecipe(itemId);
|
|
5792
|
+
if (!ent)
|
|
5793
|
+
return 0;
|
|
5794
|
+
return ent.recipe.reduce((sum, input) => {
|
|
5795
|
+
const comp = input.itemId ? getComponentById(input.itemId) : undefined;
|
|
5796
|
+
return sum + (comp?.mass ?? 0) * input.quantity;
|
|
5797
|
+
}, 0);
|
|
5798
|
+
}
|
|
5799
|
+
return 0;
|
|
5800
|
+
}
|
|
5801
|
+
function blendCrossGroup(sources) {
|
|
5802
|
+
let weightedSum = 0;
|
|
5803
|
+
let totalWeight = 0;
|
|
5804
|
+
for (const src of sources) {
|
|
5805
|
+
weightedSum += src.value * src.weight;
|
|
5806
|
+
totalWeight += src.weight;
|
|
5807
|
+
}
|
|
5808
|
+
if (totalWeight === 0)
|
|
5809
|
+
return 1;
|
|
5810
|
+
const result = Math.floor(weightedSum / totalWeight);
|
|
5811
|
+
return Math.max(1, Math.min(999, result));
|
|
5812
|
+
}
|
|
5813
|
+
function blendCargoStacks(itemId, stacks) {
|
|
5814
|
+
const decoded = stacks.map((s) => ({
|
|
5815
|
+
quantity: s.quantity,
|
|
5816
|
+
stats: decodeStackStats(itemId, s.seed),
|
|
5817
|
+
}));
|
|
5818
|
+
const allKeys = Object.keys(decoded[0]?.stats ?? {});
|
|
5819
|
+
const blended = allKeys.map((key) => Math.max(1, Math.min(999, blendStacks(decoded, key))));
|
|
5820
|
+
return UInt64.from(encodeStats(blended));
|
|
5821
|
+
}
|
|
5822
|
+
function decodeRawStackToCategoryStats(seed, category) {
|
|
5823
|
+
const raw = deriveResourceStats(seed);
|
|
5824
|
+
const defs = getStatDefinitions(category);
|
|
5825
|
+
const result = {};
|
|
5826
|
+
if (defs[0])
|
|
5827
|
+
result[defs[0].key] = raw.stat1;
|
|
5828
|
+
if (defs[1])
|
|
5829
|
+
result[defs[1].key] = raw.stat2;
|
|
5830
|
+
if (defs[2])
|
|
5831
|
+
result[defs[2].key] = raw.stat3;
|
|
5832
|
+
return result;
|
|
5833
|
+
}
|
|
5834
|
+
function computeCraftedOutputSeed(outputItemId, slotInputs) {
|
|
5835
|
+
var _a;
|
|
5836
|
+
const component = getComponentById(outputItemId);
|
|
5837
|
+
if (component) {
|
|
5838
|
+
const categoryStacks = [];
|
|
5839
|
+
for (const slot of slotInputs) {
|
|
5840
|
+
if (!slot.category)
|
|
5841
|
+
continue;
|
|
5842
|
+
const slotIsComponent = getComponentById(slot.itemId) !== undefined;
|
|
5843
|
+
const stacks = slot.stacks.map((s) => ({
|
|
5844
|
+
quantity: s.quantity,
|
|
5845
|
+
stats: slotIsComponent
|
|
5846
|
+
? decodeCraftedItemStats(slot.itemId, s.seed)
|
|
5847
|
+
: decodeRawStackToCategoryStats(s.seed, slot.category),
|
|
5848
|
+
}));
|
|
5849
|
+
categoryStacks.push({ category: slot.category, stacks });
|
|
5850
|
+
}
|
|
5851
|
+
const stats = computeComponentStats(outputItemId, categoryStacks);
|
|
5852
|
+
const ordered = component.stats.map((statDef) => {
|
|
5853
|
+
const found = stats.find((s) => s.key === statDef.key);
|
|
5854
|
+
return found ? found.value : 0;
|
|
5855
|
+
});
|
|
5856
|
+
return UInt64.from(encodeStats(ordered));
|
|
5857
|
+
}
|
|
5858
|
+
const entityRecipe = getEntityRecipeByItemId(outputItemId);
|
|
5859
|
+
if (entityRecipe) {
|
|
5860
|
+
const componentStacks = {};
|
|
5861
|
+
for (const slot of slotInputs) {
|
|
5862
|
+
if (slot.category !== undefined) {
|
|
5863
|
+
throw new Error(`entity recipe ${entityRecipe.id} expects component inputs but slot itemId=${slot.itemId} has category=${slot.category}`);
|
|
5864
|
+
}
|
|
5865
|
+
const list = (componentStacks[_a = slot.itemId] ?? (componentStacks[_a] = []));
|
|
5866
|
+
for (const s of slot.stacks) {
|
|
5867
|
+
list.push({
|
|
5868
|
+
quantity: s.quantity,
|
|
5869
|
+
stats: decodeCraftedItemStats(slot.itemId, s.seed),
|
|
5870
|
+
});
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
5873
|
+
const stats = computeEntityStats(entityRecipe.id, componentStacks);
|
|
5874
|
+
const ordered = entityRecipe.stats.map((statDef) => {
|
|
5875
|
+
const found = stats.find((s) => s.key === statDef.key);
|
|
5876
|
+
return found ? found.value : 0;
|
|
5877
|
+
});
|
|
5878
|
+
return UInt64.from(encodeStats(ordered));
|
|
5879
|
+
}
|
|
5880
|
+
throw new Error(`computeCraftedOutputSeed: no recipe found for outputItemId=${outputItemId}`);
|
|
5881
|
+
}
|
|
5882
|
+
|
|
5883
|
+
const itemsById = new Map();
|
|
5884
|
+
const synthesizedCache = new Map();
|
|
5885
|
+
for (const g of itemsData) {
|
|
5886
|
+
const item = Item.from({
|
|
5887
|
+
id: g.id,
|
|
5888
|
+
name: g.name,
|
|
5889
|
+
description: g.description,
|
|
5890
|
+
mass: g.mass,
|
|
5891
|
+
category: g.category,
|
|
5892
|
+
tier: g.tier,
|
|
5893
|
+
color: g.color,
|
|
5894
|
+
});
|
|
5895
|
+
itemsById.set(item.id.toNumber(), item);
|
|
5896
|
+
}
|
|
5897
|
+
const itemIds = Array.from(itemsById.values(), (i) => i.id);
|
|
5898
|
+
function synthesizeItem(id, source) {
|
|
5899
|
+
return Item.from({
|
|
5900
|
+
id,
|
|
5901
|
+
name: source.name,
|
|
5902
|
+
description: source.description,
|
|
5903
|
+
mass: source.mass,
|
|
5904
|
+
category: 'metal',
|
|
5905
|
+
tier: 't1',
|
|
5906
|
+
color: source.color,
|
|
5907
|
+
});
|
|
5908
|
+
}
|
|
5909
|
+
function synthesizeFromRecipes(id) {
|
|
5910
|
+
const component = getComponentById(id);
|
|
5911
|
+
if (component)
|
|
5912
|
+
return synthesizeItem(id, component);
|
|
5913
|
+
const entityRecipe = getEntityRecipeByItemId(id);
|
|
5914
|
+
if (entityRecipe) {
|
|
5915
|
+
return synthesizeItem(id, {
|
|
5916
|
+
...entityRecipe,
|
|
5917
|
+
mass: computeInputMass(entityRecipe.id, 'entity'),
|
|
5918
|
+
});
|
|
5919
|
+
}
|
|
5920
|
+
const moduleRecipe = getModuleRecipeByItemId(id);
|
|
5921
|
+
if (moduleRecipe) {
|
|
5922
|
+
return synthesizeItem(id, {
|
|
5923
|
+
...moduleRecipe,
|
|
5924
|
+
mass: computeInputMass(moduleRecipe.id, 'module'),
|
|
5925
|
+
});
|
|
5926
|
+
}
|
|
5927
|
+
return undefined;
|
|
5928
|
+
}
|
|
5929
|
+
function getItem(itemId) {
|
|
5930
|
+
const id = UInt16.from(itemId).toNumber();
|
|
5931
|
+
const existing = itemsById.get(id) ?? synthesizedCache.get(id);
|
|
5932
|
+
if (existing)
|
|
5933
|
+
return existing;
|
|
5934
|
+
const synthesized = synthesizeFromRecipes(id);
|
|
5935
|
+
if (synthesized) {
|
|
5936
|
+
synthesizedCache.set(id, synthesized);
|
|
5937
|
+
return synthesized;
|
|
5938
|
+
}
|
|
5939
|
+
throw new Error(`Item with id ${id} not found`);
|
|
5940
|
+
}
|
|
5941
|
+
function getItems() {
|
|
5942
|
+
return Array.from(itemsById.values());
|
|
5943
|
+
}
|
|
5944
|
+
|
|
5945
|
+
function calc_orbital_altitude(mass) {
|
|
5946
|
+
if (mass <= BASE_ORBITAL_MASS) {
|
|
5947
|
+
return MIN_ORBITAL_ALTITUDE;
|
|
5948
|
+
}
|
|
5949
|
+
const ratio = mass / BASE_ORBITAL_MASS;
|
|
5950
|
+
const capRatio = 10.0;
|
|
5951
|
+
let scale = Math.log(ratio) / Math.log(capRatio);
|
|
5952
|
+
scale = Math.min(scale, 1.0);
|
|
5953
|
+
return MIN_ORBITAL_ALTITUDE + Math.floor((MAX_ORBITAL_ALTITUDE - MIN_ORBITAL_ALTITUDE) * scale);
|
|
5954
|
+
}
|
|
5955
|
+
function distanceBetweenCoordinates(origin, destination) {
|
|
5956
|
+
return distanceBetweenPoints(origin.x, origin.y, destination.x, destination.y);
|
|
5957
|
+
}
|
|
5958
|
+
function distanceBetweenPoints(x1, y1, x2, y2) {
|
|
5959
|
+
const x = Math.pow(x1 - x2, 2);
|
|
5960
|
+
const y = Math.pow(y1 - y2, 2);
|
|
5961
|
+
return UInt64.from(Math.sqrt(x + y) * PRECISION$1);
|
|
5962
|
+
}
|
|
5963
|
+
function lerp(origin, destination, time) {
|
|
5964
|
+
return {
|
|
5965
|
+
x: (1 - time) * Number(origin.x) + time * Number(destination.x),
|
|
5966
|
+
y: (1 - time) * Number(origin.y) + time * Number(destination.y),
|
|
5967
|
+
};
|
|
5968
|
+
}
|
|
5969
|
+
function rotation(origin, destination) {
|
|
5970
|
+
return Math.atan2(destination.y - origin.y, destination.x - origin.x) * (180 / Math.PI) + 90;
|
|
5971
|
+
}
|
|
5972
|
+
function findNearbyPlanets(seed, origin, maxDistance = 20 * PRECISION$1) {
|
|
5973
|
+
const nearbySystems = [];
|
|
5974
|
+
const max = UInt64.from(maxDistance / PRECISION$1);
|
|
5975
|
+
const xMin = Int64.from(origin.x).subtracting(max);
|
|
5976
|
+
const xMax = Int64.from(origin.x).adding(max);
|
|
5977
|
+
const yMin = Int64.from(origin.y).subtracting(max);
|
|
5978
|
+
const yMax = Int64.from(origin.y).adding(max);
|
|
5979
|
+
for (let x = Number(xMin); x <= Number(xMax); x++) {
|
|
5980
|
+
for (let y = Number(yMin); y <= Number(yMax); y++) {
|
|
5981
|
+
const samePlace = x === Number(origin.x) && y === Number(origin.y);
|
|
5982
|
+
if (!samePlace) {
|
|
5983
|
+
const distance = distanceBetweenPoints(origin.x, origin.y, x, y);
|
|
5984
|
+
if (Number(distance) <= Number(maxDistance)) {
|
|
5985
|
+
const system = hasSystem(seed, { x, y });
|
|
5986
|
+
if (system) {
|
|
5987
|
+
nearbySystems.push({ origin, destination: { x, y }, distance });
|
|
5988
|
+
}
|
|
5989
|
+
}
|
|
5990
|
+
}
|
|
5991
|
+
}
|
|
5992
|
+
}
|
|
5993
|
+
return nearbySystems;
|
|
5994
|
+
}
|
|
5995
|
+
function calc_rechargetime(capacity, energy, recharge) {
|
|
5996
|
+
const cap = UInt32.from(capacity);
|
|
5997
|
+
const eng = UInt32.from(energy);
|
|
5998
|
+
if (eng.gte(cap))
|
|
5999
|
+
return UInt32.zero;
|
|
6000
|
+
return cap.subtracting(eng).dividing(recharge);
|
|
6001
|
+
}
|
|
6002
|
+
function calc_ship_rechargetime(ship) {
|
|
6003
|
+
if (!ship.generator)
|
|
6004
|
+
return UInt32.from(0);
|
|
6005
|
+
return calc_rechargetime(ship.generator.capacity, ship.energy ?? UInt16.from(0), ship.generator.recharge);
|
|
6006
|
+
}
|
|
6007
|
+
function calc_flighttime(distance, acceleration) {
|
|
6008
|
+
return UInt32.from(2 * Math.sqrt(Number(distance) / acceleration));
|
|
6009
|
+
}
|
|
6010
|
+
function calc_loader_flighttime(ship, mass, altitude) {
|
|
6011
|
+
const z = altitude ?? ship.coordinates.z?.toNumber() ?? calc_orbital_altitude(Number(mass));
|
|
6012
|
+
return calc_flighttime(z, calc_loader_acceleration(ship, mass));
|
|
6013
|
+
}
|
|
6014
|
+
function calc_loader_acceleration(ship, mass) {
|
|
6015
|
+
const thrust = ship.loaders ? Number(ship.loaders.thrust) : 0;
|
|
6016
|
+
const loaderMass = ship.loaders ? Number(ship.loaders.mass) : 0;
|
|
6017
|
+
return calc_acceleration(thrust, Number(mass) + loaderMass);
|
|
6018
|
+
}
|
|
6019
|
+
function calc_ship_flighttime(ship, mass, distance) {
|
|
6020
|
+
const acceleration = calc_ship_acceleration(ship, mass);
|
|
6021
|
+
return calc_flighttime(distance, acceleration);
|
|
6022
|
+
}
|
|
6023
|
+
function calc_ship_acceleration(ship, mass) {
|
|
6024
|
+
const thrust = ship.engines ? Number(ship.engines.thrust) : 0;
|
|
6025
|
+
return calc_acceleration(thrust, Number(mass));
|
|
6026
|
+
}
|
|
6027
|
+
function calc_acceleration(thrust, mass) {
|
|
6028
|
+
return (thrust / mass) * PRECISION$1;
|
|
6029
|
+
}
|
|
6030
|
+
function calc_ship_mass(ship, cargos) {
|
|
6031
|
+
const mass = UInt64.from(0);
|
|
6032
|
+
mass.add(ship.hullmass);
|
|
6033
|
+
if (ship.loaders && ship.loaders.quantity.gt(UInt32.zero)) {
|
|
6034
|
+
mass.add(ship.loaders.mass.multiplying(ship.loaders.quantity));
|
|
6035
|
+
}
|
|
6036
|
+
for (const cargo of cargos) {
|
|
6037
|
+
mass.add(getItem(cargo.item_id).mass.multiplying(cargo.quantity));
|
|
6038
|
+
}
|
|
6039
|
+
return mass;
|
|
6040
|
+
}
|
|
6041
|
+
function calc_energyusage(distance, drain) {
|
|
6042
|
+
return UInt64.from(distance).dividing(PRECISION$1).multiplying(drain);
|
|
6043
|
+
}
|
|
6044
|
+
function calculateTransferTime(ship, cargos, quantities) {
|
|
6045
|
+
let mass = UInt64.from(0);
|
|
6046
|
+
for (const cargo of cargos) {
|
|
6047
|
+
const qty = quantities?.get(Number(cargo.item_id)) ?? 0;
|
|
6048
|
+
if (qty > 0) {
|
|
6049
|
+
const good_mass = getItem(cargo.item_id).mass;
|
|
6050
|
+
const cargo_mass = good_mass.multiplying(qty);
|
|
6051
|
+
mass = UInt64.from(mass).adding(cargo_mass);
|
|
6052
|
+
}
|
|
6053
|
+
}
|
|
6054
|
+
if (mass.equals(UInt64.zero)) {
|
|
6055
|
+
return UInt32.from(0);
|
|
6056
|
+
}
|
|
6057
|
+
if (!ship.loaders)
|
|
6058
|
+
return UInt32.from(0);
|
|
6059
|
+
mass = UInt64.from(mass).adding(ship.loaders.mass);
|
|
6060
|
+
const transfer_time = calc_loader_flighttime(ship, mass);
|
|
6061
|
+
return transfer_time.dividing(ship.loaders.quantity);
|
|
6062
|
+
}
|
|
6063
|
+
function calculateRefuelingTime(ship) {
|
|
6064
|
+
return calc_ship_rechargetime(ship);
|
|
6065
|
+
}
|
|
6066
|
+
function calculateFlightTime(ship, cargos, distance) {
|
|
6067
|
+
const mass = calc_ship_mass(ship, cargos);
|
|
6068
|
+
return calc_ship_flighttime(ship, mass, distance);
|
|
6069
|
+
}
|
|
6070
|
+
function calculateLoadTimeBreakdown(ship, cargos, loadQuantities, unloadQuantities) {
|
|
6071
|
+
let mass_unload = UInt64.from(0);
|
|
6072
|
+
let mass_load = UInt64.from(0);
|
|
6073
|
+
for (const cargo of cargos) {
|
|
6074
|
+
const goodId = Number(cargo.item_id);
|
|
6075
|
+
const loadQty = loadQuantities?.get(goodId) ?? 0;
|
|
6076
|
+
const unloadQty = unloadQuantities?.get(goodId) ?? 0;
|
|
6077
|
+
if (loadQty > 0 || unloadQty > 0) {
|
|
6078
|
+
const good = getItem(cargo.item_id);
|
|
6079
|
+
if (loadQty > 0) {
|
|
6080
|
+
const cargo_mass = good.mass.multiplying(loadQty);
|
|
6081
|
+
mass_load = UInt64.from(mass_load).adding(cargo_mass);
|
|
6082
|
+
}
|
|
6083
|
+
if (unloadQty > 0) {
|
|
6084
|
+
const cargo_mass = good.mass.multiplying(unloadQty);
|
|
6085
|
+
mass_unload = UInt64.from(mass_unload).adding(cargo_mass);
|
|
6086
|
+
}
|
|
6087
|
+
}
|
|
6088
|
+
}
|
|
6089
|
+
let unloadTime = 0;
|
|
6090
|
+
let loadTime = 0;
|
|
6091
|
+
if (mass_unload.gt(UInt64.zero) && ship.loaders) {
|
|
6092
|
+
const totalMass = UInt64.from(mass_unload).adding(ship.loaders.mass);
|
|
6093
|
+
unloadTime = Number(calc_loader_flighttime(ship, totalMass));
|
|
6094
|
+
}
|
|
6095
|
+
if (mass_load.gt(UInt64.zero) && ship.loaders) {
|
|
6096
|
+
const totalMass = UInt64.from(mass_load).adding(ship.loaders.mass);
|
|
6097
|
+
loadTime = Number(calc_loader_flighttime(ship, totalMass));
|
|
6098
|
+
}
|
|
6099
|
+
const numLoaders = ship.loaders ? Number(ship.loaders.quantity) : 0;
|
|
6100
|
+
const totalTime = numLoaders > 0 ? (unloadTime + loadTime) / numLoaders : 0;
|
|
6101
|
+
const unloadTimePerLoader = numLoaders > 0 ? unloadTime / numLoaders : 0;
|
|
6102
|
+
const loadTimePerLoader = numLoaders > 0 ? loadTime / numLoaders : 0;
|
|
6103
|
+
return {
|
|
6104
|
+
unloadTime: unloadTimePerLoader,
|
|
6105
|
+
loadTime: loadTimePerLoader,
|
|
6106
|
+
totalTime,
|
|
6107
|
+
unloadMass: Number(mass_unload),
|
|
6108
|
+
loadMass: Number(mass_load),
|
|
6109
|
+
};
|
|
6110
|
+
}
|
|
6111
|
+
function estimateTravelTime(ship, travelMass, distance, options = {}) {
|
|
6112
|
+
const { needsRecharge = false, loadMass, unloadMass } = options;
|
|
6113
|
+
const flightTime = calc_ship_flighttime(ship, UInt64.from(travelMass), UInt64.from(distance));
|
|
6114
|
+
const rechargeTime = needsRecharge ? calc_ship_rechargetime(ship) : UInt32.zero;
|
|
6115
|
+
let loadTime = UInt32.zero;
|
|
6116
|
+
let unloadTime = UInt32.zero;
|
|
6117
|
+
if (loadMass &&
|
|
6118
|
+
UInt32.from(loadMass).gt(UInt32.zero) &&
|
|
6119
|
+
ship.loaders &&
|
|
6120
|
+
ship.loaders.quantity.gt(UInt32.zero)) {
|
|
6121
|
+
const totalMass = UInt64.from(loadMass).adding(ship.loaders.mass);
|
|
6122
|
+
loadTime = calc_loader_flighttime(ship, totalMass).dividing(ship.loaders.quantity);
|
|
6123
|
+
}
|
|
6124
|
+
if (unloadMass &&
|
|
6125
|
+
UInt32.from(unloadMass).gt(UInt32.zero) &&
|
|
6126
|
+
ship.loaders &&
|
|
6127
|
+
ship.loaders.quantity.gt(UInt32.zero)) {
|
|
6128
|
+
const totalMass = UInt64.from(unloadMass).adding(ship.loaders.mass);
|
|
6129
|
+
unloadTime = calc_loader_flighttime(ship, totalMass).dividing(ship.loaders.quantity);
|
|
6130
|
+
}
|
|
6131
|
+
return {
|
|
6132
|
+
flightTime,
|
|
6133
|
+
rechargeTime,
|
|
6134
|
+
loadTime,
|
|
6135
|
+
unloadTime,
|
|
6136
|
+
total: flightTime.adding(rechargeTime).adding(loadTime).adding(unloadTime),
|
|
6137
|
+
};
|
|
6138
|
+
}
|
|
6139
|
+
function estimateDealTravelTime(ship, shipMass, distance, loadMass) {
|
|
6140
|
+
const needsRecharge = !hasEnergyForDistance$1(ship, distance);
|
|
6141
|
+
const estimate = estimateTravelTime(ship, shipMass, distance, {
|
|
6142
|
+
needsRecharge,
|
|
6143
|
+
loadMass,
|
|
6144
|
+
});
|
|
6145
|
+
return estimate.total;
|
|
6146
|
+
}
|
|
6147
|
+
function hasEnergyForDistance$1(ship, distance) {
|
|
6148
|
+
if (!ship.engines)
|
|
6149
|
+
return false;
|
|
6150
|
+
const energyNeeded = UInt64.from(distance).dividing(PRECISION$1).multiplying(ship.engines.drain);
|
|
6151
|
+
return UInt64.from(ship.energy ?? 0).gte(energyNeeded);
|
|
6152
|
+
}
|
|
6153
|
+
function getFlightOrigin(entity, flightTaskIndex) {
|
|
6154
|
+
if (!entity.schedule)
|
|
6155
|
+
return entity.coordinates;
|
|
6156
|
+
let origin = entity.coordinates;
|
|
6157
|
+
for (let i = 0; i < flightTaskIndex && i < entity.schedule.tasks.length; i++) {
|
|
6158
|
+
const task = entity.schedule.tasks[i];
|
|
6159
|
+
if (task.type.equals(TaskType.TRAVEL) && task.coordinates) {
|
|
6160
|
+
origin = task.coordinates;
|
|
6161
|
+
}
|
|
6162
|
+
}
|
|
6163
|
+
return origin;
|
|
6164
|
+
}
|
|
6165
|
+
function getDestinationLocation(entity) {
|
|
6166
|
+
if (!entity.schedule)
|
|
6167
|
+
return undefined;
|
|
6168
|
+
for (let i = entity.schedule.tasks.length - 1; i >= 0; i--) {
|
|
6169
|
+
const task = entity.schedule.tasks[i];
|
|
6170
|
+
if (task.type.equals(TaskType.TRAVEL) && task.coordinates) {
|
|
6171
|
+
return task.coordinates;
|
|
6172
|
+
}
|
|
6173
|
+
}
|
|
6174
|
+
return undefined;
|
|
6175
|
+
}
|
|
6176
|
+
function getPositionAt(entity, taskIndex, taskProgress) {
|
|
6177
|
+
if (!entity.schedule || entity.schedule.tasks.length === 0 || taskIndex < 0) {
|
|
6178
|
+
return entity.coordinates;
|
|
6179
|
+
}
|
|
6180
|
+
const task = entity.schedule.tasks[taskIndex];
|
|
6181
|
+
if (!task.type.equals(TaskType.TRAVEL) || !task.coordinates) {
|
|
6182
|
+
return getFlightOrigin(entity, taskIndex);
|
|
6183
|
+
}
|
|
6184
|
+
const origin = getFlightOrigin(entity, taskIndex);
|
|
6185
|
+
const destination = task.coordinates;
|
|
6186
|
+
const interpolated = lerp(origin, destination, taskProgress);
|
|
6187
|
+
return {
|
|
6188
|
+
x: Math.round(interpolated.x),
|
|
6189
|
+
y: Math.round(interpolated.y),
|
|
6190
|
+
};
|
|
6191
|
+
}
|
|
6192
|
+
function calc_transfer_duration(source, dest, cargoMass) {
|
|
6193
|
+
if (cargoMass === 0) {
|
|
6194
|
+
return 0;
|
|
6195
|
+
}
|
|
6196
|
+
let totalThrust = 0;
|
|
6197
|
+
let totalLoaderMass = 0;
|
|
6198
|
+
let totalQuantity = 0;
|
|
6199
|
+
if (source.loaders) {
|
|
6200
|
+
const thrust = typeof source.loaders.thrust === 'number'
|
|
6201
|
+
? source.loaders.thrust
|
|
6202
|
+
: source.loaders.thrust.toNumber();
|
|
6203
|
+
const mass = typeof source.loaders.mass === 'number'
|
|
6204
|
+
? source.loaders.mass
|
|
6205
|
+
: source.loaders.mass.toNumber();
|
|
6206
|
+
const qty = typeof source.loaders.quantity === 'number'
|
|
6207
|
+
? source.loaders.quantity
|
|
6208
|
+
: source.loaders.quantity.toNumber();
|
|
6209
|
+
totalThrust += thrust * qty;
|
|
6210
|
+
totalLoaderMass += mass * qty;
|
|
6211
|
+
totalQuantity += qty;
|
|
6212
|
+
}
|
|
6213
|
+
if (dest.loaders) {
|
|
6214
|
+
const thrust = typeof dest.loaders.thrust === 'number'
|
|
6215
|
+
? dest.loaders.thrust
|
|
6216
|
+
: dest.loaders.thrust.toNumber();
|
|
6217
|
+
const mass = typeof dest.loaders.mass === 'number' ? dest.loaders.mass : dest.loaders.mass.toNumber();
|
|
6218
|
+
const qty = typeof dest.loaders.quantity === 'number'
|
|
6219
|
+
? dest.loaders.quantity
|
|
6220
|
+
: dest.loaders.quantity.toNumber();
|
|
6221
|
+
totalThrust += thrust * qty;
|
|
6222
|
+
totalLoaderMass += mass * qty;
|
|
6223
|
+
totalQuantity += qty;
|
|
6224
|
+
}
|
|
6225
|
+
if (totalThrust === 0 || totalQuantity === 0) {
|
|
6226
|
+
return 0;
|
|
6227
|
+
}
|
|
6228
|
+
const sourceZ = typeof source.location.z === 'number'
|
|
6229
|
+
? source.location.z
|
|
6230
|
+
: source.location.z?.toNumber() ?? 0;
|
|
6231
|
+
const destZ = typeof dest.location.z === 'number' ? dest.location.z : dest.location.z?.toNumber() ?? 0;
|
|
6232
|
+
const distance = Math.abs(sourceZ - destZ);
|
|
6233
|
+
const totalMass = cargoMass + totalLoaderMass;
|
|
6234
|
+
const acceleration = calc_acceleration(totalThrust, totalMass);
|
|
6235
|
+
const flightTime = 2 * Math.sqrt(distance / acceleration);
|
|
6236
|
+
return Math.floor(flightTime / totalQuantity);
|
|
6237
|
+
}
|
|
6238
|
+
|
|
6239
|
+
function capsHasMovement(caps) {
|
|
6240
|
+
return caps.engines !== undefined && caps.generator !== undefined;
|
|
6241
|
+
}
|
|
6242
|
+
function capsHasStorage(caps) {
|
|
6243
|
+
return caps.capacity !== undefined;
|
|
6244
|
+
}
|
|
6245
|
+
function capsHasLoaders(caps) {
|
|
6246
|
+
return caps.loaders !== undefined;
|
|
6247
|
+
}
|
|
6248
|
+
function capsHasGatherer(caps) {
|
|
6249
|
+
return caps.gatherer !== undefined;
|
|
6250
|
+
}
|
|
6251
|
+
function capsHasMass(caps) {
|
|
6252
|
+
return caps.hullmass !== undefined;
|
|
6253
|
+
}
|
|
6254
|
+
|
|
6255
|
+
function calcCargoItemMass(item) {
|
|
6256
|
+
const itemDef = getItem(item.item_id);
|
|
6257
|
+
let mass = UInt64.from(itemDef.mass).multiplying(item.quantity);
|
|
6258
|
+
for (const mod of item.modules) {
|
|
6259
|
+
if (mod.installed) {
|
|
6260
|
+
const modDef = getItem(mod.installed.item_id);
|
|
6261
|
+
mass = mass.adding(modDef.mass);
|
|
6262
|
+
}
|
|
6263
|
+
}
|
|
6264
|
+
return mass;
|
|
6265
|
+
}
|
|
6266
|
+
function calcCargoMass(entity) {
|
|
6267
|
+
let mass = UInt64.from(0);
|
|
6268
|
+
for (const item of entity.cargo) {
|
|
6269
|
+
mass = mass.adding(calcCargoItemMass(item));
|
|
6270
|
+
}
|
|
6271
|
+
return mass;
|
|
6272
|
+
}
|
|
6273
|
+
function calcStacksMass(stacks) {
|
|
6274
|
+
let mass = UInt64.from(0);
|
|
6275
|
+
for (const s of stacks) {
|
|
6276
|
+
mass = mass.adding(calcCargoItemMass(s));
|
|
6277
|
+
}
|
|
6278
|
+
return mass;
|
|
6279
|
+
}
|
|
6280
|
+
function availableCapacity$1(entity) {
|
|
6281
|
+
const cargoMass = calcCargoMass(entity);
|
|
6282
|
+
return entity.capacity.gt(cargoMass)
|
|
6283
|
+
? UInt64.from(entity.capacity).subtracting(cargoMass)
|
|
6284
|
+
: UInt64.from(0);
|
|
6285
|
+
}
|
|
6286
|
+
function availableCapacityFromMass(capacity, cargoMass) {
|
|
6287
|
+
const cap = UInt64.from(capacity);
|
|
6288
|
+
const mass = UInt64.from(cargoMass);
|
|
6289
|
+
return cap.gt(mass) ? cap.subtracting(mass) : UInt64.from(0);
|
|
6290
|
+
}
|
|
6291
|
+
function hasSpace$1(entity, goodMass, quantity) {
|
|
6292
|
+
const additional = goodMass.multiplying(quantity);
|
|
6293
|
+
return availableCapacity$1(entity).gte(additional);
|
|
6294
|
+
}
|
|
6295
|
+
function hasSpaceForMass(capacity, currentMass, additionalMass) {
|
|
6296
|
+
return UInt64.from(currentMass).adding(additionalMass).lte(capacity);
|
|
6297
|
+
}
|
|
6298
|
+
function isFull$1(entity) {
|
|
6299
|
+
return UInt64.from(entity.cargomass).gte(entity.capacity);
|
|
6300
|
+
}
|
|
6301
|
+
function isFullFromMass(capacity, cargoMass) {
|
|
6302
|
+
return UInt64.from(cargoMass).gte(capacity);
|
|
6303
|
+
}
|
|
6304
|
+
function cargoItemToStack(item) {
|
|
6305
|
+
return {
|
|
6306
|
+
item_id: UInt16.from(item.item_id),
|
|
6307
|
+
quantity: UInt32.from(item.quantity),
|
|
6308
|
+
seed: item.seed,
|
|
6309
|
+
modules: item.modules ?? [],
|
|
6310
|
+
};
|
|
6311
|
+
}
|
|
6312
|
+
function stackToCargoItem(stack) {
|
|
6313
|
+
return Types.cargo_item.from({
|
|
6314
|
+
item_id: stack.item_id,
|
|
6315
|
+
quantity: stack.quantity,
|
|
6316
|
+
seed: stack.seed,
|
|
6317
|
+
modules: stack.modules,
|
|
6318
|
+
});
|
|
6319
|
+
}
|
|
6320
|
+
function seedEquals(a, b) {
|
|
6321
|
+
if (!a && !b)
|
|
6322
|
+
return true;
|
|
6323
|
+
if (!a || !b)
|
|
6324
|
+
return false;
|
|
6325
|
+
return a.equals(b);
|
|
6326
|
+
}
|
|
6327
|
+
function stackIdentityEqual(a, b) {
|
|
6328
|
+
return a.item_id.equals(b.item_id) && seedEquals(a.seed, b.seed);
|
|
6329
|
+
}
|
|
6330
|
+
function stackKey(s) {
|
|
6331
|
+
const seedVal = s.seed ? s.seed.toString() : '0';
|
|
6332
|
+
return `${s.item_id.toNumber()}:${seedVal}`;
|
|
6333
|
+
}
|
|
6334
|
+
function stacksEqual(a, b) {
|
|
6335
|
+
return stackIdentityEqual(a, b) && a.quantity.equals(b.quantity);
|
|
6336
|
+
}
|
|
6337
|
+
function mergeStacks(stacks, add) {
|
|
6338
|
+
const idx = stacks.findIndex((s) => stackIdentityEqual(s, add));
|
|
6339
|
+
if (idx === -1) {
|
|
6340
|
+
return [...stacks, { ...add }];
|
|
6341
|
+
}
|
|
6342
|
+
const result = stacks.slice();
|
|
6343
|
+
result[idx] = {
|
|
6344
|
+
...result[idx],
|
|
6345
|
+
quantity: UInt32.from(result[idx].quantity.adding(add.quantity)),
|
|
6346
|
+
};
|
|
6347
|
+
return result;
|
|
6348
|
+
}
|
|
6349
|
+
function removeFromStacks(stacks, remove) {
|
|
6350
|
+
const idx = stacks.findIndex((s) => stackIdentityEqual(s, remove));
|
|
6351
|
+
if (idx === -1) {
|
|
6352
|
+
throw new Error(INSUFFICIENT_ITEM_QUANTITY);
|
|
6353
|
+
}
|
|
6354
|
+
const target = stacks[idx];
|
|
6355
|
+
if (target.quantity.lt(remove.quantity)) {
|
|
6356
|
+
throw new Error(INSUFFICIENT_ITEM_QUANTITY);
|
|
6357
|
+
}
|
|
6358
|
+
const remaining = UInt32.from(target.quantity.subtracting(remove.quantity));
|
|
6359
|
+
if (remaining.equals(UInt32.from(0))) {
|
|
6360
|
+
return [...stacks.slice(0, idx), ...stacks.slice(idx + 1)];
|
|
6361
|
+
}
|
|
6362
|
+
const result = stacks.slice();
|
|
6363
|
+
result[idx] = { ...target, quantity: remaining };
|
|
6364
|
+
return result;
|
|
6365
|
+
}
|
|
6366
|
+
|
|
6367
|
+
function hasSchedule$1(entity) {
|
|
6368
|
+
return !!entity.schedule && entity.schedule.tasks.length > 0;
|
|
6369
|
+
}
|
|
6370
|
+
function isIdle(entity) {
|
|
6371
|
+
return !hasSchedule$1(entity);
|
|
6372
|
+
}
|
|
6373
|
+
function getTasks(entity) {
|
|
6374
|
+
return entity.schedule?.tasks || [];
|
|
6375
|
+
}
|
|
6376
|
+
function scheduleDuration(entity) {
|
|
6377
|
+
if (!entity.schedule)
|
|
6378
|
+
return 0;
|
|
6379
|
+
return entity.schedule.tasks.reduce((sum, task) => sum + task.duration.toNumber(), 0);
|
|
6380
|
+
}
|
|
6381
|
+
function scheduleElapsed(entity, now) {
|
|
6382
|
+
if (!entity.schedule)
|
|
6383
|
+
return 0;
|
|
6384
|
+
const started = entity.schedule.started.toDate();
|
|
6385
|
+
const elapsed = Math.floor((now.getTime() - started.getTime()) / 1000);
|
|
6386
|
+
return Math.max(0, elapsed);
|
|
6387
|
+
}
|
|
6388
|
+
function scheduleRemaining(entity, now) {
|
|
6389
|
+
if (!entity.schedule)
|
|
6390
|
+
return 0;
|
|
6391
|
+
const duration = scheduleDuration(entity);
|
|
6392
|
+
const elapsed = scheduleElapsed(entity, now);
|
|
6393
|
+
return Math.max(0, duration - elapsed);
|
|
6394
|
+
}
|
|
6395
|
+
function scheduleComplete(entity, now) {
|
|
6396
|
+
return hasSchedule$1(entity) && scheduleRemaining(entity, now) === 0;
|
|
6397
|
+
}
|
|
6398
|
+
function currentTaskIndex(entity, now) {
|
|
6399
|
+
if (!entity.schedule || entity.schedule.tasks.length === 0)
|
|
6400
|
+
return -1;
|
|
6401
|
+
const elapsed = scheduleElapsed(entity, now);
|
|
6402
|
+
let timeAccum = 0;
|
|
6403
|
+
for (let i = 0; i < entity.schedule.tasks.length; i++) {
|
|
6404
|
+
const taskDuration = entity.schedule.tasks[i].duration.toNumber();
|
|
6405
|
+
if (elapsed < timeAccum + taskDuration) {
|
|
6406
|
+
return i;
|
|
6407
|
+
}
|
|
6408
|
+
timeAccum += taskDuration;
|
|
6409
|
+
}
|
|
6410
|
+
return entity.schedule.tasks.length - 1;
|
|
6411
|
+
}
|
|
6412
|
+
function currentTask(entity, now) {
|
|
6413
|
+
const index = currentTaskIndex(entity, now);
|
|
6414
|
+
if (index < 0 || !entity.schedule)
|
|
6415
|
+
return undefined;
|
|
6416
|
+
return entity.schedule.tasks[index];
|
|
6417
|
+
}
|
|
6418
|
+
function currentTaskType(entity, now) {
|
|
6419
|
+
const task = currentTask(entity, now);
|
|
6420
|
+
if (!task)
|
|
6421
|
+
return undefined;
|
|
6422
|
+
return task.type.toNumber();
|
|
6423
|
+
}
|
|
6424
|
+
function getTaskStartTime(entity, index) {
|
|
6425
|
+
if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length)
|
|
6426
|
+
return 0;
|
|
6427
|
+
let timeAccum = 0;
|
|
6428
|
+
for (let i = 0; i < index; i++) {
|
|
6429
|
+
timeAccum += entity.schedule.tasks[i].duration.toNumber();
|
|
6430
|
+
}
|
|
6431
|
+
return timeAccum;
|
|
6432
|
+
}
|
|
6433
|
+
function getTaskElapsed(entity, index, now) {
|
|
6434
|
+
if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length)
|
|
6435
|
+
return 0;
|
|
6436
|
+
const elapsed = scheduleElapsed(entity, now);
|
|
6437
|
+
const taskStart = getTaskStartTime(entity, index);
|
|
6438
|
+
const taskDuration = entity.schedule.tasks[index].duration.toNumber();
|
|
6439
|
+
if (elapsed <= taskStart)
|
|
6440
|
+
return 0;
|
|
6441
|
+
const elapsedInTask = elapsed - taskStart;
|
|
6442
|
+
return Math.min(elapsedInTask, taskDuration);
|
|
6443
|
+
}
|
|
6444
|
+
function getTaskRemaining(entity, index, now) {
|
|
6445
|
+
if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length)
|
|
6446
|
+
return 0;
|
|
6447
|
+
const taskDuration = entity.schedule.tasks[index].duration.toNumber();
|
|
6448
|
+
const taskElapsed = getTaskElapsed(entity, index, now);
|
|
6449
|
+
return Math.max(0, taskDuration - taskElapsed);
|
|
6450
|
+
}
|
|
6451
|
+
function isTaskComplete(entity, index, now) {
|
|
6452
|
+
if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length)
|
|
6453
|
+
return false;
|
|
6454
|
+
const taskDuration = entity.schedule.tasks[index].duration.toNumber();
|
|
6455
|
+
const taskElapsed = getTaskElapsed(entity, index, now);
|
|
6456
|
+
return taskElapsed >= taskDuration;
|
|
6457
|
+
}
|
|
6458
|
+
function isTaskInProgress(entity, index, now) {
|
|
6459
|
+
if (!entity.schedule || index < 0 || index >= entity.schedule.tasks.length)
|
|
6460
|
+
return false;
|
|
6461
|
+
const taskElapsed = getTaskElapsed(entity, index, now);
|
|
6462
|
+
const taskDuration = entity.schedule.tasks[index].duration.toNumber();
|
|
6463
|
+
return taskElapsed > 0 && taskElapsed < taskDuration;
|
|
6464
|
+
}
|
|
6465
|
+
function currentTaskProgress(entity, now) {
|
|
6466
|
+
const task = currentTask(entity, now);
|
|
6467
|
+
if (!task)
|
|
6468
|
+
return 0;
|
|
6469
|
+
const index = currentTaskIndex(entity, now);
|
|
6470
|
+
const elapsed = getTaskElapsed(entity, index, now);
|
|
6471
|
+
const duration = task.duration.toNumber();
|
|
6472
|
+
if (duration === 0)
|
|
6473
|
+
return 1;
|
|
6474
|
+
return Math.min(1, elapsed / duration);
|
|
6475
|
+
}
|
|
6476
|
+
function scheduleProgress(entity, now) {
|
|
6477
|
+
const duration = scheduleDuration(entity);
|
|
6478
|
+
if (duration === 0)
|
|
6479
|
+
return hasSchedule$1(entity) ? 1 : 0;
|
|
6480
|
+
const elapsed = scheduleElapsed(entity, now);
|
|
6481
|
+
return Math.min(1, elapsed / duration);
|
|
6482
|
+
}
|
|
6483
|
+
function isTaskType(entity, taskType, now) {
|
|
6484
|
+
return currentTaskType(entity, now) === taskType;
|
|
6485
|
+
}
|
|
6486
|
+
function isInFlight(entity, now) {
|
|
6487
|
+
return isTaskType(entity, TaskType.TRAVEL, now);
|
|
6488
|
+
}
|
|
6489
|
+
function isRecharging(entity, now) {
|
|
6490
|
+
return isTaskType(entity, TaskType.RECHARGE, now);
|
|
6491
|
+
}
|
|
6492
|
+
function isLoading(entity, now) {
|
|
6493
|
+
return isTaskType(entity, TaskType.LOAD, now);
|
|
6494
|
+
}
|
|
6495
|
+
function isUnloading(entity, now) {
|
|
6496
|
+
return isTaskType(entity, TaskType.UNLOAD, now);
|
|
6497
|
+
}
|
|
6498
|
+
function isGathering(entity, now) {
|
|
6499
|
+
return isTaskType(entity, TaskType.GATHER, now);
|
|
6500
|
+
}
|
|
6501
|
+
|
|
6502
|
+
var schedule = /*#__PURE__*/Object.freeze({
|
|
6503
|
+
__proto__: null,
|
|
6504
|
+
hasSchedule: hasSchedule$1,
|
|
6505
|
+
isIdle: isIdle,
|
|
6506
|
+
getTasks: getTasks,
|
|
6507
|
+
scheduleDuration: scheduleDuration,
|
|
6508
|
+
scheduleElapsed: scheduleElapsed,
|
|
6509
|
+
scheduleRemaining: scheduleRemaining,
|
|
6510
|
+
scheduleComplete: scheduleComplete,
|
|
6511
|
+
currentTaskIndex: currentTaskIndex,
|
|
6512
|
+
currentTask: currentTask,
|
|
6513
|
+
currentTaskType: currentTaskType,
|
|
6514
|
+
getTaskStartTime: getTaskStartTime,
|
|
6515
|
+
getTaskElapsed: getTaskElapsed,
|
|
6516
|
+
getTaskRemaining: getTaskRemaining,
|
|
6517
|
+
isTaskComplete: isTaskComplete,
|
|
6518
|
+
isTaskInProgress: isTaskInProgress,
|
|
6519
|
+
currentTaskProgress: currentTaskProgress,
|
|
6520
|
+
scheduleProgress: scheduleProgress,
|
|
6521
|
+
isTaskType: isTaskType,
|
|
6522
|
+
isInFlight: isInFlight,
|
|
6523
|
+
isRecharging: isRecharging,
|
|
6524
|
+
isLoading: isLoading,
|
|
6525
|
+
isUnloading: isUnloading,
|
|
6526
|
+
isGathering: isGathering
|
|
6527
|
+
});
|
|
6528
|
+
|
|
6529
|
+
function getHullMass(entity) {
|
|
6530
|
+
return UInt32.from(entity.hullmass ?? 0);
|
|
6531
|
+
}
|
|
6532
|
+
function createProjectedEntity(entity) {
|
|
6533
|
+
const shipMass = getHullMass(entity);
|
|
6534
|
+
const loaders = entity.loaders;
|
|
6535
|
+
const engines = entity.engines;
|
|
6536
|
+
const generator = entity.generator;
|
|
6537
|
+
const hauler = entity.hauler;
|
|
6538
|
+
const capacity = entity.capacity;
|
|
6539
|
+
const cargo = entity.cargo.map(cargoItemToStack);
|
|
6540
|
+
const projected = {
|
|
6541
|
+
location: Coordinates.from(entity.coordinates),
|
|
6542
|
+
energy: UInt16.from(entity.energy ?? 0),
|
|
6543
|
+
cargo,
|
|
6544
|
+
shipMass,
|
|
6545
|
+
capacity: capacity ? UInt64.from(capacity) : undefined,
|
|
6546
|
+
engines,
|
|
6547
|
+
generator,
|
|
6548
|
+
hauler,
|
|
6549
|
+
loaders,
|
|
6550
|
+
get cargoMass() {
|
|
6551
|
+
return calcStacksMass(this.cargo);
|
|
6552
|
+
},
|
|
6553
|
+
get totalMass() {
|
|
6554
|
+
let mass = UInt64.from(this.shipMass).adding(this.cargoMass);
|
|
6555
|
+
if (this.loaders) {
|
|
6556
|
+
mass = mass.adding(this.loaders.mass.multiplying(this.loaders.quantity));
|
|
6557
|
+
}
|
|
6558
|
+
return mass;
|
|
6559
|
+
},
|
|
6560
|
+
hasMovement() {
|
|
6561
|
+
return capsHasMovement(this.capabilities());
|
|
6562
|
+
},
|
|
6563
|
+
hasStorage() {
|
|
6564
|
+
return capsHasStorage(this.capabilities());
|
|
6565
|
+
},
|
|
6566
|
+
hasLoaders() {
|
|
6567
|
+
return capsHasLoaders(this.capabilities());
|
|
6568
|
+
},
|
|
6569
|
+
capabilities() {
|
|
6570
|
+
return {
|
|
6571
|
+
hullmass: this.shipMass,
|
|
6572
|
+
capacity: this.capacity ? UInt32.from(this.capacity) : undefined,
|
|
6573
|
+
engines: this.engines,
|
|
6574
|
+
generator: this.generator,
|
|
6575
|
+
loaders: this.loaders,
|
|
6576
|
+
};
|
|
6577
|
+
},
|
|
6578
|
+
state() {
|
|
6579
|
+
return {
|
|
6580
|
+
owner: entity.owner ?? Name.from(''),
|
|
6581
|
+
location: Types.coordinates.from(this.location),
|
|
6582
|
+
energy: this.energy,
|
|
6583
|
+
cargomass: UInt32.from(this.cargoMass),
|
|
6584
|
+
cargo: this.cargo.map(stackToCargoItem),
|
|
6585
|
+
};
|
|
6586
|
+
},
|
|
6587
|
+
};
|
|
6588
|
+
return projected;
|
|
6589
|
+
}
|
|
6590
|
+
function applyRechargeTask(projected, _task, options) {
|
|
6591
|
+
if (!projected.generator)
|
|
6592
|
+
return;
|
|
6593
|
+
if (options.complete) {
|
|
6594
|
+
projected.energy = UInt16.from(projected.generator.capacity);
|
|
6595
|
+
}
|
|
6596
|
+
else if (options.progress !== undefined) {
|
|
6597
|
+
const capacity = Number(projected.generator.capacity);
|
|
6598
|
+
const currentEnergy = Number(projected.energy);
|
|
6599
|
+
const rechargeAmount = (capacity - currentEnergy) * options.progress;
|
|
6600
|
+
projected.energy = UInt16.from(Math.min(capacity, currentEnergy + rechargeAmount));
|
|
6601
|
+
}
|
|
6602
|
+
}
|
|
6603
|
+
function applyFlightTask(projected, task, options) {
|
|
6604
|
+
if (!task.coordinates || !projected.engines)
|
|
6605
|
+
return;
|
|
6606
|
+
const origin = projected.location;
|
|
6607
|
+
const destination = Coordinates.from(task.coordinates);
|
|
6608
|
+
const distance = distanceBetweenCoordinates(origin, task.coordinates);
|
|
6609
|
+
const energyUsage = distance.dividing(PRECISION$1).multiplying(projected.engines.drain);
|
|
6610
|
+
if (options.complete) {
|
|
6611
|
+
projected.energy = projected.energy.gt(energyUsage)
|
|
6612
|
+
? UInt16.from(projected.energy.subtracting(energyUsage))
|
|
6613
|
+
: UInt16.from(0);
|
|
6614
|
+
projected.location = destination;
|
|
6615
|
+
}
|
|
6616
|
+
else if (options.progress !== undefined) {
|
|
6617
|
+
const interpolated = lerp(origin, destination, options.progress);
|
|
6618
|
+
projected.location = Coordinates.from({
|
|
6619
|
+
x: Math.round(interpolated.x),
|
|
6620
|
+
y: Math.round(interpolated.y),
|
|
6621
|
+
});
|
|
6622
|
+
const partialEnergy = UInt64.from(Math.floor(Number(energyUsage) * options.progress));
|
|
6623
|
+
projected.energy = projected.energy.gt(partialEnergy)
|
|
6624
|
+
? UInt16.from(projected.energy.subtracting(partialEnergy))
|
|
6625
|
+
: UInt16.from(0);
|
|
6626
|
+
}
|
|
6627
|
+
}
|
|
6628
|
+
function addCargoItem(projected, item) {
|
|
6629
|
+
projected.cargo = mergeStacks(projected.cargo, cargoItemToStack(item));
|
|
6630
|
+
}
|
|
6631
|
+
function removeCargoItem(projected, item) {
|
|
6632
|
+
projected.cargo = removeFromStacks(projected.cargo, cargoItemToStack(item));
|
|
6633
|
+
}
|
|
6634
|
+
function applyAddCargoTask(projected, task) {
|
|
6635
|
+
for (const item of task.cargo) {
|
|
6636
|
+
addCargoItem(projected, item);
|
|
6637
|
+
}
|
|
6638
|
+
}
|
|
6639
|
+
function applyRemoveCargoTask(projected, task) {
|
|
6640
|
+
for (const item of task.cargo) {
|
|
6641
|
+
removeCargoItem(projected, item);
|
|
6642
|
+
}
|
|
6643
|
+
}
|
|
6644
|
+
function applyEnergyCost(projected, task) {
|
|
6645
|
+
if (!task.energy_cost)
|
|
6646
|
+
return;
|
|
6647
|
+
const energyCost = UInt16.from(task.energy_cost);
|
|
6648
|
+
projected.energy = projected.energy.gt(energyCost)
|
|
6649
|
+
? UInt16.from(projected.energy.subtracting(energyCost))
|
|
6650
|
+
: UInt16.from(0);
|
|
6651
|
+
}
|
|
6652
|
+
function applyGatherTask(projected, task, options) {
|
|
6653
|
+
if (!options.complete)
|
|
6654
|
+
return;
|
|
6655
|
+
applyEnergyCost(projected, task);
|
|
6656
|
+
applyAddCargoTask(projected, task);
|
|
6657
|
+
}
|
|
6658
|
+
function applyCraftTask(projected, task) {
|
|
6659
|
+
applyEnergyCost(projected, task);
|
|
6660
|
+
if (task.cargo.length === 0)
|
|
6661
|
+
return;
|
|
6662
|
+
for (let i = 0; i < task.cargo.length - 1; i++) {
|
|
6663
|
+
removeCargoItem(projected, task.cargo[i]);
|
|
6664
|
+
}
|
|
6665
|
+
addCargoItem(projected, task.cargo[task.cargo.length - 1]);
|
|
6666
|
+
}
|
|
6667
|
+
function applyDeployTask(projected, task) {
|
|
6668
|
+
applyEnergyCost(projected, task);
|
|
6669
|
+
if (task.cargo.length > 0) {
|
|
6670
|
+
removeCargoItem(projected, task.cargo[0]);
|
|
6671
|
+
}
|
|
6672
|
+
}
|
|
6673
|
+
function applyTask(projected, task) {
|
|
6674
|
+
switch (task.type.toNumber()) {
|
|
6675
|
+
case TaskType.RECHARGE:
|
|
6676
|
+
applyRechargeTask(projected, task, { complete: true });
|
|
6677
|
+
break;
|
|
6678
|
+
case TaskType.TRAVEL:
|
|
6679
|
+
applyFlightTask(projected, task, { complete: true });
|
|
6680
|
+
break;
|
|
6681
|
+
case TaskType.LOAD:
|
|
6682
|
+
case TaskType.UNWRAP:
|
|
6683
|
+
applyAddCargoTask(projected, task);
|
|
6684
|
+
break;
|
|
6685
|
+
case TaskType.UNLOAD:
|
|
6686
|
+
case TaskType.WRAP:
|
|
6687
|
+
applyRemoveCargoTask(projected, task);
|
|
6688
|
+
break;
|
|
6689
|
+
case TaskType.GATHER:
|
|
6690
|
+
applyGatherTask(projected, task, { complete: true });
|
|
6691
|
+
break;
|
|
6692
|
+
case TaskType.CRAFT:
|
|
6693
|
+
applyCraftTask(projected, task);
|
|
6694
|
+
break;
|
|
6695
|
+
case TaskType.DEPLOY:
|
|
6696
|
+
applyDeployTask(projected, task);
|
|
6697
|
+
break;
|
|
6698
|
+
}
|
|
6699
|
+
}
|
|
6700
|
+
function projectEntity(entity, options) {
|
|
6701
|
+
const projected = createProjectedEntity(entity);
|
|
6702
|
+
if (!entity.schedule || entity.schedule.tasks.length === 0)
|
|
6703
|
+
return projected;
|
|
6704
|
+
const tasks = entity.schedule.tasks;
|
|
6705
|
+
const taskCount = options?.upToTaskIndex !== undefined
|
|
6706
|
+
? Math.max(0, Math.min(options.upToTaskIndex, tasks.length))
|
|
6707
|
+
: tasks.length;
|
|
6708
|
+
for (let i = 0; i < taskCount; i++) {
|
|
6709
|
+
applyTask(projected, tasks[i]);
|
|
6710
|
+
}
|
|
6711
|
+
return projected;
|
|
6712
|
+
}
|
|
6713
|
+
function validateSchedule(entity) {
|
|
6714
|
+
if (!entity.schedule || entity.schedule.tasks.length === 0)
|
|
6715
|
+
return;
|
|
6716
|
+
const projected = createProjectedEntity(entity);
|
|
6717
|
+
for (const task of entity.schedule.tasks) {
|
|
6718
|
+
applyTask(projected, task);
|
|
6719
|
+
if (projected.capacity && projected.cargoMass.gt(projected.capacity)) {
|
|
6720
|
+
throw new Error(ENTITY_CAPACITY_EXCEEDED);
|
|
6721
|
+
}
|
|
6722
|
+
}
|
|
6723
|
+
}
|
|
6724
|
+
function projectEntityAt(entity, now) {
|
|
6725
|
+
const projected = createProjectedEntity(entity);
|
|
6726
|
+
if (!entity.schedule || entity.schedule.tasks.length === 0) {
|
|
6727
|
+
return projected;
|
|
6728
|
+
}
|
|
6729
|
+
for (let i = 0; i < entity.schedule.tasks.length; i++) {
|
|
6730
|
+
const task = entity.schedule.tasks[i];
|
|
6731
|
+
const taskComplete = isTaskComplete(entity, i, now);
|
|
6732
|
+
const taskInProgress = isTaskInProgress(entity, i, now);
|
|
6733
|
+
if (!taskComplete && !taskInProgress) {
|
|
6734
|
+
break;
|
|
6735
|
+
}
|
|
6736
|
+
const progress = taskInProgress
|
|
6737
|
+
? getTaskElapsed(entity, i, now) / task.duration.toNumber()
|
|
6738
|
+
: undefined;
|
|
6739
|
+
switch (task.type.toNumber()) {
|
|
6740
|
+
case TaskType.RECHARGE:
|
|
6741
|
+
applyRechargeTask(projected, task, { complete: taskComplete, progress });
|
|
6742
|
+
break;
|
|
6743
|
+
case TaskType.TRAVEL:
|
|
6744
|
+
applyFlightTask(projected, task, { complete: taskComplete, progress });
|
|
6745
|
+
break;
|
|
6746
|
+
case TaskType.LOAD:
|
|
6747
|
+
case TaskType.UNWRAP:
|
|
6748
|
+
if (taskComplete)
|
|
6749
|
+
applyAddCargoTask(projected, task);
|
|
6750
|
+
break;
|
|
6751
|
+
case TaskType.UNLOAD:
|
|
6752
|
+
case TaskType.WRAP:
|
|
6753
|
+
if (taskComplete)
|
|
6754
|
+
applyRemoveCargoTask(projected, task);
|
|
6755
|
+
break;
|
|
6756
|
+
case TaskType.GATHER:
|
|
6757
|
+
if (taskComplete)
|
|
6758
|
+
applyGatherTask(projected, task, { complete: true });
|
|
6759
|
+
break;
|
|
6760
|
+
case TaskType.CRAFT:
|
|
6761
|
+
if (taskComplete)
|
|
6762
|
+
applyCraftTask(projected, task);
|
|
6763
|
+
break;
|
|
6764
|
+
case TaskType.DEPLOY:
|
|
6765
|
+
if (taskComplete)
|
|
6766
|
+
applyDeployTask(projected, task);
|
|
6767
|
+
break;
|
|
6768
|
+
}
|
|
6769
|
+
}
|
|
6770
|
+
return projected;
|
|
6771
|
+
}
|
|
6772
|
+
|
|
6773
|
+
class Location {
|
|
6774
|
+
constructor(coordinates) {
|
|
6775
|
+
this.coordinates = Coordinates.from(coordinates);
|
|
6776
|
+
}
|
|
6777
|
+
static from(coordinates) {
|
|
6778
|
+
return new Location(Coordinates.from(coordinates));
|
|
6779
|
+
}
|
|
6780
|
+
hasSystemAt(gameSeed) {
|
|
6781
|
+
const seed = Checksum256.from(gameSeed);
|
|
6782
|
+
if (this._hasSystem === undefined || !this._gameSeed?.equals(seed)) {
|
|
6783
|
+
this._gameSeed = seed;
|
|
6784
|
+
this._hasSystem = hasSystem(seed, this.coordinates);
|
|
6785
|
+
}
|
|
6786
|
+
return this._hasSystem;
|
|
6787
|
+
}
|
|
6788
|
+
getLocationTypeAt(gameSeed) {
|
|
6789
|
+
return getLocationType(gameSeed, this.coordinates);
|
|
6790
|
+
}
|
|
6791
|
+
isGatherableAt(gameSeed) {
|
|
6792
|
+
return isGatherableLocation(this.getLocationTypeAt(gameSeed));
|
|
6793
|
+
}
|
|
6794
|
+
findNearby(gameSeed, maxDistance = 20) {
|
|
6795
|
+
return findNearbyPlanets(Checksum256.from(gameSeed), this.coordinates, maxDistance);
|
|
6796
|
+
}
|
|
6797
|
+
equals(other) {
|
|
6798
|
+
const otherCoords = other instanceof Location ? other.coordinates : Coordinates.from(other);
|
|
6799
|
+
return this.coordinates.equals(otherCoords);
|
|
6800
|
+
}
|
|
6801
|
+
get epoch() {
|
|
6802
|
+
return this._epoch;
|
|
6803
|
+
}
|
|
6804
|
+
clearCache() {
|
|
6805
|
+
this._epoch = undefined;
|
|
6806
|
+
}
|
|
6807
|
+
}
|
|
6808
|
+
function toLocation(coords) {
|
|
6809
|
+
if (coords instanceof Location) {
|
|
6810
|
+
return coords;
|
|
6811
|
+
}
|
|
6812
|
+
return Location.from(coords);
|
|
6813
|
+
}
|
|
6814
|
+
|
|
6815
|
+
class ScheduleAccessor {
|
|
6816
|
+
constructor(entity) {
|
|
6817
|
+
this.entity = entity;
|
|
6818
|
+
}
|
|
6819
|
+
get hasSchedule() {
|
|
6820
|
+
return hasSchedule$1(this.entity);
|
|
6821
|
+
}
|
|
6822
|
+
get isIdle() {
|
|
6823
|
+
return isIdle(this.entity);
|
|
6824
|
+
}
|
|
6825
|
+
get tasks() {
|
|
6826
|
+
return getTasks(this.entity);
|
|
6827
|
+
}
|
|
6828
|
+
duration() {
|
|
6829
|
+
return scheduleDuration(this.entity);
|
|
6830
|
+
}
|
|
6831
|
+
elapsed(now) {
|
|
6832
|
+
return scheduleElapsed(this.entity, now);
|
|
6833
|
+
}
|
|
6834
|
+
remaining(now) {
|
|
6835
|
+
return scheduleRemaining(this.entity, now);
|
|
6836
|
+
}
|
|
6837
|
+
complete(now) {
|
|
6838
|
+
return scheduleComplete(this.entity, now);
|
|
6839
|
+
}
|
|
6840
|
+
currentTaskIndex(now) {
|
|
6841
|
+
return currentTaskIndex(this.entity, now);
|
|
6842
|
+
}
|
|
6843
|
+
currentTask(now) {
|
|
6844
|
+
return currentTask(this.entity, now);
|
|
6845
|
+
}
|
|
6846
|
+
currentTaskType(now) {
|
|
6847
|
+
return currentTaskType(this.entity, now);
|
|
6848
|
+
}
|
|
6849
|
+
taskStartTime(index) {
|
|
6850
|
+
return getTaskStartTime(this.entity, index);
|
|
6851
|
+
}
|
|
6852
|
+
taskElapsed(index, now) {
|
|
6853
|
+
return getTaskElapsed(this.entity, index, now);
|
|
6854
|
+
}
|
|
6855
|
+
taskRemaining(index, now) {
|
|
6856
|
+
return getTaskRemaining(this.entity, index, now);
|
|
6857
|
+
}
|
|
6858
|
+
taskComplete(index, now) {
|
|
6859
|
+
return isTaskComplete(this.entity, index, now);
|
|
6860
|
+
}
|
|
6861
|
+
taskInProgress(index, now) {
|
|
6862
|
+
return isTaskInProgress(this.entity, index, now);
|
|
6863
|
+
}
|
|
6864
|
+
currentTaskProgress(now) {
|
|
6865
|
+
return currentTaskProgress(this.entity, now);
|
|
6866
|
+
}
|
|
6867
|
+
progress(now) {
|
|
6868
|
+
return scheduleProgress(this.entity, now);
|
|
6869
|
+
}
|
|
6870
|
+
}
|
|
6871
|
+
function createScheduleAccessor(entity) {
|
|
6872
|
+
return new ScheduleAccessor(entity);
|
|
6873
|
+
}
|
|
6874
|
+
|
|
6875
|
+
class EntityInventory extends Types.cargo_item {
|
|
6876
|
+
get item() {
|
|
6877
|
+
if (!this._item) {
|
|
6878
|
+
this._item = getItem(this.item_id);
|
|
6879
|
+
}
|
|
6880
|
+
return this._item;
|
|
6881
|
+
}
|
|
6882
|
+
get good() {
|
|
6883
|
+
return this.item;
|
|
6884
|
+
}
|
|
6885
|
+
get name() {
|
|
6886
|
+
return this.item.name;
|
|
6887
|
+
}
|
|
6888
|
+
get unitMass() {
|
|
6889
|
+
return this.item.mass;
|
|
6890
|
+
}
|
|
6891
|
+
get totalMass() {
|
|
6892
|
+
return UInt64.from(this.unitMass).multiplying(this.quantity);
|
|
6893
|
+
}
|
|
6894
|
+
get hasCargo() {
|
|
6895
|
+
return UInt32.from(this.quantity).gt(UInt32.from(0));
|
|
6896
|
+
}
|
|
6897
|
+
get isEmpty() {
|
|
6898
|
+
return UInt32.from(this.quantity).equals(UInt32.from(0));
|
|
6899
|
+
}
|
|
6900
|
+
}
|
|
6901
|
+
|
|
6902
|
+
class InventoryAccessor {
|
|
6903
|
+
constructor(entity) {
|
|
6904
|
+
this.entity = entity;
|
|
6905
|
+
}
|
|
6906
|
+
get items() {
|
|
6907
|
+
if (!this._items) {
|
|
6908
|
+
this._items = this.entity.cargo.map((item) => new EntityInventory(item));
|
|
6909
|
+
}
|
|
6910
|
+
return this._items;
|
|
6911
|
+
}
|
|
6912
|
+
get totalMass() {
|
|
6913
|
+
return this.items.reduce((sum, c) => sum.adding(c.totalMass), UInt64.from(0));
|
|
6914
|
+
}
|
|
6915
|
+
forItem(goodId) {
|
|
6916
|
+
return this.items.find((c) => c.item_id.equals(goodId));
|
|
6917
|
+
}
|
|
6918
|
+
get sellable() {
|
|
6919
|
+
return this.items.filter((c) => c.hasCargo);
|
|
6920
|
+
}
|
|
6921
|
+
get hasSellable() {
|
|
6922
|
+
return this.items.some((c) => c.hasCargo);
|
|
6923
|
+
}
|
|
6924
|
+
get sellableCount() {
|
|
6925
|
+
return this.items.filter((c) => c.hasCargo).length;
|
|
6926
|
+
}
|
|
6927
|
+
}
|
|
6928
|
+
function createInventoryAccessor(entity) {
|
|
6929
|
+
return new InventoryAccessor(entity);
|
|
6930
|
+
}
|
|
6931
|
+
|
|
6932
|
+
function maxTravelDistance(entity) {
|
|
6933
|
+
return UInt32.from(entity.generator.capacity)
|
|
6934
|
+
.dividing(entity.engines.drain)
|
|
6935
|
+
.multiplying(PRECISION$1);
|
|
6936
|
+
}
|
|
6937
|
+
function calcEnergyUsage(entity, distance) {
|
|
6938
|
+
return distance.dividing(PRECISION$1).multiplying(entity.engines.drain);
|
|
6939
|
+
}
|
|
6940
|
+
function hasEnergyForDistance(entity, distance) {
|
|
6941
|
+
const usage = calcEnergyUsage(entity, distance);
|
|
6942
|
+
return UInt64.from(entity.energy).gte(usage);
|
|
6943
|
+
}
|
|
6944
|
+
function energyPercent(entity) {
|
|
6945
|
+
return (Number(entity.energy) / Number(entity.generator.capacity)) * 100;
|
|
6946
|
+
}
|
|
6947
|
+
function needsRecharge(entity) {
|
|
6948
|
+
return UInt64.from(entity.energy).lt(entity.generator.capacity);
|
|
6949
|
+
}
|
|
6950
|
+
|
|
6951
|
+
class Ship extends Types.entity_info {
|
|
6952
|
+
get name() {
|
|
6953
|
+
return this.entity_name;
|
|
6954
|
+
}
|
|
6955
|
+
get inv() {
|
|
6956
|
+
return (this._inv ?? (this._inv = new InventoryAccessor(this)));
|
|
6957
|
+
}
|
|
6958
|
+
get inventory() {
|
|
6959
|
+
return this.inv.items;
|
|
6960
|
+
}
|
|
6961
|
+
get sched() {
|
|
6962
|
+
return (this._sched ?? (this._sched = new ScheduleAccessor(this)));
|
|
6963
|
+
}
|
|
6964
|
+
get maxDistance() {
|
|
6965
|
+
if (!this.generator || !this.engines)
|
|
6966
|
+
return UInt32.from(0);
|
|
6967
|
+
return maxTravelDistance(this);
|
|
6968
|
+
}
|
|
6969
|
+
get isIdle() {
|
|
6970
|
+
return this.is_idle;
|
|
6971
|
+
}
|
|
6972
|
+
getFlightOrigin(flightTaskIndex) {
|
|
6973
|
+
return Coordinates.from(getFlightOrigin(this, flightTaskIndex));
|
|
6974
|
+
}
|
|
6975
|
+
destinationLocation() {
|
|
6976
|
+
const dest = getDestinationLocation(this);
|
|
6977
|
+
return dest ? Coordinates.from(dest) : undefined;
|
|
6978
|
+
}
|
|
6979
|
+
positionAt(now) {
|
|
6980
|
+
const taskIndex = this.sched.currentTaskIndex(now);
|
|
6981
|
+
const progress = this.sched.currentTaskProgress(now);
|
|
6982
|
+
return Coordinates.from(getPositionAt(this, taskIndex, progress));
|
|
6983
|
+
}
|
|
6984
|
+
isInFlight(now) {
|
|
6985
|
+
return isInFlight(this, now);
|
|
6986
|
+
}
|
|
6987
|
+
isRecharging(now) {
|
|
6988
|
+
return isRecharging(this, now);
|
|
6989
|
+
}
|
|
6990
|
+
isLoading(now) {
|
|
6991
|
+
return isLoading(this, now);
|
|
6992
|
+
}
|
|
6993
|
+
isUnloading(now) {
|
|
6994
|
+
return isUnloading(this, now);
|
|
6995
|
+
}
|
|
6996
|
+
isGathering(now) {
|
|
6997
|
+
return isGathering(this, now);
|
|
6998
|
+
}
|
|
6999
|
+
get hasEngines() {
|
|
7000
|
+
return this.engines !== undefined;
|
|
7001
|
+
}
|
|
7002
|
+
get hasGenerator() {
|
|
7003
|
+
return this.generator !== undefined;
|
|
7004
|
+
}
|
|
7005
|
+
get hasGatherer() {
|
|
7006
|
+
return this.gatherer !== undefined;
|
|
7007
|
+
}
|
|
7008
|
+
get hasWarp() {
|
|
7009
|
+
return this.warp !== undefined;
|
|
7010
|
+
}
|
|
7011
|
+
project() {
|
|
7012
|
+
return projectEntity(this);
|
|
7013
|
+
}
|
|
7014
|
+
projectAt(now) {
|
|
7015
|
+
return projectEntityAt(this, now);
|
|
7016
|
+
}
|
|
7017
|
+
get location() {
|
|
7018
|
+
return Location.from(this.coordinates);
|
|
7019
|
+
}
|
|
7020
|
+
get totalCargoMass() {
|
|
7021
|
+
return this.inv.totalMass;
|
|
7022
|
+
}
|
|
7023
|
+
get totalMass() {
|
|
7024
|
+
let mass = UInt64.from(this.hullmass ?? 0).adding(this.totalCargoMass);
|
|
7025
|
+
if (this.loaders) {
|
|
7026
|
+
mass = mass.adding(UInt64.from(this.loaders.mass).multiplying(this.loaders.quantity));
|
|
7027
|
+
}
|
|
7028
|
+
return mass;
|
|
7029
|
+
}
|
|
7030
|
+
get maxCapacity() {
|
|
7031
|
+
return UInt64.from(this.capacity);
|
|
7032
|
+
}
|
|
7033
|
+
hasSpace(goodMass, quantity) {
|
|
7034
|
+
return this.totalMass.adding(goodMass.multiplying(quantity)).lte(this.maxCapacity);
|
|
7035
|
+
}
|
|
7036
|
+
get availableCapacity() {
|
|
7037
|
+
return this.totalMass.gte(this.maxCapacity)
|
|
7038
|
+
? UInt64.from(0)
|
|
7039
|
+
: this.maxCapacity.subtracting(this.totalMass);
|
|
7040
|
+
}
|
|
7041
|
+
getCargoForItem(goodId) {
|
|
7042
|
+
return this.inv.forItem(goodId);
|
|
7043
|
+
}
|
|
7044
|
+
get sellableCargo() {
|
|
7045
|
+
return this.inv.sellable;
|
|
7046
|
+
}
|
|
7047
|
+
get hasSellableCargo() {
|
|
7048
|
+
return this.inv.hasSellable;
|
|
7049
|
+
}
|
|
7050
|
+
get sellableGoodsCount() {
|
|
7051
|
+
return this.inv.sellableCount;
|
|
7052
|
+
}
|
|
7053
|
+
get isFull() {
|
|
7054
|
+
return this.totalMass.gte(this.maxCapacity);
|
|
7055
|
+
}
|
|
7056
|
+
get energyPercent() {
|
|
7057
|
+
if (!this.generator || this.energy === undefined)
|
|
7058
|
+
return 0;
|
|
7059
|
+
return energyPercent(this);
|
|
7060
|
+
}
|
|
7061
|
+
get needsRecharge() {
|
|
7062
|
+
if (!this.generator || this.energy === undefined)
|
|
7063
|
+
return false;
|
|
7064
|
+
return needsRecharge(this);
|
|
7065
|
+
}
|
|
7066
|
+
hasEnergyFor(distance) {
|
|
7067
|
+
if (!this.engines || !this.generator || this.energy === undefined)
|
|
7068
|
+
return false;
|
|
7069
|
+
return hasEnergyForDistance(this, distance);
|
|
7070
|
+
}
|
|
7071
|
+
}
|
|
7072
|
+
|
|
7073
|
+
class Warehouse extends Types.entity_info {
|
|
7074
|
+
get name() {
|
|
7075
|
+
return this.entity_name;
|
|
7076
|
+
}
|
|
7077
|
+
get inv() {
|
|
7078
|
+
return (this._inv ?? (this._inv = new InventoryAccessor(this)));
|
|
7079
|
+
}
|
|
7080
|
+
get inventory() {
|
|
7081
|
+
return this.inv.items;
|
|
7082
|
+
}
|
|
7083
|
+
get sched() {
|
|
7084
|
+
return (this._sched ?? (this._sched = new ScheduleAccessor(this)));
|
|
7085
|
+
}
|
|
7086
|
+
get isIdle() {
|
|
7087
|
+
return this.is_idle;
|
|
7088
|
+
}
|
|
7089
|
+
isLoading(now) {
|
|
7090
|
+
return isLoading(this, now);
|
|
7091
|
+
}
|
|
7092
|
+
isUnloading(now) {
|
|
7093
|
+
return isUnloading(this, now);
|
|
7094
|
+
}
|
|
7095
|
+
get location() {
|
|
7096
|
+
return Location.from(this.coordinates);
|
|
7097
|
+
}
|
|
7098
|
+
get totalCargoMass() {
|
|
7099
|
+
return this.inv.totalMass;
|
|
7100
|
+
}
|
|
7101
|
+
get maxCapacity() {
|
|
7102
|
+
return UInt64.from(this.capacity);
|
|
7103
|
+
}
|
|
7104
|
+
get availableCapacity() {
|
|
7105
|
+
const cargo = this.totalCargoMass;
|
|
7106
|
+
return cargo.gte(this.maxCapacity) ? UInt64.from(0) : this.maxCapacity.subtracting(cargo);
|
|
7107
|
+
}
|
|
7108
|
+
hasSpace(goodMass, quantity) {
|
|
7109
|
+
return this.totalCargoMass.adding(goodMass.multiplying(quantity)).lte(this.maxCapacity);
|
|
7110
|
+
}
|
|
7111
|
+
get isFull() {
|
|
7112
|
+
return this.totalCargoMass.gte(this.maxCapacity);
|
|
7113
|
+
}
|
|
7114
|
+
getCargoForItem(goodId) {
|
|
7115
|
+
return this.inv.forItem(goodId);
|
|
7116
|
+
}
|
|
7117
|
+
get orbitalAltitude() {
|
|
7118
|
+
return this.coordinates.z?.toNumber() || 0;
|
|
7119
|
+
}
|
|
7120
|
+
get totalMass() {
|
|
7121
|
+
const hull = this.hullmass ? UInt64.from(this.hullmass) : UInt64.from(0);
|
|
7122
|
+
return hull.adding(this.totalCargoMass);
|
|
7123
|
+
}
|
|
7246
7124
|
}
|
|
7247
|
-
|
|
7248
|
-
|
|
7125
|
+
|
|
7126
|
+
class Container extends Types.entity_info {
|
|
7127
|
+
get name() {
|
|
7128
|
+
return this.entity_name;
|
|
7129
|
+
}
|
|
7130
|
+
get sched() {
|
|
7131
|
+
return (this._sched ?? (this._sched = new ScheduleAccessor(this)));
|
|
7132
|
+
}
|
|
7133
|
+
get isIdle() {
|
|
7134
|
+
return this.is_idle;
|
|
7135
|
+
}
|
|
7136
|
+
isLoading(now) {
|
|
7137
|
+
return isLoading(this, now);
|
|
7138
|
+
}
|
|
7139
|
+
isUnloading(now) {
|
|
7140
|
+
return isUnloading(this, now);
|
|
7141
|
+
}
|
|
7142
|
+
get location() {
|
|
7143
|
+
return Location.from(this.coordinates);
|
|
7144
|
+
}
|
|
7145
|
+
get totalMass() {
|
|
7146
|
+
return UInt64.from(this.hullmass ?? 0).adding(this.cargomass);
|
|
7147
|
+
}
|
|
7148
|
+
get maxCapacity() {
|
|
7149
|
+
return UInt64.from(this.capacity);
|
|
7150
|
+
}
|
|
7151
|
+
get availableCapacity() {
|
|
7152
|
+
const cargo = UInt64.from(this.cargomass);
|
|
7153
|
+
return cargo.gte(this.maxCapacity) ? UInt64.from(0) : this.maxCapacity.subtracting(cargo);
|
|
7154
|
+
}
|
|
7155
|
+
hasSpace(additionalMass) {
|
|
7156
|
+
return UInt64.from(this.cargomass).adding(additionalMass).lte(this.maxCapacity);
|
|
7157
|
+
}
|
|
7158
|
+
get isFull() {
|
|
7159
|
+
return UInt64.from(this.cargomass).gte(this.maxCapacity);
|
|
7160
|
+
}
|
|
7161
|
+
get orbitalAltitude() {
|
|
7162
|
+
return this.coordinates.z?.toNumber() || 0;
|
|
7163
|
+
}
|
|
7249
7164
|
}
|
|
7250
|
-
function
|
|
7251
|
-
|
|
7165
|
+
function computeContainerCapabilities(stats) {
|
|
7166
|
+
const density = stats['density'] ?? 500;
|
|
7167
|
+
const strength = stats['strength'] ?? 500;
|
|
7168
|
+
const ductility = stats['ductility'] ?? 500;
|
|
7169
|
+
const purity = stats['purity'] ?? 500;
|
|
7170
|
+
const hullmass = 25000 + 75 * density;
|
|
7171
|
+
const statSum = strength + ductility + purity;
|
|
7172
|
+
const exponent = statSum / 2997;
|
|
7173
|
+
const capacity = Math.floor(1000000 * Math.pow(10, exponent));
|
|
7174
|
+
return { hullmass, capacity };
|
|
7252
7175
|
}
|
|
7253
|
-
function
|
|
7254
|
-
|
|
7176
|
+
function computeContainerT2Capabilities(stats) {
|
|
7177
|
+
const strength = stats['strength'] ?? 0;
|
|
7178
|
+
const density = stats['density'] ?? 0;
|
|
7179
|
+
const ductility = stats['ductility'] ?? 0;
|
|
7180
|
+
const purity = stats['purity'] ?? 0;
|
|
7181
|
+
const hullmass = 20000 + 50 * density;
|
|
7182
|
+
const statSum = strength + ductility + purity;
|
|
7183
|
+
const exponent = statSum / 2500;
|
|
7184
|
+
const capacity = Math.floor(1500000 * Math.pow(10, exponent));
|
|
7185
|
+
return { hullmass, capacity };
|
|
7255
7186
|
}
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
|
|
7187
|
+
|
|
7188
|
+
class EntitiesManager extends BaseManager {
|
|
7189
|
+
async getEntity(type, id) {
|
|
7190
|
+
const result = await this.server.readonly('getentity', {
|
|
7191
|
+
entity_type: Name.from(type),
|
|
7192
|
+
entity_id: id,
|
|
7193
|
+
});
|
|
7194
|
+
const entityInfo = result;
|
|
7195
|
+
return this.wrapEntity(entityInfo);
|
|
7196
|
+
}
|
|
7197
|
+
async getEntities(owner, type) {
|
|
7198
|
+
const ownerName = this.resolveOwner(owner);
|
|
7199
|
+
const result = await this.server.readonly('getentities', {
|
|
7200
|
+
owner: ownerName,
|
|
7201
|
+
entity_type: type ? Name.from(type) : null,
|
|
7202
|
+
});
|
|
7203
|
+
const entities = result;
|
|
7204
|
+
return entities.map((entity) => this.wrapEntity(entity));
|
|
7205
|
+
}
|
|
7206
|
+
async getSummaries(owner, type) {
|
|
7207
|
+
const ownerName = this.resolveOwner(owner);
|
|
7208
|
+
const result = await this.server.readonly('getsummaries', {
|
|
7209
|
+
owner: ownerName,
|
|
7210
|
+
entity_type: type ? Name.from(type) : null,
|
|
7211
|
+
});
|
|
7212
|
+
return result;
|
|
7213
|
+
}
|
|
7214
|
+
async getShip(id) {
|
|
7215
|
+
return (await this.getEntity('ship', id));
|
|
7216
|
+
}
|
|
7217
|
+
async getWarehouse(id) {
|
|
7218
|
+
return (await this.getEntity('warehouse', id));
|
|
7219
|
+
}
|
|
7220
|
+
async getContainer(id) {
|
|
7221
|
+
return (await this.getEntity('container', id));
|
|
7222
|
+
}
|
|
7223
|
+
async getShips(owner) {
|
|
7224
|
+
return (await this.getEntities(owner, 'ship'));
|
|
7225
|
+
}
|
|
7226
|
+
async getWarehouses(owner) {
|
|
7227
|
+
return (await this.getEntities(owner, 'warehouse'));
|
|
7228
|
+
}
|
|
7229
|
+
async getContainers(owner) {
|
|
7230
|
+
return (await this.getEntities(owner, 'container'));
|
|
7231
|
+
}
|
|
7232
|
+
async getShipSummaries(owner) {
|
|
7233
|
+
return this.getSummaries(owner, 'ship');
|
|
7234
|
+
}
|
|
7235
|
+
async getWarehouseSummaries(owner) {
|
|
7236
|
+
return this.getSummaries(owner, 'warehouse');
|
|
7237
|
+
}
|
|
7238
|
+
async getContainerSummaries(owner) {
|
|
7239
|
+
return this.getSummaries(owner, 'container');
|
|
7240
|
+
}
|
|
7241
|
+
wrapEntity(entity) {
|
|
7242
|
+
if (entity.type.equals('ship')) {
|
|
7243
|
+
return new Ship(entity);
|
|
7244
|
+
}
|
|
7245
|
+
else if (entity.type.equals('warehouse')) {
|
|
7246
|
+
return new Warehouse(entity);
|
|
7247
|
+
}
|
|
7248
|
+
else {
|
|
7249
|
+
return new Container(entity);
|
|
7250
|
+
}
|
|
7251
|
+
}
|
|
7252
|
+
resolveOwner(owner) {
|
|
7253
|
+
if (typeof owner === 'object' && owner !== null && 'owner' in owner) {
|
|
7254
|
+
return owner.owner;
|
|
7255
|
+
}
|
|
7256
|
+
return Name.from(owner);
|
|
7257
|
+
}
|
|
7258
|
+
}
|
|
7259
|
+
|
|
7260
|
+
class Player extends Types.player_row {
|
|
7261
|
+
static fromState(state) {
|
|
7262
|
+
const playerRow = Types.player_row.from({
|
|
7263
|
+
owner: Name.from(state.owner),
|
|
7264
|
+
});
|
|
7265
|
+
return new Player(playerRow);
|
|
7266
|
+
}
|
|
7267
|
+
}
|
|
7268
|
+
|
|
7269
|
+
class PlayersManager extends BaseManager {
|
|
7270
|
+
async getPlayer(account) {
|
|
7271
|
+
const playerRow = await this.server.table('player').get(Name.from(account));
|
|
7272
|
+
if (!playerRow) {
|
|
7273
|
+
return undefined;
|
|
7274
|
+
}
|
|
7275
|
+
return new Player(playerRow);
|
|
7276
|
+
}
|
|
7277
|
+
}
|
|
7278
|
+
|
|
7279
|
+
class LocationsManager extends BaseManager {
|
|
7280
|
+
async hasSystem(location) {
|
|
7281
|
+
const game = await this.getGame();
|
|
7282
|
+
return hasSystem(game.config.seed, location);
|
|
7283
|
+
}
|
|
7284
|
+
async findNearbyPlanets(origin, maxDistance = 20) {
|
|
7285
|
+
const game = await this.getGame();
|
|
7286
|
+
return findNearbyPlanets(game.config.seed, origin, maxDistance);
|
|
7287
|
+
}
|
|
7288
|
+
async getLocationEntity(id) {
|
|
7289
|
+
const row = await this.server.table('location').get(UInt64.from(id));
|
|
7290
|
+
return row ?? undefined;
|
|
7291
|
+
}
|
|
7292
|
+
async getLocationEntityAt(coords) {
|
|
7293
|
+
const id = coordsToLocationId(coords);
|
|
7294
|
+
return this.getLocationEntity(id);
|
|
7295
|
+
}
|
|
7296
|
+
async getAllLocationEntities() {
|
|
7297
|
+
return this.server.table('location').all();
|
|
7298
|
+
}
|
|
7299
|
+
}
|
|
7300
|
+
|
|
7301
|
+
class EpochsManager extends BaseManager {
|
|
7302
|
+
async getCurrentHeight() {
|
|
7303
|
+
const game = await this.getGame();
|
|
7304
|
+
return getCurrentEpoch(game);
|
|
7305
|
+
}
|
|
7306
|
+
async getCurrent() {
|
|
7307
|
+
const game = await this.getGame();
|
|
7308
|
+
const epoch = await this.getCurrentHeight();
|
|
7309
|
+
return getEpochInfo(game, epoch);
|
|
7310
|
+
}
|
|
7311
|
+
async getByHeight(height) {
|
|
7312
|
+
const game = await this.getGame();
|
|
7313
|
+
return getEpochInfo(game, UInt64.from(height));
|
|
7314
|
+
}
|
|
7315
|
+
async getTimeRemaining() {
|
|
7316
|
+
const epochInfo = await this.getCurrent();
|
|
7317
|
+
const now = Date.now();
|
|
7318
|
+
const endTime = epochInfo.end.getTime();
|
|
7319
|
+
return Math.max(0, endTime - now);
|
|
7320
|
+
}
|
|
7321
|
+
async getProgress() {
|
|
7322
|
+
const epochInfo = await this.getCurrent();
|
|
7323
|
+
const now = Date.now();
|
|
7324
|
+
const startTime = epochInfo.start.getTime();
|
|
7325
|
+
const endTime = epochInfo.end.getTime();
|
|
7326
|
+
const duration = endTime - startTime;
|
|
7327
|
+
const elapsed = now - startTime;
|
|
7328
|
+
if (elapsed <= 0)
|
|
7329
|
+
return 0;
|
|
7330
|
+
if (elapsed >= duration)
|
|
7331
|
+
return 1;
|
|
7332
|
+
return elapsed / duration;
|
|
7333
|
+
}
|
|
7334
|
+
async fitsInCurrentEpoch(durationMs) {
|
|
7335
|
+
const remaining = await this.getTimeRemaining();
|
|
7336
|
+
return durationMs <= remaining;
|
|
7337
|
+
}
|
|
7259
7338
|
}
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7339
|
+
|
|
7340
|
+
class ActionsManager extends BaseManager {
|
|
7341
|
+
travel(shipId, destination, recharge = true) {
|
|
7342
|
+
const x = Int64.from(destination.x);
|
|
7343
|
+
const y = Int64.from(destination.y);
|
|
7344
|
+
return this.server.action('travel', {
|
|
7345
|
+
entity_type: EntityType.SHIP,
|
|
7346
|
+
id: UInt64.from(shipId),
|
|
7347
|
+
x,
|
|
7348
|
+
y,
|
|
7349
|
+
recharge,
|
|
7269
7350
|
});
|
|
7270
7351
|
}
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7352
|
+
grouptravel(entities, destination, recharge = true) {
|
|
7353
|
+
const entityRefs = entities.map((e) => Types.entity_ref.from({
|
|
7354
|
+
entity_type: e.entityType,
|
|
7355
|
+
entity_id: UInt64.from(e.entityId),
|
|
7356
|
+
}));
|
|
7357
|
+
const x = Int64.from(destination.x);
|
|
7358
|
+
const y = Int64.from(destination.y);
|
|
7359
|
+
return this.server.action('grouptravel', {
|
|
7360
|
+
entities: entityRefs,
|
|
7361
|
+
x,
|
|
7362
|
+
y,
|
|
7363
|
+
recharge,
|
|
7278
7364
|
});
|
|
7279
7365
|
}
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
id:
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7366
|
+
resolve(entityId, entityType = EntityType.SHIP) {
|
|
7367
|
+
return this.server.action('resolve', {
|
|
7368
|
+
entity_type: entityType,
|
|
7369
|
+
id: UInt64.from(entityId),
|
|
7370
|
+
});
|
|
7371
|
+
}
|
|
7372
|
+
cancel(entityId, count, entityType = EntityType.SHIP) {
|
|
7373
|
+
return this.server.action('cancel', {
|
|
7374
|
+
entity_type: entityType,
|
|
7375
|
+
id: UInt64.from(entityId),
|
|
7376
|
+
count: UInt64.from(count),
|
|
7377
|
+
});
|
|
7378
|
+
}
|
|
7379
|
+
recharge(shipId) {
|
|
7380
|
+
return this.server.action('recharge', {
|
|
7381
|
+
entity_type: EntityType.SHIP,
|
|
7382
|
+
id: UInt64.from(shipId),
|
|
7383
|
+
});
|
|
7384
|
+
}
|
|
7385
|
+
transfer(sourceType, sourceId, destType, destId, goodId, quantity) {
|
|
7386
|
+
return this.server.action('transfer', {
|
|
7387
|
+
source_type: sourceType,
|
|
7388
|
+
source_id: UInt64.from(sourceId),
|
|
7389
|
+
dest_type: destType,
|
|
7390
|
+
dest_id: UInt64.from(destId),
|
|
7391
|
+
item_id: UInt16.from(goodId),
|
|
7392
|
+
quantity: UInt32.from(quantity),
|
|
7393
|
+
});
|
|
7394
|
+
}
|
|
7395
|
+
foundCompany(account, name) {
|
|
7396
|
+
return this.platform.action('foundcompany', {
|
|
7397
|
+
account: Name.from(account),
|
|
7398
|
+
name,
|
|
7399
|
+
});
|
|
7400
|
+
}
|
|
7401
|
+
join(account) {
|
|
7402
|
+
return this.server.action('join', {
|
|
7403
|
+
account: Name.from(account),
|
|
7404
|
+
});
|
|
7405
|
+
}
|
|
7406
|
+
gather(shipId, stratum, quantity) {
|
|
7407
|
+
return this.server.action('gather', {
|
|
7408
|
+
entity_type: EntityType.SHIP,
|
|
7409
|
+
id: UInt64.from(shipId),
|
|
7410
|
+
stratum: UInt16.from(stratum),
|
|
7411
|
+
quantity: UInt32.from(quantity),
|
|
7412
|
+
});
|
|
7413
|
+
}
|
|
7414
|
+
warp(shipId, destination) {
|
|
7415
|
+
const x = Int64.from(destination.x);
|
|
7416
|
+
const y = Int64.from(destination.y);
|
|
7417
|
+
return this.server.action('warp', {
|
|
7418
|
+
entity_type: EntityType.SHIP,
|
|
7419
|
+
id: UInt64.from(shipId),
|
|
7420
|
+
x,
|
|
7421
|
+
y,
|
|
7422
|
+
});
|
|
7423
|
+
}
|
|
7424
|
+
craft(entityType, entityId, recipeId, quantity, inputs) {
|
|
7425
|
+
const cargoInputs = inputs.map((i) => Types.cargo_item.from(i));
|
|
7426
|
+
return this.server.action('craft', {
|
|
7427
|
+
entity_type: entityType,
|
|
7428
|
+
id: UInt64.from(entityId),
|
|
7429
|
+
recipe_id: UInt16.from(recipeId),
|
|
7430
|
+
quantity: UInt32.from(quantity),
|
|
7431
|
+
inputs: cargoInputs,
|
|
7432
|
+
});
|
|
7433
|
+
}
|
|
7434
|
+
blend(entityType, entityId, inputs) {
|
|
7435
|
+
const cargoInputs = inputs.map((i) => Types.cargo_item.from(i));
|
|
7436
|
+
return this.server.action('blend', {
|
|
7437
|
+
entity_type: entityType,
|
|
7438
|
+
id: UInt64.from(entityId),
|
|
7439
|
+
inputs: cargoInputs,
|
|
7440
|
+
});
|
|
7441
|
+
}
|
|
7442
|
+
deploy(entityType, entityId, packedItemId, seed, entityName) {
|
|
7443
|
+
return this.server.action('deploy', {
|
|
7444
|
+
entity_type: entityType,
|
|
7445
|
+
id: UInt64.from(entityId),
|
|
7446
|
+
packed_item_id: UInt16.from(packedItemId),
|
|
7447
|
+
seed: UInt64.from(seed),
|
|
7448
|
+
entity_name: entityName,
|
|
7449
|
+
});
|
|
7450
|
+
}
|
|
7451
|
+
addmodule(entityType, entityId, moduleIndex, moduleCargoId, targetCargoId = UInt64.from(0)) {
|
|
7452
|
+
return this.server.action('addmodule', {
|
|
7453
|
+
entity_type: entityType,
|
|
7454
|
+
entity_id: UInt64.from(entityId),
|
|
7455
|
+
module_index: moduleIndex,
|
|
7456
|
+
module_cargo_id: UInt64.from(moduleCargoId),
|
|
7457
|
+
target_cargo_id: UInt64.from(targetCargoId),
|
|
7458
|
+
});
|
|
7459
|
+
}
|
|
7460
|
+
rmmodule(entityType, entityId, moduleIndex, targetCargoId = UInt64.from(0)) {
|
|
7461
|
+
return this.server.action('rmmodule', {
|
|
7462
|
+
entity_type: entityType,
|
|
7463
|
+
entity_id: UInt64.from(entityId),
|
|
7464
|
+
module_index: moduleIndex,
|
|
7465
|
+
target_cargo_id: UInt64.from(targetCargoId),
|
|
7466
|
+
});
|
|
7467
|
+
}
|
|
7468
|
+
joinGame(account, companyName) {
|
|
7469
|
+
return [this.foundCompany(account, companyName), this.join(account)];
|
|
7470
|
+
}
|
|
7471
|
+
}
|
|
7472
|
+
|
|
7473
|
+
class GameContext {
|
|
7474
|
+
constructor(client, server, platform) {
|
|
7475
|
+
this.client = client;
|
|
7476
|
+
this.server = server;
|
|
7477
|
+
this.platform = platform;
|
|
7478
|
+
}
|
|
7479
|
+
get entities() {
|
|
7480
|
+
if (!this._entities) {
|
|
7481
|
+
this._entities = new EntitiesManager(this);
|
|
7482
|
+
}
|
|
7483
|
+
return this._entities;
|
|
7484
|
+
}
|
|
7485
|
+
get players() {
|
|
7486
|
+
if (!this._players) {
|
|
7487
|
+
this._players = new PlayersManager(this);
|
|
7488
|
+
}
|
|
7489
|
+
return this._players;
|
|
7490
|
+
}
|
|
7491
|
+
get locations() {
|
|
7492
|
+
if (!this._locations) {
|
|
7493
|
+
this._locations = new LocationsManager(this);
|
|
7494
|
+
}
|
|
7495
|
+
return this._locations;
|
|
7496
|
+
}
|
|
7497
|
+
get epochs() {
|
|
7498
|
+
if (!this._epochs) {
|
|
7499
|
+
this._epochs = new EpochsManager(this);
|
|
7500
|
+
}
|
|
7501
|
+
return this._epochs;
|
|
7502
|
+
}
|
|
7503
|
+
get actions() {
|
|
7504
|
+
if (!this._actions) {
|
|
7505
|
+
this._actions = new ActionsManager(this);
|
|
7506
|
+
}
|
|
7507
|
+
return this._actions;
|
|
7508
|
+
}
|
|
7509
|
+
async getGame(reload = false) {
|
|
7510
|
+
if (!reload && this._gameCache) {
|
|
7511
|
+
return this._gameCache;
|
|
7512
|
+
}
|
|
7513
|
+
const game = await this.platform.table('games').get();
|
|
7514
|
+
if (!game) {
|
|
7515
|
+
throw new Error('Game not initialized');
|
|
7516
|
+
}
|
|
7517
|
+
this._gameCache = game;
|
|
7518
|
+
return game;
|
|
7519
|
+
}
|
|
7520
|
+
async getState(reload = false) {
|
|
7521
|
+
if (!reload && this._stateCache) {
|
|
7522
|
+
return this._stateCache;
|
|
7523
|
+
}
|
|
7524
|
+
const state = await this.server.table('state').get();
|
|
7525
|
+
if (!state) {
|
|
7526
|
+
throw new Error('Game state not initialized');
|
|
7527
|
+
}
|
|
7528
|
+
const game = this._gameCache;
|
|
7529
|
+
this._stateCache = GameState.from(state, game);
|
|
7530
|
+
return this._stateCache;
|
|
7531
|
+
}
|
|
7532
|
+
get cachedGame() {
|
|
7533
|
+
return this._gameCache;
|
|
7534
|
+
}
|
|
7535
|
+
get cachedState() {
|
|
7536
|
+
return this._stateCache;
|
|
7537
|
+
}
|
|
7538
|
+
}
|
|
7539
|
+
|
|
7540
|
+
class Shipload {
|
|
7541
|
+
constructor(chain, constructorOptions) {
|
|
7542
|
+
const { client, platformContract, serverContract } = constructorOptions || {};
|
|
7543
|
+
const apiClient = client || new APIClient({ url: chain.url });
|
|
7544
|
+
const platform$1 = platformContract
|
|
7545
|
+
? platformContract
|
|
7546
|
+
: new Contract$1({ client: apiClient });
|
|
7547
|
+
const server$1 = serverContract
|
|
7548
|
+
? serverContract
|
|
7549
|
+
: new Contract({ client: apiClient });
|
|
7550
|
+
this._context = new GameContext(apiClient, server$1, platform$1);
|
|
7551
|
+
}
|
|
7552
|
+
static async load(chain, shiploadOptions) {
|
|
7553
|
+
let platform$1 = new Contract$1({
|
|
7554
|
+
client: new APIClient({ url: chain.url }),
|
|
7555
|
+
});
|
|
7556
|
+
if (shiploadOptions?.platformContractName) {
|
|
7557
|
+
const client = shiploadOptions.client || new APIClient({ url: chain.url });
|
|
7558
|
+
const contractKit = new ContractKit({ client });
|
|
7559
|
+
platform$1 = await contractKit.load(shiploadOptions.platformContractName);
|
|
7560
|
+
}
|
|
7561
|
+
let server$1 = new Contract({
|
|
7562
|
+
client: new APIClient({ url: chain.url }),
|
|
7563
|
+
});
|
|
7564
|
+
if (shiploadOptions?.serverContractName) {
|
|
7565
|
+
const client = shiploadOptions.client || new APIClient({ url: chain.url });
|
|
7566
|
+
const contractKit = new ContractKit({ client });
|
|
7567
|
+
server$1 = await contractKit.load(shiploadOptions.serverContractName);
|
|
7568
|
+
}
|
|
7569
|
+
return new Shipload(chain, {
|
|
7570
|
+
...shiploadOptions,
|
|
7571
|
+
platformContract: platform$1,
|
|
7572
|
+
serverContract: server$1,
|
|
7287
7573
|
});
|
|
7288
7574
|
}
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
function getComponentsForCategory(category) {
|
|
7292
|
-
return components.filter((c) => c.recipe.some((r) => r.category === category));
|
|
7293
|
-
}
|
|
7294
|
-
function getComponentsForStat(statKey) {
|
|
7295
|
-
return components.filter((c) => c.stats.some((s) => s.key === statKey));
|
|
7296
|
-
}
|
|
7297
|
-
|
|
7298
|
-
function encodeStats(values) {
|
|
7299
|
-
let seed = 0n;
|
|
7300
|
-
for (let i = 0; i < values.length && i < 6; i++) {
|
|
7301
|
-
seed |= BigInt(values[i] & 0x3ff) << BigInt(i * 10);
|
|
7302
|
-
}
|
|
7303
|
-
return seed;
|
|
7304
|
-
}
|
|
7305
|
-
function decodeStat(seed, index) {
|
|
7306
|
-
return Number((seed >> BigInt(index * 10)) & 0x3ffn);
|
|
7307
|
-
}
|
|
7308
|
-
function decodeStats(seed, count) {
|
|
7309
|
-
const stats = [];
|
|
7310
|
-
for (let i = 0; i < count; i++) {
|
|
7311
|
-
stats.push(decodeStat(seed, i));
|
|
7575
|
+
get client() {
|
|
7576
|
+
return this._context.client;
|
|
7312
7577
|
}
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
function mapStatsToKeys(seed, statDefs) {
|
|
7316
|
-
const values = decodeStats(seed, statDefs.length);
|
|
7317
|
-
const result = {};
|
|
7318
|
-
for (let i = 0; i < statDefs.length; i++) {
|
|
7319
|
-
result[statDefs[i].key] = values[i];
|
|
7578
|
+
get server() {
|
|
7579
|
+
return this._context.server;
|
|
7320
7580
|
}
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
function decodeCraftedItemStats(itemId, seed) {
|
|
7324
|
-
const comp = getComponentById(itemId);
|
|
7325
|
-
if (comp)
|
|
7326
|
-
return mapStatsToKeys(seed, comp.stats);
|
|
7327
|
-
const entityRecipe = entityRecipes.find((r) => r.packedItemId === itemId);
|
|
7328
|
-
if (entityRecipe)
|
|
7329
|
-
return mapStatsToKeys(seed, entityRecipe.stats);
|
|
7330
|
-
const moduleRecipe = moduleRecipes.find((r) => r.itemId === itemId);
|
|
7331
|
-
if (moduleRecipe)
|
|
7332
|
-
return mapStatsToKeys(seed, moduleRecipe.stats);
|
|
7333
|
-
return {};
|
|
7334
|
-
}
|
|
7335
|
-
function blendStacks(stacks, statKey) {
|
|
7336
|
-
let totalQty = 0;
|
|
7337
|
-
let weightedSum = 0;
|
|
7338
|
-
for (const stack of stacks) {
|
|
7339
|
-
const val = stack.stats[statKey] ?? 0;
|
|
7340
|
-
weightedSum += val * stack.quantity;
|
|
7341
|
-
totalQty += stack.quantity;
|
|
7581
|
+
get platform() {
|
|
7582
|
+
return this._context.platform;
|
|
7342
7583
|
}
|
|
7343
|
-
|
|
7344
|
-
return
|
|
7345
|
-
return Math.floor(weightedSum / totalQty);
|
|
7346
|
-
}
|
|
7347
|
-
function computeComponentStats(componentId, categoryStacks) {
|
|
7348
|
-
const comp = getComponentById(componentId);
|
|
7349
|
-
if (!comp)
|
|
7350
|
-
return [];
|
|
7351
|
-
return comp.stats.map((statDef) => {
|
|
7352
|
-
const matching = categoryStacks.find((cs) => cs.category === statDef.source);
|
|
7353
|
-
const value = matching ? blendStacks(matching.stacks, statDef.key) : 0;
|
|
7354
|
-
return { key: statDef.key, value: Math.max(1, Math.min(999, value)) };
|
|
7355
|
-
});
|
|
7356
|
-
}
|
|
7357
|
-
function blendComponentStacks(stacks) {
|
|
7358
|
-
if (stacks.length === 0)
|
|
7359
|
-
return {};
|
|
7360
|
-
const allKeys = new Set();
|
|
7361
|
-
for (const s of stacks) {
|
|
7362
|
-
for (const k of Object.keys(s.stats))
|
|
7363
|
-
allKeys.add(k);
|
|
7584
|
+
get entities() {
|
|
7585
|
+
return this._context.entities;
|
|
7364
7586
|
}
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
result[key] = blendStacks(stacks.map((s) => ({ quantity: s.quantity, stats: s.stats })), key);
|
|
7587
|
+
get players() {
|
|
7588
|
+
return this._context.players;
|
|
7368
7589
|
}
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
function computeEntityStats(entityRecipeId, componentStacks) {
|
|
7372
|
-
const recipe = getEntityRecipe(entityRecipeId) ?? getModuleRecipe(entityRecipeId);
|
|
7373
|
-
if (!recipe)
|
|
7374
|
-
return [];
|
|
7375
|
-
const blendedByComponent = {};
|
|
7376
|
-
for (const [compId, stacks] of Object.entries(componentStacks)) {
|
|
7377
|
-
blendedByComponent[Number(compId)] = blendComponentStacks(stacks);
|
|
7590
|
+
get locations() {
|
|
7591
|
+
return this._context.locations;
|
|
7378
7592
|
}
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
const value = blended[stat.sourceStatKey] ?? 0;
|
|
7382
|
-
return { key: stat.key, value: Math.max(1, Math.min(999, value)) };
|
|
7383
|
-
});
|
|
7384
|
-
}
|
|
7385
|
-
function decodeStackStats(itemId, seed) {
|
|
7386
|
-
if (itemId >= 10000) {
|
|
7387
|
-
return decodeCraftedItemStats(itemId, BigInt(seed.toString()));
|
|
7593
|
+
get epochs() {
|
|
7594
|
+
return this._context.epochs;
|
|
7388
7595
|
}
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
}
|
|
7392
|
-
const categoryItemMass = {
|
|
7393
|
-
metal: 30000,
|
|
7394
|
-
precious: 40000,
|
|
7395
|
-
gas: 15000,
|
|
7396
|
-
mineral: 22000,
|
|
7397
|
-
organic: 15000,
|
|
7398
|
-
};
|
|
7399
|
-
function computeInputMass(itemId, itemType) {
|
|
7400
|
-
if (itemType === 'component') {
|
|
7401
|
-
const comp = getComponentById(itemId);
|
|
7402
|
-
if (!comp)
|
|
7403
|
-
return 0;
|
|
7404
|
-
return comp.recipe.reduce((sum, input) => {
|
|
7405
|
-
const mass = input.category ? categoryItemMass[input.category] ?? 0 : 0;
|
|
7406
|
-
return sum + mass * input.quantity;
|
|
7407
|
-
}, 0);
|
|
7596
|
+
get actions() {
|
|
7597
|
+
return this._context.actions;
|
|
7408
7598
|
}
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
if (!mod)
|
|
7412
|
-
return 0;
|
|
7413
|
-
return mod.recipe.reduce((sum, input) => {
|
|
7414
|
-
const comp = input.itemId ? getComponentById(input.itemId) : undefined;
|
|
7415
|
-
return sum + (comp?.mass ?? 0) * input.quantity;
|
|
7416
|
-
}, 0);
|
|
7599
|
+
async getGame(reload = false) {
|
|
7600
|
+
return this._context.getGame(reload);
|
|
7417
7601
|
}
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
if (!ent)
|
|
7421
|
-
return 0;
|
|
7422
|
-
return ent.recipe.reduce((sum, input) => {
|
|
7423
|
-
const comp = input.itemId ? getComponentById(input.itemId) : undefined;
|
|
7424
|
-
return sum + (comp?.mass ?? 0) * input.quantity;
|
|
7425
|
-
}, 0);
|
|
7602
|
+
async getState(reload = false) {
|
|
7603
|
+
return this._context.getState(reload);
|
|
7426
7604
|
}
|
|
7427
|
-
return 0;
|
|
7428
7605
|
}
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7606
|
+
|
|
7607
|
+
function makeShip(state) {
|
|
7608
|
+
const info = {
|
|
7609
|
+
type: Name.from('ship'),
|
|
7610
|
+
id: UInt64.from(state.id),
|
|
7611
|
+
owner: Name.from(state.owner),
|
|
7612
|
+
entity_name: state.name,
|
|
7613
|
+
coordinates: Types.coordinates.from(state.coordinates),
|
|
7614
|
+
cargomass: UInt32.from(0),
|
|
7615
|
+
cargo: state.cargo || [],
|
|
7616
|
+
is_idle: !state.schedule,
|
|
7617
|
+
current_task_elapsed: UInt32.from(0),
|
|
7618
|
+
current_task_remaining: UInt32.from(0),
|
|
7619
|
+
pending_tasks: [],
|
|
7620
|
+
};
|
|
7621
|
+
if (state.hullmass !== undefined)
|
|
7622
|
+
info.hullmass = UInt32.from(state.hullmass);
|
|
7623
|
+
if (state.capacity !== undefined)
|
|
7624
|
+
info.capacity = UInt32.from(state.capacity);
|
|
7625
|
+
if (state.energy !== undefined)
|
|
7626
|
+
info.energy = UInt16.from(state.energy);
|
|
7627
|
+
if (state.engines)
|
|
7628
|
+
info.engines = state.engines;
|
|
7629
|
+
if (state.generator)
|
|
7630
|
+
info.generator = state.generator;
|
|
7631
|
+
if (state.loaders)
|
|
7632
|
+
info.loaders = state.loaders;
|
|
7633
|
+
if (state.schedule)
|
|
7634
|
+
info.schedule = state.schedule;
|
|
7635
|
+
const entityInfo = Types.entity_info.from(info);
|
|
7636
|
+
return new Ship(entityInfo);
|
|
7440
7637
|
}
|
|
7441
|
-
function
|
|
7442
|
-
const
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7638
|
+
function makeWarehouse(state) {
|
|
7639
|
+
const info = {
|
|
7640
|
+
type: Name.from('warehouse'),
|
|
7641
|
+
id: UInt64.from(state.id),
|
|
7642
|
+
owner: Name.from(state.owner),
|
|
7643
|
+
entity_name: state.name,
|
|
7644
|
+
coordinates: Types.coordinates.from(state.coordinates),
|
|
7645
|
+
capacity: UInt32.from(state.capacity),
|
|
7646
|
+
cargomass: UInt32.from(0),
|
|
7647
|
+
cargo: state.cargo || [],
|
|
7648
|
+
is_idle: !state.schedule,
|
|
7649
|
+
current_task_elapsed: UInt32.from(0),
|
|
7650
|
+
current_task_remaining: UInt32.from(0),
|
|
7651
|
+
pending_tasks: [],
|
|
7652
|
+
};
|
|
7653
|
+
if (state.hullmass !== undefined)
|
|
7654
|
+
info.hullmass = UInt32.from(state.hullmass);
|
|
7655
|
+
if (state.loaders)
|
|
7656
|
+
info.loaders = state.loaders;
|
|
7657
|
+
if (state.schedule)
|
|
7658
|
+
info.schedule = state.schedule;
|
|
7659
|
+
const entityInfo = Types.entity_info.from(info);
|
|
7660
|
+
return new Warehouse(entityInfo);
|
|
7661
|
+
}
|
|
7662
|
+
function makeContainer(state) {
|
|
7663
|
+
const entityInfo = Types.entity_info.from({
|
|
7664
|
+
type: Name.from('container'),
|
|
7665
|
+
id: UInt64.from(state.id),
|
|
7666
|
+
owner: Name.from(state.owner),
|
|
7667
|
+
entity_name: state.name,
|
|
7668
|
+
coordinates: Types.coordinates.from(state.coordinates),
|
|
7669
|
+
hullmass: UInt32.from(state.hullmass),
|
|
7670
|
+
capacity: UInt32.from(state.capacity),
|
|
7671
|
+
cargomass: UInt32.from(state.cargomass || 0),
|
|
7672
|
+
cargo: [],
|
|
7673
|
+
is_idle: !state.schedule,
|
|
7674
|
+
current_task_elapsed: UInt32.from(0),
|
|
7675
|
+
current_task_remaining: UInt32.from(0),
|
|
7676
|
+
pending_tasks: [],
|
|
7677
|
+
schedule: state.schedule,
|
|
7678
|
+
});
|
|
7679
|
+
return new Container(entityInfo);
|
|
7449
7680
|
}
|
|
7450
7681
|
|
|
7451
7682
|
function totalCargoMass(cargo) {
|
|
@@ -7686,7 +7917,7 @@ const categories = [
|
|
|
7686
7917
|
{
|
|
7687
7918
|
id: 'precious',
|
|
7688
7919
|
name: 'Precious Metals',
|
|
7689
|
-
label: 'Precious',
|
|
7920
|
+
label: 'Precious Metal',
|
|
7690
7921
|
description: 'Conductive, corrosion-resistant — electronics, energy systems, precision components',
|
|
7691
7922
|
color: categoryColors.precious,
|
|
7692
7923
|
},
|
|
@@ -8755,5 +8986,5 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
8755
8986
|
buildEntityDescription: buildEntityDescription
|
|
8756
8987
|
});
|
|
8757
8988
|
|
|
8758
|
-
export { ActionsManager, BASE_ORBITAL_MASS, COMMIT_ALREADY_SET, COMMIT_CANNOT_MATCH, COMMIT_NOT_SET, COMPANY_NOT_FOUND, CONTAINER_Z, CRAFT_ENERGY_DIVISOR, Container, Coordinates, DEPTH_THRESHOLD_T1, DEPTH_THRESHOLD_T2, DEPTH_THRESHOLD_T3, DEPTH_THRESHOLD_T4, DEPTH_THRESHOLD_T5, EPOCH_NON_ZERO, EPOCH_NOT_READY, ERROR_SYSTEM_ALREADY_INITIALIZED, ERROR_SYSTEM_DISABLED, ERROR_SYSTEM_NOT_INITIALIZED, EntitiesManager, EntityInventory, EntityType, EpochsManager, GAME_NOT_FOUND, GAME_SEED_NOT_SET, GameState, INITIAL_CONTAINER_CAPACITY, INITIAL_CONTAINER_HULLMASS, INITIAL_WAREHOUSE_CAPACITY, INSUFFICIENT_BALANCE, INSUFFICIENT_ITEM_QUANTITY, INSUFFICIENT_ITEM_SUPPLY, INVALID_AMOUNT, ITEM_CARGO_ARM, ITEM_CARGO_LINING, ITEM_CARGO_LINING_T2, ITEM_CONTAINER_T1_PACKED, ITEM_CONTAINER_T2_PACKED, ITEM_DOES_NOT_EXIST, ITEM_ENGINE_T1, ITEM_FOCUSING_ARRAY, ITEM_GATHERER_T1, ITEM_GENERATOR_T1, ITEM_HAULER_T1, ITEM_HULL_PLATES, ITEM_HULL_PLATES_T2, ITEM_LOADER_T1, ITEM_MANUFACTURING_T1, ITEM_MATTER_CONDUIT, ITEM_NOT_AVAILABLE_AT_LOCATION, ITEM_POWER_CELL, ITEM_REACTION_CHAMBER, ITEM_SHIP_T1_PACKED, ITEM_STORAGE_T1, ITEM_SURVEY_PROBE, ITEM_THRUSTER_CORE, ITEM_TOOL_BIT, ITEM_TYPE_COMPONENT, ITEM_TYPE_ENTITY, ITEM_TYPE_MODULE, ITEM_TYPE_RESOURCE, ITEM_WAREHOUSE_T1_PACKED, InventoryAccessor, Item, LOCATION_MAX_DEPTH, LOCATION_MIN_DEPTH, Location, LocationType, LocationsManager, MAX_ORBITAL_ALTITUDE, MIN_ORBITAL_ALTITUDE, MODULE_ANY, MODULE_CRAFTER, MODULE_ENGINE, MODULE_GATHERER, MODULE_GENERATOR, MODULE_HAULER, MODULE_LAUNCHER, MODULE_LOADER, MODULE_STORAGE, MODULE_WARP, index as NFT, NO_SCHEDULE, PLANET_SUBTYPE_GAS_GIANT, PLANET_SUBTYPE_ICY, PLANET_SUBTYPE_INDUSTRIAL, PLANET_SUBTYPE_OCEAN, PLANET_SUBTYPE_ROCKY, PLANET_SUBTYPE_TERRESTRIAL, PLAYER_ALREADY_JOINED, PLAYER_NOT_FOUND, PRECISION$1 as PRECISION, platform as PlatformContract, Player, PlayersManager, REQUIRES_MORE_THAN_ONE, REQUIRES_POSITIVE_VALUE, SHIP_ALREADY_THERE, SHIP_ALREADY_TRAVELING, SHIP_CANNOT_BUY_TRAVELING, SHIP_CANNOT_CANCEL_TASK, SHIP_CANNOT_UPDATE_TRAVELING, SHIP_CARGO_NOT_LOADED, SHIP_CARGO_NOT_OWNED, SHIP_INVALID_CARGO, SHIP_INVALID_DESTINATION, SHIP_INVALID_TRAVEL_DURATION, SHIP_NOT_ARRIVED, SHIP_NOT_ENOUGH_ENERGY, SHIP_NOT_ENOUGH_ENERGY_CAPACITY, SHIP_NOT_FOUND, SHIP_NOT_IDLE, SHIP_NOT_OWNED, SHIP_NO_COMPLETED_TASKS, SHIP_NO_TASKS_TO_CANCEL, ScheduleAccessor, server as ServerContract, Ship, Shipload, TRAVEL_MAX_DURATION, TaskCancelable, TaskType, WAREHOUSE_ALREADY_AT_LOCATION, WAREHOUSE_CAPACITY_EXCEEDED, WAREHOUSE_NOT_FOUND, WAREHOUSE_Z, Warehouse, availableCapacity$1 as availableCapacity, availableCapacityFromMass, blendCargoStacks, blendComponentStacks, blendCrossGroup, blendStacks, buildEntityDescription, calcCargoItemMass, calcCargoMass, calcEnergyUsage, calcLoadDuration, calc_acceleration, calc_craft_duration, calc_craft_energy, calc_energyusage, calc_flighttime, calc_gather_duration, calc_gather_energy, calc_loader_acceleration, calc_loader_flighttime, calc_orbital_altitude, calc_rechargetime, calc_ship_acceleration, calc_ship_flighttime, calc_ship_mass, calc_ship_rechargetime, calc_transfer_duration, calculateFlightTime, calculateLoadTimeBreakdown, calculateRefuelingTime, calculateTransferTime, canMove, capabilityAttributes, capabilityNames, capsHasCrafter, capsHasGatherer, capsHasLoaders, capsHasMass, capsHasMovement, capsHasStorage, cargoUtils, categoryColors, categoryIcons, categoryItemMass, componentIcon, components, computeBaseCapacityShip, computeBaseCapacityWarehouse, computeBaseHullmass, computeComponentStats, computeContainerCapabilities, computeContainerT2Capabilities, computeCrafterDrain, computeCrafterSpeed, computeEngineCapabilities, computeEngineDrain, computeEngineThrust, computeEntityStats, computeGathererCapabilities, computeGathererDepth, computeGathererDrain, computeGathererSpeed, computeGathererYield, computeGeneratorCap, computeGeneratorCapabilities, computeGeneratorRech, computeHaulPenalty, computeHaulerCapabilities, computeHaulerDrain, computeInputMass, computeLoaderCapabilities, computeLoaderMass, computeLoaderThrust, computeManufacturingCapabilities, computeShipCapabilities, computeShipHullCapabilities, computeStorageCapabilities, computeWarehouseHullCapabilities, coordsToLocationId, createInventoryAccessor, createProjectedEntity, createScheduleAccessor, decodeCraftedItemStats, decodeStat, decodeStats, Shipload as default,
|
|
8989
|
+
export { ActionsManager, BASE_ORBITAL_MASS, COMMIT_ALREADY_SET, COMMIT_CANNOT_MATCH, COMMIT_NOT_SET, COMPANY_NOT_FOUND, CONTAINER_Z, CRAFT_ENERGY_DIVISOR, Container, Coordinates, DEPTH_THRESHOLD_T1, DEPTH_THRESHOLD_T2, DEPTH_THRESHOLD_T3, DEPTH_THRESHOLD_T4, DEPTH_THRESHOLD_T5, ENTITY_CAPACITY_EXCEEDED, EPOCH_NON_ZERO, EPOCH_NOT_READY, ERROR_SYSTEM_ALREADY_INITIALIZED, ERROR_SYSTEM_DISABLED, ERROR_SYSTEM_NOT_INITIALIZED, EntitiesManager, EntityInventory, EntityType, EpochsManager, GAME_NOT_FOUND, GAME_SEED_NOT_SET, GameState, INITIAL_CONTAINER_CAPACITY, INITIAL_CONTAINER_HULLMASS, INITIAL_WAREHOUSE_CAPACITY, INSUFFICIENT_BALANCE, INSUFFICIENT_ITEM_QUANTITY, INSUFFICIENT_ITEM_SUPPLY, INVALID_AMOUNT, ITEM_CARGO_ARM, ITEM_CARGO_LINING, ITEM_CARGO_LINING_T2, ITEM_CONTAINER_T1_PACKED, ITEM_CONTAINER_T2_PACKED, ITEM_DOES_NOT_EXIST, ITEM_ENGINE_T1, ITEM_FOCUSING_ARRAY, ITEM_GATHERER_T1, ITEM_GENERATOR_T1, ITEM_HAULER_T1, ITEM_HULL_PLATES, ITEM_HULL_PLATES_T2, ITEM_LOADER_T1, ITEM_MANUFACTURING_T1, ITEM_MATTER_CONDUIT, ITEM_NOT_AVAILABLE_AT_LOCATION, ITEM_POWER_CELL, ITEM_REACTION_CHAMBER, ITEM_SHIP_T1_PACKED, ITEM_STORAGE_T1, ITEM_SURVEY_PROBE, ITEM_THRUSTER_CORE, ITEM_TOOL_BIT, ITEM_TYPE_COMPONENT, ITEM_TYPE_ENTITY, ITEM_TYPE_MODULE, ITEM_TYPE_RESOURCE, ITEM_WAREHOUSE_T1_PACKED, InventoryAccessor, Item, LOCATION_MAX_DEPTH, LOCATION_MIN_DEPTH, Location, LocationType, LocationsManager, MAX_ORBITAL_ALTITUDE, MIN_ORBITAL_ALTITUDE, MODULE_ANY, MODULE_CRAFTER, MODULE_ENGINE, MODULE_GATHERER, MODULE_GENERATOR, MODULE_HAULER, MODULE_LAUNCHER, MODULE_LOADER, MODULE_STORAGE, MODULE_WARP, index as NFT, NO_SCHEDULE, PLANET_SUBTYPE_GAS_GIANT, PLANET_SUBTYPE_ICY, PLANET_SUBTYPE_INDUSTRIAL, PLANET_SUBTYPE_OCEAN, PLANET_SUBTYPE_ROCKY, PLANET_SUBTYPE_TERRESTRIAL, PLAYER_ALREADY_JOINED, PLAYER_NOT_FOUND, PRECISION$1 as PRECISION, platform as PlatformContract, Player, PlayersManager, RECIPE_INPUTS_EXCESS, RECIPE_INPUTS_INSUFFICIENT, RECIPE_INPUTS_INVALID, RECIPE_INPUTS_MIXED, REQUIRES_MORE_THAN_ONE, REQUIRES_POSITIVE_VALUE, RESERVE_TIERS, SHIP_ALREADY_THERE, SHIP_ALREADY_TRAVELING, SHIP_CANNOT_BUY_TRAVELING, SHIP_CANNOT_CANCEL_TASK, SHIP_CANNOT_UPDATE_TRAVELING, SHIP_CARGO_NOT_LOADED, SHIP_CARGO_NOT_OWNED, SHIP_INVALID_CARGO, SHIP_INVALID_DESTINATION, SHIP_INVALID_TRAVEL_DURATION, SHIP_NOT_ARRIVED, SHIP_NOT_ENOUGH_ENERGY, SHIP_NOT_ENOUGH_ENERGY_CAPACITY, SHIP_NOT_FOUND, SHIP_NOT_IDLE, SHIP_NOT_OWNED, SHIP_NO_COMPLETED_TASKS, SHIP_NO_TASKS_TO_CANCEL, ScheduleAccessor, server as ServerContract, Ship, Shipload, TIER_ROLL_MAX, TRAVEL_MAX_DURATION, TaskCancelable, TaskType, WAREHOUSE_ALREADY_AT_LOCATION, WAREHOUSE_CAPACITY_EXCEEDED, WAREHOUSE_NOT_FOUND, WAREHOUSE_Z, Warehouse, availableCapacity$1 as availableCapacity, availableCapacityFromMass, blendCargoStacks, blendComponentStacks, blendCrossGroup, blendStacks, buildEntityDescription, calcCargoItemMass, calcCargoMass, calcEnergyUsage, calcLoadDuration, calcStacksMass, calc_acceleration, calc_craft_duration, calc_craft_energy, calc_energyusage, calc_flighttime, calc_gather_duration, calc_gather_energy, calc_loader_acceleration, calc_loader_flighttime, calc_orbital_altitude, calc_rechargetime, calc_ship_acceleration, calc_ship_flighttime, calc_ship_mass, calc_ship_rechargetime, calc_transfer_duration, calculateFlightTime, calculateLoadTimeBreakdown, calculateRefuelingTime, calculateTransferTime, canMove, capabilityAttributes, capabilityNames, capsHasCrafter, capsHasGatherer, capsHasLoaders, capsHasMass, capsHasMovement, capsHasStorage, cargoItemToStack, cargoUtils, categoryColors, categoryIcons, categoryItemMass, componentIcon, components, computeBaseCapacityShip, computeBaseCapacityWarehouse, computeBaseHullmass, computeComponentStats, computeContainerCapabilities, computeContainerT2Capabilities, computeCraftedOutputSeed, computeCrafterDrain, computeCrafterSpeed, computeEngineCapabilities, computeEngineDrain, computeEngineThrust, computeEntityStats, computeGathererCapabilities, computeGathererDepth, computeGathererDrain, computeGathererSpeed, computeGathererYield, computeGeneratorCap, computeGeneratorCapabilities, computeGeneratorRech, computeHaulPenalty, computeHaulerCapabilities, computeHaulerDrain, computeInputMass, computeLoaderCapabilities, computeLoaderMass, computeLoaderThrust, computeManufacturingCapabilities, computeShipCapabilities, computeShipHullCapabilities, computeStorageCapabilities, computeWarehouseHullCapabilities, coordsToLocationId, createInventoryAccessor, createProjectedEntity, createScheduleAccessor, decodeCraftedItemStats, decodeStat, decodeStats, Shipload as default, deriveLocation, deriveLocationEpoch, deriveLocationSize, deriveLocationStatic, deriveResourceStats, deriveStratum, deserializeAsset, deserializeComponent, deserializeEntity, deserializeModule, deserializeResource, distanceBetweenCoordinates, distanceBetweenPoints, encodeStats, energyPercent, entityDisplayName, entityRecipes, estimateDealTravelTime, estimateTravelTime, findNearbyPlanets, formatModuleLine, getAllCraftableItems, getCapabilityAttributes, getCategoryInfo, getComponentById, getComponentsForCategory, getComponentsForStat, getCurrentEpoch, getDepthThreshold, getDestinationLocation, getEligibleResources, getEntityRecipe, getEntityRecipeByItemId, getEntitySlotLayout, getEpochInfo, getFlightOrigin, getItem, getItems, getLocationCandidates, getLocationType, getLocationTypeName, getModuleCapabilityType, getModuleRecipe, getModuleRecipeByItemId, getPlanetSubtype, getPlanetSubtypes, getPositionAt, getResourceTier, getResourceWeight, getStatDefinitions, getStatMappings, getStatMappingsForCapability, getStatMappingsForStat, getStatName, getSystemName, hasEnergy, hasEnergyForDistance$1 as hasEnergyForDistance, hasGatherer, hasLoaders, hasMass, hasSchedule, hasSpace$1 as hasSpace, hasSpaceForMass, hasStorage, hasSystem, hash, hash512, isCraftedItem, isFull$1 as isFull, isFullFromMass, isGatherableLocation, isInvertedAttribute, isModuleItem, isRelatedItem, itemCategory, itemIcons, itemIds, itemOffset, itemTier, itemTypeCode, lerp, makeContainer, makeShip, makeWarehouse, maxTravelDistance, mergeStacks, moduleAccepts, moduleDisplayName, moduleIcon, moduleRecipes, needsRecharge, projectEntity, projectEntityAt, readCommonBase, removeFromStacks, resolveItem, resolveStats, rollTier, rollWithinTier, rotation, schedule, stackKey, stackToCargoItem, stacksEqual, statMappings, tierColors, toLocation, validateSchedule };
|
|
8759
8990
|
//# sourceMappingURL=shipload.m.js.map
|