@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
@@ -1,5 +1,6 @@
1
- import {UInt64, UInt64Type} from '@wharfkit/antelope'
1
+ import {UInt32, UInt64, UInt64Type} from '@wharfkit/antelope'
2
2
  import {EntityInventory} from './entity-inventory'
3
+ import {ServerContract} from '../contracts'
3
4
 
4
5
  export interface CargoData {
5
6
  cargo: EntityInventory[]
@@ -11,17 +12,11 @@ export function totalCargoMass(cargo: EntityInventory[]): UInt64 {
11
12
  }, UInt64.from(0))
12
13
  }
13
14
 
14
- export function cargoValue(cargo: EntityInventory[]): UInt64 {
15
- return cargo.reduce((sum, c) => {
16
- return sum.adding(c.totalCost)
17
- }, UInt64.from(0))
18
- }
19
-
20
- export function getCargoForGood(
15
+ export function getCargoForItem(
21
16
  cargo: EntityInventory[],
22
17
  goodId: UInt64Type
23
18
  ): EntityInventory | undefined {
24
- return cargo.find((c) => c.good_id.equals(goodId))
19
+ return cargo.find((c) => c.item_id.equals(goodId))
25
20
  }
26
21
 
27
22
  export function hasSpace(
@@ -45,3 +40,45 @@ export function availableCapacity(currentMass: UInt64, maxCapacity: UInt64): UIn
45
40
  export function isFull(currentMass: UInt64, maxCapacity: UInt64): boolean {
46
41
  return currentMass.gte(maxCapacity)
47
42
  }
43
+
44
+ export function afterRemoveItems(
45
+ cargo: ServerContract.Types.cargo_item[],
46
+ goodsToRemove: Array<{goodId: number; quantity: number}>
47
+ ): EntityInventory[] {
48
+ if (cargo.length === 0) {
49
+ return []
50
+ }
51
+
52
+ return cargo.map((item) => {
53
+ const removeItem = goodsToRemove.find((s) => Number(item.item_id) === s.goodId)
54
+ if (!removeItem) {
55
+ return new EntityInventory(item)
56
+ }
57
+
58
+ const currentQty = Number(item.quantity)
59
+ const newQty = Math.max(0, currentQty - removeItem.quantity)
60
+
61
+ return new EntityInventory(
62
+ ServerContract.Types.cargo_item.from({
63
+ item_id: item.item_id,
64
+ quantity: UInt32.from(newQty),
65
+ })
66
+ )
67
+ })
68
+ }
69
+
70
+ export function afterRemoveAllItems(cargo: ServerContract.Types.cargo_item[]): EntityInventory[] {
71
+ if (cargo.length === 0) {
72
+ return []
73
+ }
74
+
75
+ return cargo.map(
76
+ (item) =>
77
+ new EntityInventory(
78
+ ServerContract.Types.cargo_item.from({
79
+ item_id: item.item_id,
80
+ quantity: UInt32.from(0),
81
+ })
82
+ )
83
+ )
84
+ }
@@ -0,0 +1,106 @@
1
+ import {UInt64, UInt64Type} from '@wharfkit/antelope'
2
+ import {ServerContract} from '../contracts'
3
+ import {CoordinatesType} from '../types'
4
+ import {Location} from './location'
5
+ import {ScheduleAccessor} from '../scheduling/accessor'
6
+ import * as schedule from '../scheduling/schedule'
7
+
8
+ export interface ContainerStateInput {
9
+ id: UInt64Type
10
+ owner: string
11
+ name: string
12
+ coordinates: CoordinatesType | {x: number; y: number; z?: number}
13
+ hullmass: number
14
+ capacity: number
15
+ cargomass?: number
16
+ schedule?: ServerContract.Types.schedule
17
+ }
18
+
19
+ export class Container extends ServerContract.Types.entity_info {
20
+ private _sched?: ScheduleAccessor
21
+
22
+ get name(): string {
23
+ return this.entity_name
24
+ }
25
+
26
+ get sched(): ScheduleAccessor {
27
+ return (this._sched ??= new ScheduleAccessor(this))
28
+ }
29
+
30
+ get isIdle(): boolean {
31
+ return this.is_idle
32
+ }
33
+
34
+ isLoading(now: Date): boolean {
35
+ return schedule.isLoading(this, now)
36
+ }
37
+
38
+ isUnloading(now: Date): boolean {
39
+ return schedule.isUnloading(this, now)
40
+ }
41
+
42
+ get location(): Location {
43
+ return Location.from(this.coordinates)
44
+ }
45
+
46
+ get totalMass(): UInt64 {
47
+ return UInt64.from(this.hullmass ?? 0).adding(this.cargomass)
48
+ }
49
+
50
+ get maxCapacity(): UInt64 {
51
+ return UInt64.from(this.capacity)
52
+ }
53
+
54
+ get availableCapacity(): UInt64 {
55
+ const cargo = UInt64.from(this.cargomass)
56
+ return cargo.gte(this.maxCapacity) ? UInt64.from(0) : this.maxCapacity.subtracting(cargo)
57
+ }
58
+
59
+ hasSpace(additionalMass: UInt64): boolean {
60
+ return UInt64.from(this.cargomass).adding(additionalMass).lte(this.maxCapacity)
61
+ }
62
+
63
+ get isFull(): boolean {
64
+ return UInt64.from(this.cargomass).gte(this.maxCapacity)
65
+ }
66
+
67
+ get orbitalAltitude(): number {
68
+ return this.coordinates.z?.toNumber() || 0
69
+ }
70
+ }
71
+
72
+ export function computeContainerCapabilities(stats: Record<string, number>): {
73
+ hullmass: number
74
+ capacity: number
75
+ } {
76
+ const density = stats['density'] ?? 500
77
+ const strength = stats['strength'] ?? 500
78
+ const ductility = stats['ductility'] ?? 500
79
+ const purity = stats['purity'] ?? 500
80
+
81
+ const hullmass = 25000 + 75 * density
82
+
83
+ const statSum = strength + ductility + purity
84
+ const exponent = statSum / 2997
85
+ const capacity = Math.floor(1000000 * Math.pow(10, exponent))
86
+
87
+ return {hullmass, capacity}
88
+ }
89
+
90
+ export function computeContainerT2Capabilities(stats: Record<string, number>): {
91
+ hullmass: number
92
+ capacity: number
93
+ } {
94
+ const strength = stats['strength'] ?? 0
95
+ const density = stats['density'] ?? 0
96
+ const ductility = stats['ductility'] ?? 0
97
+ const purity = stats['purity'] ?? 0
98
+
99
+ const hullmass = 20000 + 50 * density
100
+
101
+ const statSum = strength + ductility + purity
102
+ const exponent = statSum / 2500
103
+ const capacity = Math.floor(1500000 * Math.pow(10, exponent))
104
+
105
+ return {hullmass, capacity}
106
+ }
@@ -1,34 +1,34 @@
1
1
  import {UInt32, UInt64} from '@wharfkit/antelope'
2
2
  import {ServerContract} from '../contracts'
3
- import {getGood} from '../market/goods'
4
- import {Good} from '../types'
3
+ import {getItem} from '../market/items'
4
+ import {Item} from '../types'
5
5
 
6
6
  export class EntityInventory extends ServerContract.Types.cargo_item {
7
- private _good?: Good
7
+ private _item?: Item
8
8
 
9
- get good(): Good {
10
- if (!this._good) {
11
- this._good = getGood(this.good_id)
9
+ get item(): Item {
10
+ if (!this._item) {
11
+ this._item = getItem(this.item_id)
12
12
  }
13
- return this._good
13
+ return this._item
14
+ }
15
+
16
+ get good(): Item {
17
+ return this.item
14
18
  }
15
19
 
16
20
  get name(): string {
17
- return this.good.name
21
+ return this.item.name
18
22
  }
19
23
 
20
24
  get unitMass(): UInt32 {
21
- return this.good.mass
25
+ return this.item.mass
22
26
  }
23
27
 
24
28
  get totalMass(): UInt64 {
25
29
  return UInt64.from(this.unitMass).multiplying(this.quantity)
26
30
  }
27
31
 
28
- get totalCost(): UInt64 {
29
- return this.unit_cost.multiplying(this.quantity)
30
- }
31
-
32
32
  get hasCargo(): boolean {
33
33
  return UInt32.from(this.quantity).gt(UInt32.from(0))
34
34
  }
@@ -0,0 +1,42 @@
1
+ import {UInt64, UInt64Type} from '@wharfkit/antelope'
2
+ import {EntityInventory} from './entity-inventory'
3
+ import {HasCargo} from '../capabilities/storage'
4
+
5
+ export type {HasCargo}
6
+
7
+ export class InventoryAccessor {
8
+ private _items?: EntityInventory[]
9
+
10
+ constructor(private readonly entity: HasCargo) {}
11
+
12
+ get items(): EntityInventory[] {
13
+ if (!this._items) {
14
+ this._items = this.entity.cargo.map((item) => new EntityInventory(item))
15
+ }
16
+ return this._items
17
+ }
18
+
19
+ get totalMass(): UInt64 {
20
+ return this.items.reduce((sum, c) => sum.adding(c.totalMass), UInt64.from(0))
21
+ }
22
+
23
+ forItem(goodId: UInt64Type): EntityInventory | undefined {
24
+ return this.items.find((c) => c.item_id.equals(goodId))
25
+ }
26
+
27
+ get sellable(): EntityInventory[] {
28
+ return this.items.filter((c) => c.hasCargo)
29
+ }
30
+
31
+ get hasSellable(): boolean {
32
+ return this.items.some((c) => c.hasCargo)
33
+ }
34
+
35
+ get sellableCount(): number {
36
+ return this.items.filter((c) => c.hasCargo).length
37
+ }
38
+ }
39
+
40
+ export function createInventoryAccessor(entity: HasCargo): InventoryAccessor {
41
+ return new InventoryAccessor(entity)
42
+ }
@@ -1,35 +1,22 @@
1
- import {Checksum256, Checksum256Type, UInt16, UInt16Type, UInt64} from '@wharfkit/antelope'
2
- import {ServerContract} from '../contracts'
3
- import {Coordinates, CoordinatesType, Distance, GoodPrice} from '../types'
4
- import {hasSystem} from '../utils/system'
1
+ import {Checksum256, Checksum256Type, UInt16Type, UInt64} from '@wharfkit/antelope'
2
+ import {Coordinates, CoordinatesType, Distance, LocationType} from '../types'
3
+ import {getLocationType, hasSystem, isGatherableLocation} from '../utils/system'
5
4
  import {findNearbyPlanets} from '../travel/travel'
6
5
 
7
- /**
8
- * Location helper class for working with game coordinates.
9
- * Provides system detection, market price caching, nearby planet finding, and supply tracking.
10
- */
11
6
  export class Location {
12
7
  readonly coordinates: Coordinates
13
- private _marketPrices?: GoodPrice[]
14
8
  private _gameSeed?: Checksum256
15
9
  private _hasSystem?: boolean
16
- private _locationRows?: ServerContract.Types.location_row[]
17
10
  private _epoch?: UInt64
18
11
 
19
12
  constructor(coordinates: CoordinatesType) {
20
13
  this.coordinates = Coordinates.from(coordinates)
21
14
  }
22
15
 
23
- /**
24
- * Create a Location from coordinates
25
- */
26
16
  static from(coordinates: CoordinatesType): Location {
27
17
  return new Location(Coordinates.from(coordinates))
28
18
  }
29
19
 
30
- /**
31
- * Check if this location has a system (planet)
32
- */
33
20
  hasSystemAt(gameSeed: Checksum256Type): boolean {
34
21
  const seed = Checksum256.from(gameSeed)
35
22
  if (this._hasSystem === undefined || !this._gameSeed?.equals(seed)) {
@@ -39,200 +26,32 @@ export class Location {
39
26
  return this._hasSystem
40
27
  }
41
28
 
42
- /**
43
- * Set cached market prices for this location
44
- */
45
- setMarketPrices(prices: GoodPrice[]): void {
46
- this._marketPrices = prices
29
+ getLocationTypeAt(gameSeed: Checksum256Type): LocationType {
30
+ return getLocationType(gameSeed, this.coordinates)
47
31
  }
48
32
 
49
- /**
50
- * Get cached market prices (returns undefined if not cached)
51
- */
52
- get marketPrices(): GoodPrice[] | undefined {
53
- return this._marketPrices
33
+ isGatherableAt(gameSeed: Checksum256Type): boolean {
34
+ return isGatherableLocation(this.getLocationTypeAt(gameSeed))
54
35
  }
55
36
 
56
- /**
57
- * Get price for a specific good (from cache)
58
- */
59
- getPrice(goodId: UInt16Type): GoodPrice | undefined {
60
- if (!this._marketPrices) return undefined
61
- return this._marketPrices.find((p) => p.id.equals(goodId))
62
- }
63
-
64
- /**
65
- * Find nearby planets from this location
66
- */
67
37
  findNearby(gameSeed: Checksum256Type, maxDistance: UInt16Type = 20): Distance[] {
68
38
  return findNearbyPlanets(Checksum256.from(gameSeed), this.coordinates, maxDistance)
69
39
  }
70
40
 
71
- /**
72
- * Check if this location equals another location
73
- */
74
41
  equals(other: CoordinatesType | Location): boolean {
75
42
  const otherCoords = other instanceof Location ? other.coordinates : Coordinates.from(other)
76
43
  return this.coordinates.equals(otherCoords)
77
44
  }
78
45
 
79
- /**
80
- * Set location rows (supply data) for this location
81
- */
82
- setLocationRows(rows: ServerContract.Types.location_row[], epoch: UInt64): void {
83
- this._locationRows = rows
84
- this._epoch = epoch
85
- }
86
-
87
- /**
88
- * Get cached location rows (supply data)
89
- */
90
- get locationRows(): ServerContract.Types.location_row[] | undefined {
91
- return this._locationRows
92
- }
93
-
94
- /**
95
- * Get supply for a specific good at this location
96
- * Returns undefined if location rows not cached or good not found
97
- */
98
- getSupply(goodId: UInt16Type): UInt16 | undefined {
99
- if (!this._locationRows) return undefined
100
- const row = this._locationRows.find(
101
- (r) => r.good_id.equals(goodId) && this._epoch && r.epoch.equals(this._epoch)
102
- )
103
- return row ? row.supply : undefined
104
- }
105
-
106
- /**
107
- * Get all available goods at this location (goods with supply > 0)
108
- * Returns undefined if location rows not cached
109
- */
110
- get availableGoods(): ServerContract.Types.location_row[] | undefined {
111
- if (!this._locationRows) return undefined
112
- return this._locationRows.filter(
113
- (r) => this._epoch && r.epoch.equals(this._epoch) && r.supply.gt(UInt16.from(0))
114
- )
115
- }
116
-
117
- /**
118
- * Check if a specific good is available (has supply)
119
- * Returns false if location rows not cached
120
- */
121
- hasGood(goodId: UInt16Type): boolean {
122
- const supply = this.getSupply(goodId)
123
- return supply !== undefined && supply.gt(UInt16.from(0))
124
- }
125
-
126
- /**
127
- * Get the epoch for cached location data
128
- */
129
46
  get epoch(): UInt64 | undefined {
130
47
  return this._epoch
131
48
  }
132
49
 
133
- /**
134
- * Check if cached data exists
135
- */
136
- get hasCachedData(): boolean {
137
- return this._marketPrices !== undefined || this._locationRows !== undefined
138
- }
139
-
140
- /**
141
- * Check if supply data is cached
142
- */
143
- get hasSupplyData(): boolean {
144
- return this._locationRows !== undefined
145
- }
146
-
147
- /**
148
- * Clear all cached data
149
- */
150
50
  clearCache(): void {
151
- this._marketPrices = undefined
152
- this._locationRows = undefined
153
51
  this._epoch = undefined
154
52
  }
155
-
156
- /**
157
- * Create optimistic Location with updated supply after purchase/sale.
158
- * Matches contract: update_location_supply (delta can be positive or negative)
159
- * Contract reference: market.cpp:53, 123-151
160
- *
161
- * @param goodId - Good ID to update supply for
162
- * @param quantityDelta - Change in supply (negative for purchase, positive for sale)
163
- * @returns New Location with updated supply in cached data
164
- *
165
- * @example
166
- * // After buying 10 units (supply decreases)
167
- * const newLocation = location.withUpdatedSupply(1, -10)
168
- *
169
- * // After selling 5 units (supply increases)
170
- * const newLocation = location.withUpdatedSupply(1, 5)
171
- */
172
- withUpdatedSupply(goodId: UInt16Type, quantityDelta: number): Location {
173
- const newLocation = Location.from(this.coordinates)
174
-
175
- // Copy market prices if cached
176
- if (this._marketPrices) {
177
- newLocation._marketPrices = this._marketPrices.map((price) => {
178
- if (price.id.equals(goodId)) {
179
- const currentSupply = UInt16.from(price.supply)
180
- const delta = UInt16.from(Math.abs(quantityDelta))
181
- const newSupply =
182
- quantityDelta < 0
183
- ? currentSupply.gte(delta)
184
- ? currentSupply.subtracting(delta)
185
- : UInt16.from(0)
186
- : currentSupply.adding(quantityDelta)
187
-
188
- return GoodPrice.from({
189
- id: price.id,
190
- good: price.good,
191
- price: price.price,
192
- supply: newSupply,
193
- })
194
- }
195
- return price
196
- })
197
- }
198
-
199
- // Copy location rows if cached
200
- if (this._locationRows && this._epoch) {
201
- newLocation._locationRows = this._locationRows.map((row) => {
202
- if (row.good_id.equals(goodId) && row.epoch.equals(this._epoch!)) {
203
- const currentSupply = UInt16.from(row.supply)
204
- const delta = UInt16.from(Math.abs(quantityDelta))
205
- const newSupply =
206
- quantityDelta < 0
207
- ? currentSupply.gte(delta)
208
- ? currentSupply.subtracting(delta)
209
- : UInt16.from(0)
210
- : currentSupply.adding(quantityDelta)
211
-
212
- return ServerContract.Types.location_row.from({
213
- id: row.id,
214
- coordinates: row.coordinates,
215
- epoch: row.epoch,
216
- good_id: row.good_id,
217
- supply: newSupply,
218
- })
219
- }
220
- return row
221
- })
222
- newLocation._epoch = this._epoch
223
- }
224
-
225
- // Copy other cached data
226
- newLocation._gameSeed = this._gameSeed
227
- newLocation._hasSystem = this._hasSystem
228
-
229
- return newLocation
230
- }
231
53
  }
232
54
 
233
- /**
234
- * Helper function to convert various coordinate types to Location
235
- */
236
55
  export function toLocation(coords: CoordinatesType | Location): Location {
237
56
  if (coords instanceof Location) {
238
57
  return coords
@@ -0,0 +1,72 @@
1
+ import {Name, UInt16, UInt32, UInt64} from '@wharfkit/antelope'
2
+ import {ServerContract} from '../contracts'
3
+ import {Ship, ShipStateInput} from './ship'
4
+ import {Warehouse, WarehouseStateInput} from './warehouse'
5
+ import {Container, ContainerStateInput} from './container'
6
+
7
+ export function makeShip(state: ShipStateInput): Ship {
8
+ const info: Record<string, unknown> = {
9
+ type: Name.from('ship'),
10
+ id: UInt64.from(state.id),
11
+ owner: Name.from(state.owner),
12
+ entity_name: state.name,
13
+ coordinates: ServerContract.Types.coordinates.from(state.coordinates),
14
+ cargomass: UInt32.from(0),
15
+ cargo: state.cargo || [],
16
+ is_idle: !state.schedule,
17
+ current_task_elapsed: UInt32.from(0),
18
+ current_task_remaining: UInt32.from(0),
19
+ pending_tasks: [],
20
+ }
21
+ if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
22
+ if (state.capacity !== undefined) info.capacity = UInt32.from(state.capacity)
23
+ if (state.energy !== undefined) info.energy = UInt16.from(state.energy)
24
+ if (state.engines) info.engines = state.engines
25
+ if (state.generator) info.generator = state.generator
26
+ if (state.loaders) info.loaders = state.loaders
27
+ if (state.schedule) info.schedule = state.schedule
28
+ const entityInfo = ServerContract.Types.entity_info.from(info)
29
+ return new Ship(entityInfo)
30
+ }
31
+
32
+ export function makeWarehouse(state: WarehouseStateInput): Warehouse {
33
+ const info: Record<string, unknown> = {
34
+ type: Name.from('warehouse'),
35
+ id: UInt64.from(state.id),
36
+ owner: Name.from(state.owner),
37
+ entity_name: state.name,
38
+ coordinates: ServerContract.Types.coordinates.from(state.coordinates),
39
+ capacity: UInt32.from(state.capacity),
40
+ cargomass: UInt32.from(0),
41
+ cargo: state.cargo || [],
42
+ is_idle: !state.schedule,
43
+ current_task_elapsed: UInt32.from(0),
44
+ current_task_remaining: UInt32.from(0),
45
+ pending_tasks: [],
46
+ }
47
+ if (state.hullmass !== undefined) info.hullmass = UInt32.from(state.hullmass)
48
+ if (state.loaders) info.loaders = state.loaders
49
+ if (state.schedule) info.schedule = state.schedule
50
+ const entityInfo = ServerContract.Types.entity_info.from(info)
51
+ return new Warehouse(entityInfo)
52
+ }
53
+
54
+ export function makeContainer(state: ContainerStateInput): Container {
55
+ const entityInfo = ServerContract.Types.entity_info.from({
56
+ type: Name.from('container'),
57
+ id: UInt64.from(state.id),
58
+ owner: Name.from(state.owner),
59
+ entity_name: state.name,
60
+ coordinates: ServerContract.Types.coordinates.from(state.coordinates),
61
+ hullmass: UInt32.from(state.hullmass),
62
+ capacity: UInt32.from(state.capacity),
63
+ cargomass: UInt32.from(state.cargomass || 0),
64
+ cargo: [],
65
+ is_idle: !state.schedule,
66
+ current_task_elapsed: UInt32.from(0),
67
+ current_task_remaining: UInt32.from(0),
68
+ pending_tasks: [],
69
+ schedule: state.schedule,
70
+ })
71
+ return new Container(entityInfo)
72
+ }