@shipload/sdk 2.0.0-rc1 → 2.0.0-rc11

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.
Files changed (74) hide show
  1. package/lib/shipload.d.ts +1701 -1183
  2. package/lib/shipload.js +6746 -3447
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +6429 -3229
  5. package/lib/shipload.m.js.map +1 -1
  6. package/package.json +6 -6
  7. package/src/capabilities/crafting.ts +26 -0
  8. package/src/capabilities/gathering.ts +36 -0
  9. package/src/capabilities/guards.ts +38 -0
  10. package/src/capabilities/hauling.ts +22 -0
  11. package/src/capabilities/index.ts +8 -0
  12. package/src/capabilities/loading.ts +8 -0
  13. package/src/capabilities/modules.ts +57 -0
  14. package/src/capabilities/movement.ts +29 -0
  15. package/src/capabilities/storage.ts +72 -0
  16. package/src/contracts/server.ts +932 -314
  17. package/src/data/capabilities.ts +408 -0
  18. package/src/data/categories.ts +58 -0
  19. package/src/data/colors.ts +53 -0
  20. package/src/data/items.json +17 -0
  21. package/src/data/locations.ts +53 -0
  22. package/src/data/nebula-adjectives.json +211 -0
  23. package/src/data/nebula-nouns.json +151 -0
  24. package/src/data/recipes.ts +571 -0
  25. package/src/data/syllables.json +1386 -780
  26. package/src/data/tiers.ts +45 -0
  27. package/src/derivation/crafting.ts +197 -0
  28. package/src/derivation/index.ts +28 -0
  29. package/src/derivation/location-size.ts +15 -0
  30. package/src/derivation/resources.ts +142 -0
  31. package/src/derivation/stats.ts +146 -0
  32. package/src/derivation/stratum.ts +124 -0
  33. package/src/entities/cargo-utils.ts +46 -9
  34. package/src/entities/container.ts +106 -0
  35. package/src/entities/entity-inventory.ts +13 -13
  36. package/src/entities/inventory-accessor.ts +42 -0
  37. package/src/entities/location.ts +7 -188
  38. package/src/entities/makers.ts +72 -0
  39. package/src/entities/player.ts +1 -273
  40. package/src/entities/ship-deploy.ts +263 -0
  41. package/src/entities/ship.ts +93 -453
  42. package/src/entities/warehouse.ts +34 -148
  43. package/src/errors.ts +4 -4
  44. package/src/index-module.ts +226 -42
  45. package/src/managers/actions.ts +111 -79
  46. package/src/managers/context.ts +0 -9
  47. package/src/managers/entities.ts +22 -5
  48. package/src/managers/index.ts +0 -1
  49. package/src/managers/locations.ts +15 -79
  50. package/src/market/items.ts +30 -0
  51. package/src/nft/description.ts +175 -0
  52. package/src/nft/deserializers.ts +81 -0
  53. package/src/nft/index.ts +2 -0
  54. package/src/resolution/resolve-item.ts +313 -0
  55. package/src/scheduling/accessor.ts +82 -0
  56. package/src/scheduling/projection.ts +158 -54
  57. package/src/scheduling/schedule.ts +24 -0
  58. package/src/shipload.ts +0 -5
  59. package/src/travel/travel.ts +93 -19
  60. package/src/types/capabilities.ts +71 -0
  61. package/src/types/entity-traits.ts +69 -0
  62. package/src/types/entity.ts +39 -0
  63. package/src/types/index.ts +3 -0
  64. package/src/types.ts +76 -33
  65. package/src/utils/hash.ts +1 -1
  66. package/src/utils/system.ts +148 -11
  67. package/src/data/goods.json +0 -23
  68. package/src/managers/trades.ts +0 -119
  69. package/src/market/goods.ts +0 -31
  70. package/src/market/market.ts +0 -209
  71. package/src/market/rolls.ts +0 -8
  72. package/src/trading/collect.ts +0 -939
  73. package/src/trading/deal.ts +0 -208
  74. package/src/trading/trade.ts +0 -203
