@shipload/sdk 2.0.0-rc20 → 2.0.0-rc22
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 +193 -117
- package/lib/shipload.js +2992 -1945
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +2935 -1932
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/modules.ts +36 -7
- package/src/capabilities/storage.ts +1 -1
- package/src/contracts/server.ts +69 -1
- package/src/data/entities.json +50 -0
- package/src/data/item-ids.ts +75 -0
- package/src/data/items.json +250 -15
- package/src/data/metadata.ts +208 -0
- package/src/data/recipes-runtime.ts +65 -0
- package/src/data/recipes.json +878 -0
- package/src/derivation/crafting.ts +172 -111
- package/src/derivation/resources.ts +14 -38
- package/src/entities/container.ts +4 -4
- package/src/entities/entity-inventory.ts +2 -2
- package/src/entities/makers.ts +18 -10
- package/src/entities/ship-deploy.ts +8 -8
- package/src/entities/ship.ts +4 -4
- package/src/index-module.ts +10 -48
- package/src/market/items.ts +23 -75
- package/src/nft/description.ts +7 -7
- package/src/nft/deserializers.ts +6 -4
- package/src/resolution/display-name.ts +8 -4
- package/src/resolution/resolve-item.ts +80 -65
- package/src/scheduling/projection.ts +49 -29
- package/src/travel/travel.ts +8 -7
- package/src/types.ts +27 -33
- package/src/data/recipes.ts +0 -587
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Name, UInt16, UInt32, UInt64} from '@wharfkit/antelope'
|
|
1
|
+
import {Name, TimePoint, UInt16, UInt32, UInt64} from '@wharfkit/antelope'
|
|
2
2
|
import {ServerContract} from '../contracts'
|
|
3
3
|
import {Coordinates, PRECISION, TaskType} from '../types'
|
|
4
4
|
import {
|
|
@@ -13,16 +13,10 @@ import {
|
|
|
13
13
|
RECIPE_INPUTS_EXCESS,
|
|
14
14
|
RECIPE_INPUTS_INSUFFICIENT,
|
|
15
15
|
RECIPE_INPUTS_INVALID,
|
|
16
|
-
RECIPE_INPUTS_MIXED,
|
|
17
16
|
RECIPE_NOT_FOUND,
|
|
18
17
|
SHIP_CARGO_NOT_LOADED,
|
|
19
18
|
} from '../errors'
|
|
20
|
-
import {
|
|
21
|
-
getComponentById,
|
|
22
|
-
getEntityRecipeByItemId,
|
|
23
|
-
getModuleRecipeByItemId,
|
|
24
|
-
RecipeInput,
|
|
25
|
-
} from '../data/recipes'
|
|
19
|
+
import {getRecipe, RecipeInput} from '../data/recipes-runtime'
|
|
26
20
|
import {getItem} from '../market/items'
|
|
27
21
|
import {distanceBetweenCoordinates, lerp} from '../travel/travel'
|
|
28
22
|
import {
|
|
@@ -296,14 +290,41 @@ export function projectEntity(entity: Projectable, options?: ProjectionOptions):
|
|
|
296
290
|
return projected
|
|
297
291
|
}
|
|
298
292
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if (
|
|
306
|
-
|
|
293
|
+
export interface ProjectableSnapshot extends Projectable {
|
|
294
|
+
current_task?: ServerContract.Types.task
|
|
295
|
+
pending_tasks?: ServerContract.Types.task[]
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function buildRemainingProjectable(snapshot: ProjectableSnapshot): Projectable | null {
|
|
299
|
+
if (!snapshot.schedule) return null
|
|
300
|
+
const remainingTasks: ServerContract.Types.task[] = []
|
|
301
|
+
if (snapshot.current_task) remainingTasks.push(snapshot.current_task)
|
|
302
|
+
if (snapshot.pending_tasks?.length) remainingTasks.push(...snapshot.pending_tasks)
|
|
303
|
+
if (remainingTasks.length === 0) return null
|
|
304
|
+
|
|
305
|
+
const completedCount = snapshot.schedule.tasks.length - remainingTasks.length
|
|
306
|
+
let startedMs = snapshot.schedule.started.toMilliseconds()
|
|
307
|
+
for (let i = 0; i < completedCount; i++) {
|
|
308
|
+
startedMs += snapshot.schedule.tasks[i].duration.toNumber() * 1000
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return {
|
|
312
|
+
...snapshot,
|
|
313
|
+
schedule: ServerContract.Types.schedule.from({
|
|
314
|
+
started: TimePoint.fromMilliseconds(startedMs),
|
|
315
|
+
tasks: remainingTasks,
|
|
316
|
+
}),
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export function projectFromCurrentState(snapshot: ProjectableSnapshot): ProjectedEntity {
|
|
321
|
+
const projectable = buildRemainingProjectable(snapshot)
|
|
322
|
+
return projectable ? projectEntity(projectable) : createProjectedEntity(snapshot)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function getRecipeInputsForOutput(outputItemId: number): RecipeInput[] | undefined {
|
|
326
|
+
const recipe = getRecipe(outputItemId)
|
|
327
|
+
return recipe?.inputs
|
|
307
328
|
}
|
|
308
329
|
|
|
309
330
|
function validateCraftTask(task: ServerContract.Types.task, projected: ProjectedEntity): void {
|
|
@@ -313,7 +334,7 @@ function validateCraftTask(task: ServerContract.Types.task, projected: Projected
|
|
|
313
334
|
const inputs = task.cargo.slice(0, -1)
|
|
314
335
|
const craftQuantity = output.quantity.toNumber()
|
|
315
336
|
|
|
316
|
-
const recipe =
|
|
337
|
+
const recipe = getRecipeInputsForOutput(output.item_id.toNumber())
|
|
317
338
|
if (!recipe) throw new Error(RECIPE_NOT_FOUND)
|
|
318
339
|
|
|
319
340
|
const groupedInputs: ServerContract.Types.cargo_item[][] = recipe.map(() => [])
|
|
@@ -321,15 +342,15 @@ function validateCraftTask(task: ServerContract.Types.task, projected: Projected
|
|
|
321
342
|
let matched = false
|
|
322
343
|
for (let ri = 0; ri < recipe.length; ri++) {
|
|
323
344
|
const req = recipe[ri]
|
|
324
|
-
if (
|
|
345
|
+
if ('itemId' in req) {
|
|
325
346
|
if (input.item_id.toNumber() === req.itemId) {
|
|
326
347
|
groupedInputs[ri].push(input)
|
|
327
348
|
matched = true
|
|
328
349
|
break
|
|
329
350
|
}
|
|
330
|
-
} else
|
|
351
|
+
} else {
|
|
331
352
|
const item = getItem(input.item_id)
|
|
332
|
-
if (item.category === req.category) {
|
|
353
|
+
if (item.category === req.category && item.tier === req.tier) {
|
|
333
354
|
groupedInputs[ri].push(input)
|
|
334
355
|
matched = true
|
|
335
356
|
break
|
|
@@ -348,15 +369,6 @@ function validateCraftTask(task: ServerContract.Types.task, projected: Projected
|
|
|
348
369
|
const required = recipe[ri].quantity * craftQuantity
|
|
349
370
|
if (provided < required) throw new Error(RECIPE_INPUTS_INSUFFICIENT)
|
|
350
371
|
if (provided !== required) throw new Error(RECIPE_INPUTS_EXCESS)
|
|
351
|
-
|
|
352
|
-
if (!recipe[ri].itemId && stacks.length > 1) {
|
|
353
|
-
const firstItemId = stacks[0].item_id.toNumber()
|
|
354
|
-
for (let si = 1; si < stacks.length; si++) {
|
|
355
|
-
if (stacks[si].item_id.toNumber() !== firstItemId) {
|
|
356
|
-
throw new Error(RECIPE_INPUTS_MIXED)
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
372
|
}
|
|
361
373
|
|
|
362
374
|
for (const input of inputs) {
|
|
@@ -441,3 +453,11 @@ export function projectEntityAt(entity: Projectable, now: Date): ProjectedEntity
|
|
|
441
453
|
|
|
442
454
|
return projected
|
|
443
455
|
}
|
|
456
|
+
|
|
457
|
+
export function projectFromCurrentStateAt(
|
|
458
|
+
snapshot: ProjectableSnapshot,
|
|
459
|
+
now: Date
|
|
460
|
+
): ProjectedEntity {
|
|
461
|
+
const projectable = buildRemainingProjectable(snapshot)
|
|
462
|
+
return projectable ? projectEntityAt(projectable, now) : createProjectedEntity(snapshot)
|
|
463
|
+
}
|
package/src/travel/travel.ts
CHANGED
|
@@ -174,7 +174,8 @@ export function calc_ship_mass(ship: ShipLike, cargos: CargoMassInfo[]): UInt64
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
for (const cargo of cargos) {
|
|
177
|
-
|
|
177
|
+
const cargoMass = getItem(cargo.item_id).mass * Number(UInt32.from(cargo.quantity))
|
|
178
|
+
mass.add(UInt64.from(cargoMass))
|
|
178
179
|
}
|
|
179
180
|
|
|
180
181
|
return mass
|
|
@@ -195,8 +196,8 @@ export function calculateTransferTime(
|
|
|
195
196
|
const qty = quantities?.get(Number(cargo.item_id)) ?? 0
|
|
196
197
|
if (qty > 0) {
|
|
197
198
|
const good_mass = getItem(cargo.item_id).mass
|
|
198
|
-
const cargo_mass = good_mass
|
|
199
|
-
mass = UInt64.from(mass).adding(cargo_mass)
|
|
199
|
+
const cargo_mass = good_mass * qty
|
|
200
|
+
mass = UInt64.from(mass).adding(UInt64.from(cargo_mass))
|
|
200
201
|
}
|
|
201
202
|
}
|
|
202
203
|
|
|
@@ -249,12 +250,12 @@ export function calculateLoadTimeBreakdown(
|
|
|
249
250
|
const good = getItem(cargo.item_id)
|
|
250
251
|
|
|
251
252
|
if (loadQty > 0) {
|
|
252
|
-
const cargo_mass = good.mass
|
|
253
|
-
mass_load = UInt64.from(mass_load).adding(cargo_mass)
|
|
253
|
+
const cargo_mass = good.mass * loadQty
|
|
254
|
+
mass_load = UInt64.from(mass_load).adding(UInt64.from(cargo_mass))
|
|
254
255
|
}
|
|
255
256
|
if (unloadQty > 0) {
|
|
256
|
-
const cargo_mass = good.mass
|
|
257
|
-
mass_unload = UInt64.from(mass_unload).adding(cargo_mass)
|
|
257
|
+
const cargo_mass = good.mass * unloadQty
|
|
258
|
+
mass_unload = UInt64.from(mass_unload).adding(UInt64.from(cargo_mass))
|
|
258
259
|
}
|
|
259
260
|
}
|
|
260
261
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Int64Type,
|
|
3
|
-
Name,
|
|
4
|
-
Struct,
|
|
5
|
-
UInt16,
|
|
6
|
-
UInt16Type,
|
|
7
|
-
UInt32,
|
|
8
|
-
UInt32Type,
|
|
9
|
-
UInt64,
|
|
10
|
-
} from '@wharfkit/antelope'
|
|
1
|
+
import {Int64Type, Name, UInt16, UInt16Type, UInt32, UInt32Type, UInt64} from '@wharfkit/antelope'
|
|
11
2
|
import {ServerContract} from './contracts'
|
|
12
3
|
|
|
13
4
|
export const PRECISION = 10000
|
|
@@ -110,8 +101,20 @@ export interface Distance {
|
|
|
110
101
|
distance: UInt16
|
|
111
102
|
}
|
|
112
103
|
|
|
104
|
+
export type ItemType = 'resource' | 'component' | 'module' | 'entity'
|
|
113
105
|
export type ResourceCategory = 'ore' | 'crystal' | 'gas' | 'regolith' | 'biomass'
|
|
114
106
|
export type ResourceTier = 't1' | 't2' | 't3' | 't4' | 't5'
|
|
107
|
+
export type ModuleType =
|
|
108
|
+
| 'any'
|
|
109
|
+
| 'engine'
|
|
110
|
+
| 'generator'
|
|
111
|
+
| 'gatherer'
|
|
112
|
+
| 'loader'
|
|
113
|
+
| 'warp'
|
|
114
|
+
| 'crafter'
|
|
115
|
+
| 'launcher'
|
|
116
|
+
| 'storage'
|
|
117
|
+
| 'hauler'
|
|
115
118
|
|
|
116
119
|
export const TIER_ADJECTIVES: Record<number, string> = {
|
|
117
120
|
1: 'Crude',
|
|
@@ -138,27 +141,18 @@ export function tierNumber(tier: string): number {
|
|
|
138
141
|
return Number(String(tier).replace(/^t/i, ''))
|
|
139
142
|
}
|
|
140
143
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
tier
|
|
155
|
-
@Struct.field('string')
|
|
156
|
-
color!: string
|
|
157
|
-
|
|
158
|
-
get displayName(): string {
|
|
159
|
-
if (this.name && this.name.length > 0) return this.name
|
|
160
|
-
const adj = TIER_ADJECTIVES[tierNumber(this.tier)] ?? 'Unknown'
|
|
161
|
-
const cat = CATEGORY_LABELS[this.category] ?? 'Resource'
|
|
162
|
-
return `${adj} ${cat}`
|
|
163
|
-
}
|
|
144
|
+
export interface Item {
|
|
145
|
+
id: number
|
|
146
|
+
name: string
|
|
147
|
+
description: string
|
|
148
|
+
color: string
|
|
149
|
+
mass: number
|
|
150
|
+
type: ItemType
|
|
151
|
+
tier: number
|
|
152
|
+
category?: ResourceCategory
|
|
153
|
+
moduleType?: ModuleType
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function formatTier(tier: number): string {
|
|
157
|
+
return 'T' + tier
|
|
164
158
|
}
|