@shipload/sdk 2.0.0-rc1 → 2.0.0-rc2
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/README.md +349 -1
- package/lib/shipload.d.ts +609 -248
- package/lib/shipload.js +1683 -1031
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +1613 -1047
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -2
- package/src/capabilities/extraction.ts +37 -0
- package/src/capabilities/guards.ts +43 -0
- package/src/capabilities/index.ts +5 -0
- package/src/capabilities/loading.ts +8 -0
- package/src/capabilities/movement.ts +29 -0
- package/src/capabilities/storage.ts +67 -0
- package/src/contracts/server.ts +340 -136
- package/src/data/goods.json +2 -2
- package/src/entities/cargo-utils.ts +96 -1
- package/src/entities/container.ts +70 -0
- package/src/entities/inventory-accessor.ts +46 -0
- package/src/entities/location.ts +22 -8
- package/src/entities/makers.ts +69 -0
- package/src/entities/player.ts +2 -1
- package/src/entities/ship.ts +86 -437
- package/src/entities/warehouse.ts +28 -144
- package/src/index-module.ts +34 -1
- package/src/managers/actions.ts +60 -28
- package/src/managers/entities.ts +22 -5
- package/src/managers/locations.ts +28 -9
- package/src/managers/trades.ts +2 -2
- package/src/market/market.ts +3 -4
- package/src/scheduling/accessor.ts +82 -0
- package/src/scheduling/projection.ts +125 -53
- package/src/scheduling/schedule.ts +24 -0
- package/src/trading/collect.ts +0 -1
- package/src/trading/deal.ts +0 -1
- package/src/travel/travel.ts +63 -2
- package/src/types/capabilities.ts +79 -0
- package/src/types/entity-traits.ts +70 -0
- package/src/types/entity.ts +36 -0
- package/src/types/index.ts +3 -0
- package/src/types.ts +75 -8
- package/src/utils/hash.ts +1 -1
- package/src/utils/system.ts +132 -4
package/src/entities/ship.ts
CHANGED
|
@@ -1,20 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {UInt16, UInt32, UInt64, UInt64Type} from '@wharfkit/antelope'
|
|
2
2
|
import {ServerContract} from '../contracts'
|
|
3
|
-
import {Coordinates, CoordinatesType
|
|
4
|
-
import {
|
|
3
|
+
import {Coordinates, CoordinatesType} from '../types'
|
|
4
|
+
import {
|
|
5
|
+
getDestinationLocation,
|
|
6
|
+
getPositionAt,
|
|
7
|
+
getFlightOrigin as travelGetFlightOrigin,
|
|
8
|
+
} from '../travel/travel'
|
|
9
|
+
import {
|
|
10
|
+
ProjectedEntity,
|
|
11
|
+
projectEntity as sharedProjectEntity,
|
|
12
|
+
projectEntityAt as sharedProjectEntityAt,
|
|
13
|
+
} from '../scheduling/projection'
|
|
5
14
|
import {Location} from './location'
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import {Scheduleable} from '../scheduling/schedule'
|
|
15
|
+
import {ScheduleAccessor} from '../scheduling/accessor'
|
|
16
|
+
import {InventoryAccessor} from './inventory-accessor'
|
|
9
17
|
import {EntityInventory} from './entity-inventory'
|
|
10
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
energyPercent as calcEnergyPercent,
|
|
20
|
+
needsRecharge as calcNeedsRecharge,
|
|
21
|
+
hasEnergyForDistance,
|
|
22
|
+
maxTravelDistance,
|
|
23
|
+
} from '../capabilities/movement'
|
|
24
|
+
import * as cargoUtils from './cargo-utils'
|
|
25
|
+
import * as schedule from '../scheduling/schedule'
|
|
11
26
|
|
|
12
27
|
export interface ShipStateInput {
|
|
13
28
|
id: UInt64Type
|
|
14
|
-
owner:
|
|
29
|
+
owner: string
|
|
15
30
|
name: string
|
|
16
|
-
|
|
17
|
-
|
|
31
|
+
coordinates: CoordinatesType | {x: number; y: number; z?: number}
|
|
32
|
+
hullmass: number
|
|
18
33
|
capacity: number
|
|
19
34
|
energy: number
|
|
20
35
|
engines: ServerContract.Types.movement_stats
|
|
@@ -24,382 +39,102 @@ export interface ShipStateInput {
|
|
|
24
39
|
cargo?: ServerContract.Types.cargo_item[]
|
|
25
40
|
}
|
|
26
41
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
capacity: UInt32.from(state.capacity),
|
|
37
|
-
energy: UInt16.from(state.energy),
|
|
38
|
-
cargomass: UInt32.from(0),
|
|
39
|
-
cargo: state.cargo || [],
|
|
40
|
-
is_idle: !state.schedule,
|
|
41
|
-
current_task_elapsed: UInt32.from(0),
|
|
42
|
-
current_task_remaining: UInt32.from(0),
|
|
43
|
-
pending_tasks: [],
|
|
44
|
-
engines: state.engines,
|
|
45
|
-
generator: state.generator,
|
|
46
|
-
loaders: state.loaders,
|
|
47
|
-
schedule: state.schedule,
|
|
48
|
-
})
|
|
49
|
-
return new Ship(entityInfo)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
private _location?: Location
|
|
53
|
-
private _inventory?: EntityInventory[]
|
|
42
|
+
type MovementEntity = {
|
|
43
|
+
engines: ServerContract.Types.movement_stats
|
|
44
|
+
generator: ServerContract.Types.energy_stats
|
|
45
|
+
energy: UInt16
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class Ship extends ServerContract.Types.entity_info {
|
|
49
|
+
private _sched?: ScheduleAccessor
|
|
50
|
+
private _inv?: InventoryAccessor
|
|
54
51
|
|
|
55
52
|
get name(): string {
|
|
56
53
|
return this.entity_name
|
|
57
54
|
}
|
|
58
55
|
|
|
56
|
+
get inv(): InventoryAccessor {
|
|
57
|
+
return (this._inv ??= new InventoryAccessor(this))
|
|
58
|
+
}
|
|
59
|
+
|
|
59
60
|
get inventory(): EntityInventory[] {
|
|
60
|
-
|
|
61
|
-
this._inventory = this.cargo.map((item) => new EntityInventory(item))
|
|
62
|
-
}
|
|
63
|
-
return this._inventory
|
|
61
|
+
return this.inv.items
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
get
|
|
67
|
-
|
|
68
|
-
return UInt32.from(this.generator.capacity)
|
|
69
|
-
.dividing(this.engines.drain)
|
|
70
|
-
.multiplying(PRECISION)
|
|
64
|
+
get sched(): ScheduleAccessor {
|
|
65
|
+
return (this._sched ??= new ScheduleAccessor(this))
|
|
71
66
|
}
|
|
72
67
|
|
|
73
|
-
get
|
|
74
|
-
return
|
|
68
|
+
get maxDistance(): UInt32 {
|
|
69
|
+
if (!this.generator || !this.engines) return UInt32.from(0)
|
|
70
|
+
return maxTravelDistance(this as MovementEntity)
|
|
75
71
|
}
|
|
76
72
|
|
|
77
73
|
get isIdle(): boolean {
|
|
78
74
|
return this.is_idle
|
|
79
75
|
}
|
|
80
76
|
|
|
81
|
-
get tasks(): ServerContract.Types.task[] {
|
|
82
|
-
return schedule.getTasks(this)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
scheduleDuration(): number {
|
|
86
|
-
return schedule.scheduleDuration(this)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
scheduleElapsed(now: Date): number {
|
|
90
|
-
return schedule.scheduleElapsed(this, now)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
scheduleRemaining(now: Date): number {
|
|
94
|
-
return schedule.scheduleRemaining(this, now)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
scheduleComplete(now: Date): boolean {
|
|
98
|
-
return schedule.scheduleComplete(this, now)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
currentTaskIndex(now: Date): number {
|
|
102
|
-
return schedule.currentTaskIndex(this, now)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
currentTask(now: Date): ServerContract.Types.task | undefined {
|
|
106
|
-
return schedule.currentTask(this, now)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
currentTaskType(now: Date): TaskType | undefined {
|
|
110
|
-
return schedule.currentTaskType(this, now)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
getTaskStartTime(index: number): number {
|
|
114
|
-
return schedule.getTaskStartTime(this, index)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
getTaskElapsed(index: number, now: Date): number {
|
|
118
|
-
return schedule.getTaskElapsed(this, index, now)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
getTaskRemaining(index: number, now: Date): number {
|
|
122
|
-
return schedule.getTaskRemaining(this, index, now)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
isTaskComplete(index: number, now: Date): boolean {
|
|
126
|
-
return schedule.isTaskComplete(this, index, now)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
isTaskInProgress(index: number, now: Date): boolean {
|
|
130
|
-
return schedule.isTaskInProgress(this, index, now)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
currentTaskProgress(now: Date): number {
|
|
134
|
-
return schedule.currentTaskProgress(this, now)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
scheduleProgress(now: Date): number {
|
|
138
|
-
return schedule.scheduleProgress(this, now)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
77
|
getFlightOrigin(flightTaskIndex: number): Coordinates {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
let origin: Coordinates = this.location
|
|
145
|
-
for (let i = 0; i < flightTaskIndex && i < this.schedule.tasks.length; i++) {
|
|
146
|
-
const task = this.schedule.tasks[i]
|
|
147
|
-
if (task.type.equals(TaskType.FLIGHT) && task.location) {
|
|
148
|
-
origin = task.location
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return origin
|
|
78
|
+
return Coordinates.from(travelGetFlightOrigin(this, flightTaskIndex))
|
|
152
79
|
}
|
|
153
80
|
|
|
154
81
|
destinationLocation(): Coordinates | undefined {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
for (let i = this.schedule.tasks.length - 1; i >= 0; i--) {
|
|
158
|
-
const task = this.schedule.tasks[i]
|
|
159
|
-
if (task.type.equals(TaskType.FLIGHT) && task.location) {
|
|
160
|
-
return task.location
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return undefined
|
|
82
|
+
const dest = getDestinationLocation(this)
|
|
83
|
+
return dest ? Coordinates.from(dest) : undefined
|
|
164
84
|
}
|
|
165
85
|
|
|
166
86
|
positionAt(now: Date): Coordinates {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const taskIndex = this.currentTaskIndex(now)
|
|
172
|
-
if (taskIndex < 0) return this.location
|
|
173
|
-
|
|
174
|
-
const task = this.schedule.tasks[taskIndex]
|
|
175
|
-
|
|
176
|
-
if (!task.type.equals(TaskType.FLIGHT) || !task.location) {
|
|
177
|
-
return this.getFlightOrigin(taskIndex)
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const origin = this.getFlightOrigin(taskIndex)
|
|
181
|
-
const destination = task.location
|
|
182
|
-
const progress = this.currentTaskProgress(now)
|
|
183
|
-
|
|
184
|
-
const interpolated = lerp(origin, destination, progress)
|
|
185
|
-
return Coordinates.from({
|
|
186
|
-
x: Math.round(interpolated.x),
|
|
187
|
-
y: Math.round(interpolated.y),
|
|
188
|
-
})
|
|
87
|
+
const taskIndex = this.sched.currentTaskIndex(now)
|
|
88
|
+
const progress = this.sched.currentTaskProgress(now)
|
|
89
|
+
return Coordinates.from(getPositionAt(this, taskIndex, progress))
|
|
189
90
|
}
|
|
190
91
|
|
|
191
92
|
isInFlight(now: Date): boolean {
|
|
192
|
-
|
|
193
|
-
return taskType === TaskType.FLIGHT
|
|
93
|
+
return schedule.isInFlight(this, now)
|
|
194
94
|
}
|
|
195
95
|
|
|
196
96
|
isRecharging(now: Date): boolean {
|
|
197
|
-
|
|
198
|
-
return taskType === TaskType.RECHARGE
|
|
97
|
+
return schedule.isRecharging(this, now)
|
|
199
98
|
}
|
|
200
99
|
|
|
201
100
|
isLoading(now: Date): boolean {
|
|
202
|
-
|
|
203
|
-
return taskType === TaskType.LOAD
|
|
101
|
+
return schedule.isLoading(this, now)
|
|
204
102
|
}
|
|
205
103
|
|
|
206
104
|
isUnloading(now: Date): boolean {
|
|
207
|
-
|
|
208
|
-
return taskType === TaskType.UNLOAD
|
|
105
|
+
return schedule.isUnloading(this, now)
|
|
209
106
|
}
|
|
210
107
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
for (const item of this.cargo) {
|
|
214
|
-
const good = getGood(item.good_id)
|
|
215
|
-
mass = mass.adding(good.mass.multiplying(item.quantity))
|
|
216
|
-
}
|
|
217
|
-
return mass
|
|
108
|
+
isExtracting(now: Date): boolean {
|
|
109
|
+
return schedule.isExtracting(this, now)
|
|
218
110
|
}
|
|
219
111
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const loaders = this.loaders
|
|
223
|
-
return {
|
|
224
|
-
location: Coordinates.from(this.location),
|
|
225
|
-
energy: UInt16.from(this.energy),
|
|
226
|
-
cargoMass,
|
|
227
|
-
shipMass,
|
|
228
|
-
engines: this.engines,
|
|
229
|
-
generator: this.generator,
|
|
230
|
-
loaders,
|
|
231
|
-
get totalMass() {
|
|
232
|
-
let mass = UInt64.from(this.shipMass).adding(this.cargoMass)
|
|
233
|
-
if (this.loaders) {
|
|
234
|
-
mass = mass.adding(this.loaders.mass.multiplying(this.loaders.quantity))
|
|
235
|
-
}
|
|
236
|
-
return mass
|
|
237
|
-
},
|
|
238
|
-
}
|
|
112
|
+
get hasExtractor(): boolean {
|
|
113
|
+
return this.extractor !== undefined
|
|
239
114
|
}
|
|
240
115
|
|
|
241
116
|
project(): ProjectedEntity {
|
|
242
|
-
|
|
243
|
-
const projected = this.createProjectedEntity(cargoMass)
|
|
244
|
-
|
|
245
|
-
if (!this.schedule) {
|
|
246
|
-
return projected
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
for (const task of this.schedule.tasks) {
|
|
250
|
-
switch (task.type.toNumber()) {
|
|
251
|
-
case TaskType.RECHARGE:
|
|
252
|
-
if (projected.generator) {
|
|
253
|
-
projected.energy = UInt16.from(projected.generator.capacity)
|
|
254
|
-
}
|
|
255
|
-
break
|
|
256
|
-
case TaskType.FLIGHT: {
|
|
257
|
-
if (task.location) {
|
|
258
|
-
const distance = distanceBetweenCoordinates(
|
|
259
|
-
projected.location,
|
|
260
|
-
task.location
|
|
261
|
-
)
|
|
262
|
-
if (projected.engines) {
|
|
263
|
-
const energyUsage = distance
|
|
264
|
-
.dividing(PRECISION)
|
|
265
|
-
.multiplying(projected.engines.drain)
|
|
266
|
-
projected.energy = projected.energy.gt(energyUsage)
|
|
267
|
-
? UInt16.from(projected.energy.subtracting(energyUsage))
|
|
268
|
-
: UInt16.from(0)
|
|
269
|
-
}
|
|
270
|
-
projected.location = Coordinates.from(task.location)
|
|
271
|
-
}
|
|
272
|
-
break
|
|
273
|
-
}
|
|
274
|
-
case TaskType.LOAD:
|
|
275
|
-
for (const item of task.cargo) {
|
|
276
|
-
const good = getGood(item.good_id)
|
|
277
|
-
projected.cargoMass = projected.cargoMass.adding(
|
|
278
|
-
good.mass.multiplying(item.quantity)
|
|
279
|
-
)
|
|
280
|
-
}
|
|
281
|
-
break
|
|
282
|
-
case TaskType.UNLOAD:
|
|
283
|
-
for (const item of task.cargo) {
|
|
284
|
-
const good = getGood(item.good_id)
|
|
285
|
-
const cargoMass = good.mass.multiplying(item.quantity)
|
|
286
|
-
projected.cargoMass = projected.cargoMass.gt(cargoMass)
|
|
287
|
-
? projected.cargoMass.subtracting(cargoMass)
|
|
288
|
-
: UInt64.from(0)
|
|
289
|
-
}
|
|
290
|
-
break
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
return projected
|
|
117
|
+
return sharedProjectEntity(this)
|
|
295
118
|
}
|
|
296
119
|
|
|
297
120
|
projectAt(now: Date): ProjectedEntity {
|
|
298
|
-
|
|
299
|
-
const projected = this.createProjectedEntity(cargoMass)
|
|
300
|
-
|
|
301
|
-
if (!this.schedule || this.schedule.tasks.length === 0) {
|
|
302
|
-
return projected
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
for (let i = 0; i < this.schedule.tasks.length; i++) {
|
|
306
|
-
const task = this.schedule.tasks[i]
|
|
307
|
-
const taskComplete = this.isTaskComplete(i, now)
|
|
308
|
-
const taskInProgress = this.isTaskInProgress(i, now)
|
|
309
|
-
|
|
310
|
-
if (!taskComplete && !taskInProgress) {
|
|
311
|
-
break
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
switch (task.type.toNumber()) {
|
|
315
|
-
case TaskType.RECHARGE:
|
|
316
|
-
if (projected.generator) {
|
|
317
|
-
if (taskComplete) {
|
|
318
|
-
projected.energy = UInt16.from(projected.generator.capacity)
|
|
319
|
-
} else if (taskInProgress) {
|
|
320
|
-
const progress = this.getTaskElapsed(i, now) / task.duration.toNumber()
|
|
321
|
-
const capacity = Number(projected.generator.capacity)
|
|
322
|
-
const currentEnergy = Number(projected.energy)
|
|
323
|
-
const rechargeAmount = (capacity - currentEnergy) * progress
|
|
324
|
-
projected.energy = UInt16.from(
|
|
325
|
-
Math.min(capacity, currentEnergy + rechargeAmount)
|
|
326
|
-
)
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
break
|
|
330
|
-
case TaskType.FLIGHT: {
|
|
331
|
-
if (task.location && projected.engines) {
|
|
332
|
-
const origin = projected.location
|
|
333
|
-
const destination = Coordinates.from(task.location)
|
|
334
|
-
const distance = distanceBetweenCoordinates(origin, task.location)
|
|
335
|
-
const energyUsage = distance
|
|
336
|
-
.dividing(PRECISION)
|
|
337
|
-
.multiplying(projected.engines.drain)
|
|
338
|
-
|
|
339
|
-
if (taskComplete) {
|
|
340
|
-
projected.energy = projected.energy.gt(energyUsage)
|
|
341
|
-
? UInt16.from(projected.energy.subtracting(energyUsage))
|
|
342
|
-
: UInt16.from(0)
|
|
343
|
-
projected.location = destination
|
|
344
|
-
} else if (taskInProgress) {
|
|
345
|
-
const progress = this.getTaskElapsed(i, now) / task.duration.toNumber()
|
|
346
|
-
const interpolated = lerp(origin, destination, progress)
|
|
347
|
-
projected.location = Coordinates.from({
|
|
348
|
-
x: Math.round(interpolated.x),
|
|
349
|
-
y: Math.round(interpolated.y),
|
|
350
|
-
})
|
|
351
|
-
const partialEnergy = UInt64.from(
|
|
352
|
-
Math.floor(Number(energyUsage) * progress)
|
|
353
|
-
)
|
|
354
|
-
projected.energy = projected.energy.gt(partialEnergy)
|
|
355
|
-
? UInt16.from(projected.energy.subtracting(partialEnergy))
|
|
356
|
-
: UInt16.from(0)
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
break
|
|
360
|
-
}
|
|
361
|
-
case TaskType.LOAD:
|
|
362
|
-
if (taskComplete) {
|
|
363
|
-
for (const item of task.cargo) {
|
|
364
|
-
const good = getGood(item.good_id)
|
|
365
|
-
projected.cargoMass = projected.cargoMass.adding(
|
|
366
|
-
good.mass.multiplying(item.quantity)
|
|
367
|
-
)
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
break
|
|
371
|
-
case TaskType.UNLOAD:
|
|
372
|
-
if (taskComplete) {
|
|
373
|
-
for (const item of task.cargo) {
|
|
374
|
-
const good = getGood(item.good_id)
|
|
375
|
-
const cargoMass = good.mass.multiplying(item.quantity)
|
|
376
|
-
projected.cargoMass = projected.cargoMass.gt(cargoMass)
|
|
377
|
-
? projected.cargoMass.subtracting(cargoMass)
|
|
378
|
-
: UInt64.from(0)
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
break
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
return projected
|
|
121
|
+
return sharedProjectEntityAt(this, now)
|
|
386
122
|
}
|
|
387
123
|
|
|
388
|
-
get
|
|
389
|
-
return this.
|
|
124
|
+
get location(): Location {
|
|
125
|
+
return Location.from(this.coordinates)
|
|
390
126
|
}
|
|
391
127
|
|
|
392
128
|
get totalCargoMass(): UInt64 {
|
|
393
|
-
return this.
|
|
129
|
+
return this.inv.totalMass
|
|
394
130
|
}
|
|
395
131
|
|
|
396
132
|
get cargoValue(): UInt64 {
|
|
397
|
-
return this.
|
|
133
|
+
return this.inv.totalValue
|
|
398
134
|
}
|
|
399
135
|
|
|
400
136
|
get totalMass(): UInt64 {
|
|
401
|
-
|
|
402
|
-
let mass = UInt64.from(this.mass ?? 0).adding(cargoMass)
|
|
137
|
+
let mass = UInt64.from(this.hullmass ?? 0).adding(this.totalCargoMass)
|
|
403
138
|
if (this.loaders) {
|
|
404
139
|
mass = mass.adding(UInt64.from(this.loaders.mass).multiplying(this.loaders.quantity))
|
|
405
140
|
}
|
|
@@ -411,43 +146,29 @@ export class Ship extends ServerContract.Types.entity_info implements Scheduleab
|
|
|
411
146
|
}
|
|
412
147
|
|
|
413
148
|
hasSpace(goodMass: UInt64, quantity: number): boolean {
|
|
414
|
-
|
|
415
|
-
const newTotal = this.totalMass.adding(additionalMass)
|
|
416
|
-
return newTotal.lte(this.maxCapacity)
|
|
149
|
+
return this.totalMass.adding(goodMass.multiplying(quantity)).lte(this.maxCapacity)
|
|
417
150
|
}
|
|
418
151
|
|
|
419
152
|
get availableCapacity(): UInt64 {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
return this.maxCapacity.subtracting(this.totalMass)
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
get locationObject(): Location {
|
|
427
|
-
if (!this._location) {
|
|
428
|
-
this._location = Location.from(this.location)
|
|
429
|
-
}
|
|
430
|
-
return this._location
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
setLocation(location: Location): void {
|
|
434
|
-
this._location = location
|
|
153
|
+
return this.totalMass.gte(this.maxCapacity)
|
|
154
|
+
? UInt64.from(0)
|
|
155
|
+
: this.maxCapacity.subtracting(this.totalMass)
|
|
435
156
|
}
|
|
436
157
|
|
|
437
158
|
getCargoForGood(goodId: UInt64Type): EntityInventory | undefined {
|
|
438
|
-
return this.
|
|
159
|
+
return this.inv.forGood(goodId)
|
|
439
160
|
}
|
|
440
161
|
|
|
441
162
|
get sellableCargo(): EntityInventory[] {
|
|
442
|
-
return this.
|
|
163
|
+
return this.inv.sellable
|
|
443
164
|
}
|
|
444
165
|
|
|
445
166
|
get hasSellableCargo(): boolean {
|
|
446
|
-
return this.
|
|
167
|
+
return this.inv.hasSellable
|
|
447
168
|
}
|
|
448
169
|
|
|
449
170
|
get sellableGoodsCount(): number {
|
|
450
|
-
return this.
|
|
171
|
+
return this.inv.sellableCount
|
|
451
172
|
}
|
|
452
173
|
|
|
453
174
|
get isFull(): boolean {
|
|
@@ -455,105 +176,33 @@ export class Ship extends ServerContract.Types.entity_info implements Scheduleab
|
|
|
455
176
|
}
|
|
456
177
|
|
|
457
178
|
get energyPercent(): number {
|
|
458
|
-
if (!this.generator) return 0
|
|
459
|
-
return (
|
|
179
|
+
if (!this.generator || this.energy === undefined) return 0
|
|
180
|
+
return calcEnergyPercent(this as MovementEntity)
|
|
460
181
|
}
|
|
461
182
|
|
|
462
183
|
get needsRecharge(): boolean {
|
|
463
|
-
if (!this.generator) return false
|
|
464
|
-
return
|
|
184
|
+
if (!this.generator || this.energy === undefined) return false
|
|
185
|
+
return calcNeedsRecharge(this as MovementEntity)
|
|
465
186
|
}
|
|
466
187
|
|
|
467
188
|
hasEnergyFor(distance: UInt64): boolean {
|
|
468
|
-
if (!this.engines) return false
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
calculateSaleValue(prices: Map<number, UInt64>): {
|
|
474
|
-
revenue: UInt64
|
|
475
|
-
profit: UInt64
|
|
476
|
-
cost: UInt64
|
|
477
|
-
} {
|
|
478
|
-
if (this.cargo.length === 0) {
|
|
479
|
-
return {revenue: UInt64.from(0), profit: UInt64.from(0), cost: UInt64.from(0)}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
let revenue = UInt64.from(0)
|
|
483
|
-
let cost = UInt64.from(0)
|
|
484
|
-
|
|
485
|
-
for (const item of this.cargo) {
|
|
486
|
-
if (UInt32.from(item.quantity).equals(UInt32.from(0))) continue
|
|
487
|
-
|
|
488
|
-
const goodId = Number(item.good_id)
|
|
489
|
-
const salePrice = prices.get(goodId)
|
|
490
|
-
|
|
491
|
-
if (salePrice) {
|
|
492
|
-
revenue = revenue.adding(salePrice.multiplying(item.quantity))
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
cost = cost.adding(item.unit_cost.multiplying(item.quantity))
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
const profit = revenue.gte(cost) ? revenue.subtracting(cost) : UInt64.from(0)
|
|
189
|
+
if (!this.engines || !this.generator || this.energy === undefined) return false
|
|
190
|
+
return hasEnergyForDistance(this as MovementEntity, distance)
|
|
191
|
+
}
|
|
499
192
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
profit,
|
|
503
|
-
cost,
|
|
504
|
-
}
|
|
193
|
+
calculateSaleValue(prices: Map<number, UInt64>): cargoUtils.SaleValue {
|
|
194
|
+
return cargoUtils.calculateSaleValue(this.cargo, prices)
|
|
505
195
|
}
|
|
506
196
|
|
|
507
|
-
calculateSaleValueFromArray(prices: UInt64[]): {
|
|
508
|
-
|
|
509
|
-
profit: UInt64
|
|
510
|
-
cost: UInt64
|
|
511
|
-
} {
|
|
512
|
-
const priceMap = new Map<number, UInt64>()
|
|
513
|
-
prices.forEach((price, index) => {
|
|
514
|
-
priceMap.set(index, price)
|
|
515
|
-
})
|
|
516
|
-
return this.calculateSaleValue(priceMap)
|
|
197
|
+
calculateSaleValueFromArray(prices: UInt64[]): cargoUtils.SaleValue {
|
|
198
|
+
return cargoUtils.calculateSaleValueFromArray(this.cargo, prices)
|
|
517
199
|
}
|
|
518
200
|
|
|
519
201
|
afterSellGoods(goodsToSell: Array<{goodId: number; quantity: number}>): EntityInventory[] {
|
|
520
|
-
|
|
521
|
-
return []
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
return this.cargo.map((item) => {
|
|
525
|
-
const saleItem = goodsToSell.find((s) => Number(item.good_id) === s.goodId)
|
|
526
|
-
if (!saleItem) {
|
|
527
|
-
return new EntityInventory(item)
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
const currentQty = Number(item.quantity)
|
|
531
|
-
const newQty = Math.max(0, currentQty - saleItem.quantity)
|
|
532
|
-
|
|
533
|
-
return new EntityInventory(
|
|
534
|
-
ServerContract.Types.cargo_item.from({
|
|
535
|
-
good_id: item.good_id,
|
|
536
|
-
quantity: UInt32.from(newQty),
|
|
537
|
-
unit_cost: item.unit_cost,
|
|
538
|
-
})
|
|
539
|
-
)
|
|
540
|
-
})
|
|
202
|
+
return cargoUtils.afterSellGoods(this.cargo, goodsToSell)
|
|
541
203
|
}
|
|
542
204
|
|
|
543
205
|
afterSellAllGoods(): EntityInventory[] {
|
|
544
|
-
|
|
545
|
-
return []
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
return this.cargo.map(
|
|
549
|
-
(item) =>
|
|
550
|
-
new EntityInventory(
|
|
551
|
-
ServerContract.Types.cargo_item.from({
|
|
552
|
-
good_id: item.good_id,
|
|
553
|
-
quantity: UInt32.from(0),
|
|
554
|
-
unit_cost: item.unit_cost,
|
|
555
|
-
})
|
|
556
|
-
)
|
|
557
|
-
)
|
|
206
|
+
return cargoUtils.afterSellAllGoods(this.cargo)
|
|
558
207
|
}
|
|
559
208
|
}
|