@@ -0,0 +1,81 @@
1
+ import {getEntitySlotLayout} from '../data/recipes'
2
+ import {
3
+ ITEM_TYPE_COMPONENT,
4
+ ITEM_TYPE_ENTITY,
5
+ ITEM_TYPE_MODULE,
6
+ ITEM_TYPE_RESOURCE,
7
+ itemTypeCode,
8
+ } from '../data/tiers'
9
+
10
+ export interface NFTInstalledModule {
11
+ item_id: number
12
+ seed: string
13
+ }
14
+
15
+ export interface NFTModuleSlot {
16
+ type: number
17
+ installed?: NFTInstalledModule
18
+ }
19
+
20
+ export interface NFTCargoItem {
21
+ item_id: number
22
+ quantity: number
23
+ seed: string
24
+ modules?: NFTModuleSlot[]
25
+ }
26
+
27
+ export interface NFTCommonBase {
28
+ quantity: number
29
+ seed: string
30
+ origin_x: string
31
+ origin_y: string
32
+ }
33
+
34
+ export function readCommonBase(data: Record<string, any>): NFTCommonBase {
35
+ return {
36
+ quantity: Number(data.quantity),
37
+ seed: String(data.seed),
38
+ origin_x: String(data.origin_x),
39
+ origin_y: String(data.origin_y),
40
+ }
41
+ }
42
+
43
+ export function deserializeScalar(data: Record<string, any>, itemId: number): NFTCargoItem {
44
+ const base = readCommonBase(data)
45
+ return {item_id: itemId, quantity: base.quantity, seed: base.seed}
46
+ }
47
+
48
+ export const deserializeResource = deserializeScalar
49
+ export const deserializeComponent = deserializeScalar
50
+ export const deserializeModule = deserializeScalar
51
+
52
+ export function deserializeEntity(data: Record<string, any>, itemId: number): NFTCargoItem {
53
+ const base = readCommonBase(data)
54
+ const moduleItems: number[] = (data.module_items ?? []).map((v: any) => Number(v))
55
+ const moduleSeeds: string[] = (data.module_seeds ?? []).map((v: any) => String(v))
56
+ const layout = getEntitySlotLayout(itemId)
57
+
58
+ const modules: NFTModuleSlot[] = layout.map((slot, i) => ({
59
+ type: slot.type,
60
+ installed:
61
+ moduleItems[i] && moduleItems[i] !== 0
62
+ ? {item_id: moduleItems[i], seed: moduleSeeds[i]}
63
+ : undefined,
64
+ }))
65
+
66
+ return {item_id: itemId, quantity: base.quantity, seed: base.seed, modules}
67
+ }
68
+
69
+ export function deserializeAsset(data: Record<string, any>, itemId: number): NFTCargoItem {
70
+ const type = itemTypeCode(itemId)
71
+ switch (type) {
72
+ case ITEM_TYPE_RESOURCE:
73
+ case ITEM_TYPE_COMPONENT:
74
+ case ITEM_TYPE_MODULE:
75
+ return deserializeScalar(data, itemId)
76
+ case ITEM_TYPE_ENTITY:
77
+ return deserializeEntity(data, itemId)
78
+ default:
79
+ throw new Error(`unknown item type ${type} for item ${itemId}`)
80
+ }
81
+ }
@@ -0,0 +1,2 @@
1
+ export * from './deserializers'
2
+ export * from './description'
@@ -0,0 +1,313 @@
1
+ import {UInt16, UInt64} from '@wharfkit/antelope'
2
+ import type {UInt16Type, UInt64Type} from '@wharfkit/antelope'
3
+ import type {ResourceCategory, ResourceTier} from '../types'
4
+ import {getItem} from '../market/items'
5
+ import {getComponentById, getEntityRecipeByItemId, getModuleRecipeByItemId} from '../data/recipes'
6
+ import {
7
+ getModuleCapabilityType,
8
+ isModuleItem,
9
+ MODULE_CRAFTER,
10
+ MODULE_ENGINE,
11
+ MODULE_GATHERER,
12
+ MODULE_GENERATOR,
13
+ MODULE_LOADER,
14
+ MODULE_STORAGE,
15
+ } from '../capabilities/modules'
16
+ import {decodeCraftedItemStats} from '../derivation/crafting'
17
+ import {deriveResourceStats} from '../derivation/stratum'
18
+ import {getStatDefinitions} from '../derivation/stats'
19
+ import {
20
+ computeEngineCapabilities,
21
+ computeGathererCapabilities,
22
+ computeGeneratorCapabilities,
23
+ computeLoaderCapabilities,
24
+ computeManufacturingCapabilities,
25
+ computeShipHullCapabilities,
26
+ } from '../entities/ship-deploy'
27
+ import {computeContainerCapabilities} from '../entities/container'
28
+ import {categoryColors, categoryIcons, componentIcon, itemIcons, moduleIcon} from '../data/colors'
29
+ import {ServerContract} from '../contracts'
30
+
31
+ export interface ResolvedItemStat {
32
+ key: string
33
+ label: string
34
+ abbreviation: string
35
+ value: number
36
+ color: string
37
+ category: ResourceCategory
38
+ inverted?: boolean
39
+ }
40
+
41
+ export interface ResolvedAttributeGroup {
42
+ capability: string
43
+ attributes: {label: string; value: number}[]
44
+ }
45
+
46
+ export type ResolvedItemType = 'resource' | 'component' | 'module' | 'entity'
47
+
48
+ export interface ResolvedModuleSlot {
49
+ name?: string
50
+ installed: boolean
51
+ attributes?: {label: string; value: number}[]
52
+ }
53
+
54
+ export interface ResolvedItem {
55
+ itemId: number
56
+ name: string
57
+ icon: string
58
+ category?: ResourceCategory
59
+ tier: ResourceTier
60
+ mass: number
61
+ itemType: ResolvedItemType
62
+ stats?: ResolvedItemStat[]
63
+ attributes?: ResolvedAttributeGroup[]
64
+ moduleSlots?: ResolvedModuleSlot[]
65
+ }
66
+
67
+ function toNum(v: UInt16Type): number {
68
+ return Number(UInt16.from(v).value.toString())
69
+ }
70
+
71
+ function toBigSeed(v: UInt64Type): bigint {
72
+ return BigInt(UInt64.from(v).toString())
73
+ }
74
+
75
+ function resolveResource(id: number, seed?: UInt64Type): ResolvedItem {
76
+ const item = getItem(id)
77
+ const cat = item.category
78
+ let stats: ResolvedItemStat[] | undefined
79
+ if (seed !== undefined) {
80
+ const derived = deriveResourceStats(toBigSeed(seed))
81
+ const defs = getStatDefinitions(cat)
82
+ const values = [derived.stat1, derived.stat2, derived.stat3]
83
+ stats = defs.map((d, i) => ({
84
+ key: d.key,
85
+ label: d.label,
86
+ abbreviation: d.abbreviation,
87
+ value: values[i] ?? 0,
88
+ color: categoryColors[cat],
89
+ category: cat,
90
+ inverted: d.inverted,
91
+ }))
92
+ }
93
+ return {
94
+ itemId: id,
95
+ name: String(item.name),
96
+ icon: categoryIcons[cat] ?? '⬡',
97
+ category: cat,
98
+ tier: item.tier,
99
+ mass: Number(item.mass.value.toString()),
100
+ itemType: 'resource',
101
+ stats,
102
+ }
103
+ }
104
+
105
+ function resolveComponent(id: number, seed?: UInt64Type): ResolvedItem {
106
+ const comp = getComponentById(id)!
107
+ let stats: ResolvedItemStat[] | undefined
108
+ if (seed !== undefined) {
109
+ const decoded = decodeCraftedItemStats(id, toBigSeed(seed))
110
+ stats = Object.entries(decoded).map(([key, value]) => {
111
+ const allDefs = getStatDefinitions('metal')
112
+ .concat(getStatDefinitions('precious'))
113
+ .concat(getStatDefinitions('gas'))
114
+ .concat(getStatDefinitions('mineral'))
115
+ .concat(getStatDefinitions('organic'))
116
+ const def = allDefs.find((d) => d.key === key)
117
+ const statDef = comp.stats.find((s) => s.key === key)
118
+ const cat = (statDef?.source ?? 'metal') as ResourceCategory
119
+ return {
120
+ key,
121
+ label: def?.label ?? key,
122
+ abbreviation: def?.abbreviation ?? key.slice(0, 3).toUpperCase(),
123
+ value,
124
+ color: categoryColors[cat],
125
+ category: cat,
126
+ inverted: def?.inverted,
127
+ }
128
+ })
129
+ }
130
+ return {
131
+ itemId: id,
132
+ name: comp.name,
133
+ icon: itemIcons[id] ?? componentIcon,
134
+ tier: 't1' as ResourceTier,
135
+ mass: comp.mass,
136
+ itemType: 'component',
137
+ stats,
138
+ }
139
+ }
140
+
141
+ function computeCapabilityGroup(
142
+ moduleType: number,
143
+ stats: Record<string, number>
144
+ ): ResolvedAttributeGroup | undefined {
145
+ switch (moduleType) {
146
+ case MODULE_ENGINE: {
147
+ const caps = computeEngineCapabilities(stats)
148
+ return {
149
+ capability: 'Engine',
150
+ attributes: [
151
+ {label: 'Thrust', value: caps.thrust},
152
+ {label: 'Drain', value: caps.drain},
153
+ ],
154
+ }
155
+ }
156
+ case MODULE_GENERATOR: {
157
+ const caps = computeGeneratorCapabilities(stats)
158
+ return {
159
+ capability: 'Generator',
160
+ attributes: [
161
+ {label: 'Capacity', value: caps.capacity},
162
+ {label: 'Recharge', value: caps.recharge},
163
+ ],
164
+ }
165
+ }
166
+ case MODULE_GATHERER: {
167
+ const caps = computeGathererCapabilities(stats)
168
+ return {
169
+ capability: 'Gatherer',
170
+ attributes: [
171
+ {label: 'Yield', value: caps.yield},
172
+ {label: 'Drain', value: caps.drain},
173
+ {label: 'Depth', value: caps.depth},
174
+ {label: 'Speed', value: caps.speed},
175
+ ],
176
+ }
177
+ }
178
+ case MODULE_LOADER: {
179
+ const caps = computeLoaderCapabilities(stats)
180
+ return {
181
+ capability: 'Loader',
182
+ attributes: [
183
+ {label: 'Mass', value: caps.mass},
184
+ {label: 'Thrust', value: caps.thrust},
185
+ {label: 'Quantity', value: caps.quantity},
186
+ ],
187
+ }
188
+ }
189
+ case MODULE_CRAFTER: {
190
+ const caps = computeManufacturingCapabilities(stats)
191
+ return {
192
+ capability: 'Manufacturing',
193
+ attributes: [
194
+ {label: 'Speed', value: caps.speed},
195
+ {label: 'Drain', value: caps.drain},
196
+ ],
197
+ }
198
+ }
199
+ case MODULE_STORAGE: {
200
+ const str = stats.strength ?? 500
201
+ const duc = stats.ductility ?? 500
202
+ const pur = stats.purity ?? 500
203
+ const statSum = str + duc + pur
204
+ const pct = 10 + Math.floor((statSum * 10) / 2997)
205
+ return {capability: 'Storage', attributes: [{label: 'Capacity Bonus', value: pct}]}
206
+ }
207
+ default:
208
+ return undefined
209
+ }
210
+ }
211
+
212
+ function resolveModule(id: number, seed?: UInt64Type): ResolvedItem {
213
+ const recipe = getModuleRecipeByItemId(id)!
214
+ let attributes: ResolvedAttributeGroup[] | undefined
215
+ if (seed !== undefined) {
216
+ const stats = decodeCraftedItemStats(id, toBigSeed(seed))
217
+ const modType = getModuleCapabilityType(id)
218
+ const group = computeCapabilityGroup(modType, stats)
219
+ if (group) attributes = [group]
220
+ }
221
+ return {
222
+ itemId: id,
223
+ name: recipe.name,
224
+ icon: itemIcons[id] ?? moduleIcon,
225
+ tier: 't1' as ResourceTier,
226
+ mass: 0,
227
+ itemType: 'module',
228
+ attributes,
229
+ }
230
+ }
231
+
232
+ function resolveEntity(
233
+ id: number,
234
+ seed?: UInt64Type,
235
+ modules?: ServerContract.Types.module_entry[]
236
+ ): ResolvedItem {
237
+ const recipe = getEntityRecipeByItemId(id)!
238
+ let attributes: ResolvedAttributeGroup[] | undefined
239
+ let moduleSlots: ResolvedModuleSlot[] | undefined
240
+
241
+ if (seed !== undefined) {
242
+ const stats = decodeCraftedItemStats(id, toBigSeed(seed))
243
+ attributes = []
244
+
245
+ const isShip = recipe.id === 'ship-t1'
246
+ if (isShip) {
247
+ const hullCaps = computeShipHullCapabilities(stats)
248
+ attributes.push({
249
+ capability: 'Hull',
250
+ attributes: [
251
+ {label: 'Mass', value: hullCaps.hullmass},
252
+ {label: 'Capacity', value: hullCaps.capacity},
253
+ ],
254
+ })
255
+ } else {
256
+ const containerCaps = computeContainerCapabilities(stats)
257
+ attributes.push({
258
+ capability: 'Hull',
259
+ attributes: [
260
+ {label: 'Mass', value: containerCaps.hullmass},
261
+ {label: 'Capacity', value: containerCaps.capacity},
262
+ ],
263
+ })
264
+ }
265
+ }
266
+
267
+ if (recipe.moduleSlots) {
268
+ moduleSlots = recipe.moduleSlots.map((slot, i) => {
269
+ const mod = modules?.[i]
270
+ if (mod?.installed) {
271
+ const modItemId = Number(mod.installed.item_id.value.toString())
272
+ const modSeed = BigInt(mod.installed.seed.toString())
273
+ const modStats = decodeCraftedItemStats(modItemId, modSeed)
274
+ const modType = getModuleCapabilityType(modItemId)
275
+ const group = computeCapabilityGroup(modType, modStats)
276
+ const modRecipe = getModuleRecipeByItemId(modItemId)
277
+ return {
278
+ name: modRecipe?.name ?? 'Module',
279
+ installed: true,
280
+ attributes: group?.attributes,
281
+ }
282
+ }
283
+ return {installed: false}
284
+ })
285
+ }
286
+
287
+ return {
288
+ itemId: id,
289
+ name: recipe.name,
290
+ icon: itemIcons[id] ?? componentIcon,
291
+ tier: 't1' as ResourceTier,
292
+ mass: 0,
293
+ itemType: 'entity',
294
+ attributes,
295
+ moduleSlots,
296
+ }
297
+ }
298
+
299
+ export function resolveItem(
300
+ itemId: UInt16Type,
301
+ seed?: UInt64Type,
302
+ modules?: ServerContract.Types.module_entry[]
303
+ ): ResolvedItem {
304
+ const id = toNum(itemId)
305
+
306
+ if (isModuleItem(id)) return resolveModule(id, seed)
307
+
308
+ if (getComponentById(id)) return resolveComponent(id, seed)
309
+
310
+ if (getEntityRecipeByItemId(id)) return resolveEntity(id, seed, modules)
311
+
312
+ return resolveResource(id, seed)
313
+ }
@@ -0,0 +1,82 @@
1
+ import {ServerContract} from '../contracts'
2
+ import {TaskType} from '../types'
3
+ import {ScheduleData} from './schedule'
4
+ import * as schedule from './schedule'
5
+
6
+ type Task = ServerContract.Types.task
7
+
8
+ export class ScheduleAccessor {
9
+ constructor(private entity: ScheduleData) {}
10
+
11
+ get hasSchedule(): boolean {
12
+ return schedule.hasSchedule(this.entity)
13
+ }
14
+
15
+ get isIdle(): boolean {
16
+ return schedule.isIdle(this.entity)
17
+ }
18
+
19
+ get tasks(): Task[] {
20
+ return schedule.getTasks(this.entity)
21
+ }
22
+
23
+ duration(): number {
24
+ return schedule.scheduleDuration(this.entity)
25
+ }
26
+
27
+ elapsed(now: Date): number {
28
+ return schedule.scheduleElapsed(this.entity, now)
29
+ }
30
+
31
+ remaining(now: Date): number {
32
+ return schedule.scheduleRemaining(this.entity, now)
33
+ }
34
+
35
+ complete(now: Date): boolean {
36
+ return schedule.scheduleComplete(this.entity, now)
37
+ }
38
+
39
+ currentTaskIndex(now: Date): number {
40
+ return schedule.currentTaskIndex(this.entity, now)
41
+ }
42
+
43
+ currentTask(now: Date): Task | undefined {
44
+ return schedule.currentTask(this.entity, now)
45
+ }
46
+
47
+ currentTaskType(now: Date): TaskType | undefined {
48
+ return schedule.currentTaskType(this.entity, now)
49
+ }
50
+
51
+ taskStartTime(index: number): number {
52
+ return schedule.getTaskStartTime(this.entity, index)
53
+ }
54
+
55
+ taskElapsed(index: number, now: Date): number {
56
+ return schedule.getTaskElapsed(this.entity, index, now)
57
+ }
58
+
59
+ taskRemaining(index: number, now: Date): number {
60
+ return schedule.getTaskRemaining(this.entity, index, now)
61
+ }
62
+
63
+ taskComplete(index: number, now: Date): boolean {
64
+ return schedule.isTaskComplete(this.entity, index, now)
65
+ }
66
+
67
+ taskInProgress(index: number, now: Date): boolean {
68
+ return schedule.isTaskInProgress(this.entity, index, now)
69
+ }
70
+
71
+ currentTaskProgress(now: Date): number {
72
+ return schedule.currentTaskProgress(this.entity, now)
73
+ }
74
+
75
+ progress(now: Date): number {
76
+ return schedule.scheduleProgress(this.entity, now)
77
+ }
78
+ }
79
+
80
+ export function createScheduleAccessor(entity: ScheduleData): ScheduleAccessor {
81
+ return new ScheduleAccessor(entity)
82
+ }