@shipload/sdk 0.7.1 → 2.0.0-rc10

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 (79) hide show
  1. package/lib/shipload.d.ts +2203 -288
  2. package/lib/shipload.js +8441 -2210
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +8160 -2167
  5. package/lib/shipload.m.js.map +1 -1
  6. package/package.json +7 -6
  7. package/src/capabilities/crafting.ts +26 -0
  8. package/src/capabilities/extraction.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 +1217 -254
  17. package/src/data/capabilities.ts +408 -0
  18. package/src/data/categories.ts +58 -0
  19. package/src/data/colors.ts +52 -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 +1790 -0
  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 +118 -0
  33. package/src/entities/cargo-utils.ts +84 -0
  34. package/src/entities/container.ts +106 -0
  35. package/src/entities/entity-inventory.ts +39 -0
  36. package/src/entities/gamestate.ts +152 -0
  37. package/src/entities/inventory-accessor.ts +42 -0
  38. package/src/entities/location.ts +60 -0
  39. package/src/entities/makers.ts +72 -0
  40. package/src/entities/player.ts +15 -0
  41. package/src/entities/ship-deploy.ts +263 -0
  42. package/src/entities/ship.ts +199 -0
  43. package/src/entities/warehouse.ts +91 -0
  44. package/src/errors.ts +46 -9
  45. package/src/index-module.ts +302 -7
  46. package/src/managers/actions.ts +197 -0
  47. package/src/managers/base.ts +25 -0
  48. package/src/managers/context.ts +95 -0
  49. package/src/managers/entities.ts +103 -0
  50. package/src/managers/epochs.ts +47 -0
  51. package/src/managers/index.ts +8 -0
  52. package/src/managers/locations.ts +39 -0
  53. package/src/managers/players.ts +13 -0
  54. package/src/market/items.ts +30 -0
  55. package/src/nft/description.ts +175 -0
  56. package/src/nft/deserializers.ts +81 -0
  57. package/src/nft/index.ts +2 -0
  58. package/src/resolution/resolve-item.ts +313 -0
  59. package/src/scheduling/accessor.ts +82 -0
  60. package/src/{epoch.ts → scheduling/epoch.ts} +1 -1
  61. package/src/scheduling/projection.ts +322 -0
  62. package/src/scheduling/schedule.ts +179 -0
  63. package/src/shipload.ts +36 -159
  64. package/src/travel/travel.ts +499 -0
  65. package/src/types/capabilities.ts +71 -0
  66. package/src/types/entity-traits.ts +69 -0
  67. package/src/types/entity.ts +39 -0
  68. package/src/types/index.ts +3 -0
  69. package/src/types.ts +113 -35
  70. package/src/{hash.ts → utils/hash.ts} +1 -1
  71. package/src/utils/system.ts +155 -0
  72. package/src/goods.ts +0 -124
  73. package/src/market.ts +0 -214
  74. package/src/rolls.ts +0 -8
  75. package/src/ship.ts +0 -36
  76. package/src/state.ts +0 -0
  77. package/src/syllables.ts +0 -1184
  78. package/src/system.ts +0 -37
  79. package/src/travel.ts +0 -259
package/src/types.ts CHANGED
@@ -1,16 +1,109 @@
1
- import {Struct, UInt16, UInt16Type, UInt64, UInt64Type} from '@wharfkit/antelope'
1
+ import {
2
+ Int64Type,
3
+ Name,
4
+ Struct,
5
+ UInt16,
6
+ UInt16Type,
7
+ UInt32,
8
+ UInt32Type,
9
+ UInt64,
10
+ } from '@wharfkit/antelope'
2
11
  import {ServerContract} from './contracts'
3
12
 
4
13
  export const PRECISION = 10000
5
- export const TRAVEL_MAXMASS_PENALTY = 5 // Penalty (in seconds) for exceeding the maximum mass per 1000 unit
14
+ export const CRAFT_ENERGY_DIVISOR = 150000
6
15
 
7
- export interface CameraPosition extends ServerContract.ActionParams.Type.coordinates {
8
- z: number
16
+ export const WAREHOUSE_Z = 500
17
+ export const INITIAL_WAREHOUSE_CAPACITY = 10000000
18
+
19
+ export const CONTAINER_Z = 300
20
+ export const INITIAL_CONTAINER_HULLMASS = 50000
21
+ export const INITIAL_CONTAINER_CAPACITY = 2000000
22
+
23
+ export const TRAVEL_MAX_DURATION = 86400
24
+
25
+ export const MIN_ORBITAL_ALTITUDE = 800
26
+ export const MAX_ORBITAL_ALTITUDE = 3000
27
+
28
+ export const BASE_ORBITAL_MASS = 100000
29
+
30
+ export interface ShipLike {
31
+ coordinates: ServerContract.Types.coordinates
32
+ hullmass?: UInt32
33
+ energy?: UInt16
34
+ engines?: ServerContract.Types.movement_stats
35
+ generator?: ServerContract.Types.energy_stats
36
+ loaders?: ServerContract.Types.loader_stats
37
+ hauler?: ServerContract.Types.hauler_stats
38
+ capacity?: UInt32
39
+ }
40
+
41
+ export interface CargoMassInfo {
42
+ item_id: UInt16Type
43
+ quantity: UInt32Type
44
+ }
45
+
46
+ export enum TaskType {
47
+ IDLE = 0,
48
+ TRAVEL = 1,
49
+ RECHARGE = 2,
50
+ LOAD = 3,
51
+ UNLOAD = 4,
52
+ EXTRACT = 5,
53
+ WARP = 6,
54
+ CRAFT = 7,
55
+ DEPLOY = 8,
56
+ DEPLOY_SHIP = 9,
57
+ }
58
+
59
+ export enum LocationType {
60
+ EMPTY = 0,
61
+ PLANET = 1,
62
+ ASTEROID = 2,
63
+ NEBULA = 3,
9
64
  }
10
65
 
11
- export interface Dimensions {
12
- width: number
13
- height: number
66
+ export enum TaskCancelable {
67
+ NEVER = 0,
68
+ BEFORE_START = 1,
69
+ ALWAYS = 2,
70
+ }
71
+
72
+ export const EntityType = {
73
+ SHIP: Name.from('ship'),
74
+ WAREHOUSE: Name.from('warehouse'),
75
+ CONTAINER: Name.from('container'),
76
+ } as const
77
+
78
+ export type EntityTypeName = (typeof EntityType)[keyof typeof EntityType]
79
+
80
+ export type CoordinatesType =
81
+ | Coordinates
82
+ | ServerContract.Types.coordinates
83
+ | {x: Int64Type; y: Int64Type}
84
+
85
+ export class Coordinates extends ServerContract.Types.coordinates {
86
+ static from(value: CoordinatesType): Coordinates {
87
+ return super.from(value) as Coordinates
88
+ }
89
+
90
+ equals(other: CoordinatesType): boolean {
91
+ const coords = Coordinates.from(other)
92
+ return this.x.equals(coords.x) && this.y.equals(coords.y)
93
+ }
94
+
95
+ toLocationId(): UInt64 {
96
+ return coordsToLocationId(this)
97
+ }
98
+ }
99
+
100
+ export function coordsToLocationId(coords: CoordinatesType): UInt64 {
101
+ const c = Coordinates.from(coords)
102
+ const mask = BigInt(0xffffffff)
103
+ const x = BigInt(c.x.toNumber()) & mask
104
+ const y = BigInt(c.y.toNumber()) & mask
105
+ const id = (x << BigInt(32)) | y
106
+ return UInt64.from(id)
14
107
  }
15
108
 
16
109
  export interface Distance {
@@ -19,38 +112,23 @@ export interface Distance {
19
112
  distance: UInt16
20
113
  }
21
114
 
22
- @Struct.type('good')
23
- export class Good extends Struct {
115
+ export type ResourceCategory = 'metal' | 'precious' | 'gas' | 'mineral' | 'organic'
116
+ export type ResourceTier = 't1' | 't2' | 't3' | 't4' | 't5'
117
+
118
+ @Struct.type('item')
119
+ export class Item extends Struct {
24
120
  @Struct.field(UInt16)
25
121
  id!: UInt16
26
122
  @Struct.field('string')
27
123
  name!: string
28
124
  @Struct.field('string')
29
125
  description!: string
30
- @Struct.field(UInt64)
31
- base_price!: UInt64
32
- @Struct.field(UInt64)
33
- mass!: UInt64
34
- }
35
-
36
- export interface GoodType {
37
- id: UInt16Type
38
- name: string
39
- description: string
40
- base_price: UInt64Type
41
- mass: UInt64Type
42
- }
43
-
44
- @Struct.type('GoodPrice')
45
- export class GoodPrice extends Struct {
46
- @Struct.field(UInt16)
47
- id!: UInt16
48
- @Struct.field(Good)
49
- good!: Good
50
- @Struct.field(UInt64)
51
- price!: UInt64
52
- @Struct.field(UInt64)
53
- supply!: UInt64
126
+ @Struct.field(UInt32)
127
+ mass!: UInt32
128
+ @Struct.field('string')
129
+ category!: ResourceCategory
130
+ @Struct.field('string')
131
+ tier!: ResourceTier
132
+ @Struct.field('string')
133
+ color!: string
54
134
  }
55
-
56
- export interface Coordinates extends ServerContract.ActionParams.Type.coordinates {}
@@ -1,6 +1,6 @@
1
1
  import {Bytes, Checksum256, Checksum256Type, Checksum512} from '@wharfkit/antelope'
2
2
 
3
- export function hash(seed: Checksum256Type, string: string): Checksum512 {
3
+ export function hash(seed: Checksum256Type, string: string): Checksum256 {
4
4
  const bytes = Bytes.from(`${seed}${string}`, 'utf8')
5
5
  return Checksum256.hash(bytes)
6
6
  }
@@ -0,0 +1,155 @@
1
+ import {Checksum256, Checksum256Type, Checksum512, UInt8} from '@wharfkit/antelope'
2
+ import {hash512} from './hash'
3
+ import {Coordinates, CoordinatesType, LocationType} from '../types'
4
+ import {ServerContract} from '../contracts'
5
+ import {deriveLocationSize} from '../derivation/location-size'
6
+ import syllables from '../data/syllables.json'
7
+ import nebulaAdjectives from '../data/nebula-adjectives.json'
8
+ import nebulaNouns from '../data/nebula-nouns.json'
9
+
10
+ const LOCATION_EXISTS_THRESHOLD = 0x10
11
+ const LOCATION_ACTIVE_THRESHOLD = 0x80
12
+
13
+ export function getLocationType(
14
+ gameSeed: Checksum256Type,
15
+ coordinates: CoordinatesType
16
+ ): LocationType {
17
+ const seed = Checksum256.from(gameSeed)
18
+ const str = ['system', coordinates.x, coordinates.y].join('-')
19
+ const hashResult = hash512(seed, str)
20
+
21
+ if (hashResult.array[0] >= LOCATION_EXISTS_THRESHOLD) {
22
+ return LocationType.EMPTY
23
+ }
24
+
25
+ if (hashResult.array[1] < 96) {
26
+ return LocationType.PLANET
27
+ } else if (hashResult.array[1] < 176) {
28
+ return LocationType.ASTEROID
29
+ }
30
+ return LocationType.NEBULA
31
+ }
32
+
33
+ export function isExtractableLocation(locationType: LocationType): boolean {
34
+ return locationType !== LocationType.EMPTY
35
+ }
36
+
37
+ function uint16(hash: Checksum512, offset: number): number {
38
+ return (hash.array[offset] << 8) | hash.array[offset + 1]
39
+ }
40
+
41
+ function generatePlanetName(hashResult: Checksum512): string {
42
+ const syllableCount = 2 + (hashResult.array[0] % 2)
43
+ const name: string[] = []
44
+ for (let i = 0; i < syllableCount; i++) {
45
+ const index = uint16(hashResult, 1 + i * 2) % syllables.length
46
+ const syllable = syllables[index]
47
+ name.push(i > 0 ? syllable.toLowerCase() : syllable)
48
+ }
49
+ return name.join('')
50
+ }
51
+
52
+ function generateAsteroidName(hashResult: Checksum512): string {
53
+ const A = 65
54
+ const letter1 = String.fromCharCode(A + (hashResult.array[0] % 26))
55
+ const letter2 = String.fromCharCode(A + (hashResult.array[1] % 26))
56
+ const num = (uint16(hashResult, 2) % 9000) + 1000
57
+ return `${letter1}${letter2}-${num}`
58
+ }
59
+
60
+ function generateNebulaName(hashResult: Checksum512): string {
61
+ const adjIdx = uint16(hashResult, 0) % nebulaAdjectives.length
62
+ const nounIdx = uint16(hashResult, 2) % nebulaNouns.length
63
+ return `${nebulaAdjectives[adjIdx]} ${nebulaNouns[nounIdx]}`
64
+ }
65
+
66
+ export function getSystemName(gameSeed: Checksum256Type, location: CoordinatesType): string {
67
+ const seed = Checksum256.from(gameSeed)
68
+ const locationType = getLocationType(seed, location)
69
+ if (locationType === LocationType.EMPTY) {
70
+ throw new Error("System doesn't exist at location")
71
+ }
72
+ const seedStr = `${location.x}-${location.y}-${locationType}-name`
73
+ const hashResult = hash512(seed, seedStr)
74
+ switch (locationType) {
75
+ case LocationType.PLANET:
76
+ return generatePlanetName(hashResult)
77
+ case LocationType.ASTEROID:
78
+ return generateAsteroidName(hashResult)
79
+ case LocationType.NEBULA:
80
+ return generateNebulaName(hashResult)
81
+ default:
82
+ return generatePlanetName(hashResult)
83
+ }
84
+ }
85
+
86
+ export function hasSystem(gameSeed: Checksum256Type, coordinates: CoordinatesType): boolean {
87
+ return getLocationType(gameSeed, coordinates) !== LocationType.EMPTY
88
+ }
89
+
90
+ export function deriveLocationStatic(
91
+ gameSeed: Checksum256Type,
92
+ coordinates: CoordinatesType
93
+ ): ServerContract.Types.location_static {
94
+ const seed = Checksum256.from(gameSeed)
95
+ const coords = Coordinates.from(coordinates)
96
+ const str = `system-${coords.x}-${coords.y}`
97
+ const hashResult = hash512(seed, str)
98
+
99
+ const loc = ServerContract.Types.location_static.from({
100
+ coords: coords,
101
+ type: LocationType.EMPTY,
102
+ subtype: 0,
103
+ seed0: 0,
104
+ seed1: 0,
105
+ })
106
+
107
+ if (hashResult.array[0] >= LOCATION_EXISTS_THRESHOLD) {
108
+ return loc
109
+ }
110
+
111
+ if (hashResult.array[1] < 96) {
112
+ loc.type = UInt8.from(LocationType.PLANET)
113
+ } else if (hashResult.array[1] < 176) {
114
+ loc.type = UInt8.from(LocationType.ASTEROID)
115
+ } else {
116
+ loc.type = UInt8.from(LocationType.NEBULA)
117
+ }
118
+
119
+ loc.subtype = UInt8.from(
120
+ Number(loc.type) === LocationType.PLANET ? hashResult.array[2] % 6 : hashResult.array[2]
121
+ )
122
+ loc.seed0 = UInt8.from(hashResult.array[3])
123
+ loc.seed1 = UInt8.from(hashResult.array[4])
124
+
125
+ return loc
126
+ }
127
+
128
+ export function deriveLocationEpoch(
129
+ epochSeed: Checksum256Type,
130
+ coordinates: CoordinatesType
131
+ ): ServerContract.Types.location_epoch {
132
+ const seed = Checksum256.from(epochSeed)
133
+ const coords = Coordinates.from(coordinates)
134
+ const str = `system-epoch-${coords.x}-${coords.y}`
135
+ const hashResult = hash512(seed, str)
136
+
137
+ return ServerContract.Types.location_epoch.from({
138
+ active: hashResult.array[0] < LOCATION_ACTIVE_THRESHOLD,
139
+ seed0: hashResult.array[1],
140
+ seed1: hashResult.array[2],
141
+ })
142
+ }
143
+
144
+ export function deriveLocation(
145
+ gameSeed: Checksum256Type,
146
+ epochSeed: Checksum256Type,
147
+ coordinates: CoordinatesType
148
+ ): ServerContract.Types.location_derived {
149
+ const staticProps = deriveLocationStatic(gameSeed, coordinates)
150
+ return ServerContract.Types.location_derived.from({
151
+ static_props: staticProps,
152
+ epoch_props: deriveLocationEpoch(epochSeed, coordinates),
153
+ size: deriveLocationSize(staticProps),
154
+ })
155
+ }
package/src/goods.ts DELETED
@@ -1,124 +0,0 @@
1
- import {UInt16, UInt16Type, UInt64} from '@wharfkit/antelope'
2
- import {Coordinates, Good, GoodType, PRECISION} from './types'
3
-
4
- // List of goods with titles and descriptions
5
- const goods: GoodType[] = [
6
- {
7
- id: 1,
8
- name: 'FizzGlo',
9
- description: 'Pops with flavor! A neon drink that makes your burps glow.',
10
- base_price: 50,
11
- mass: 35_000,
12
- },
13
- // {
14
- // id: 2,
15
- // name: 'ZapSnacks',
16
- // description: 'Electric taste! Spicy edible energy sparks for a tongue-tingling experience.',
17
- // base_price: 0,
18
- // mass: 0,
19
- // },
20
- {
21
- id: 3,
22
- name: 'Blob Buddies',
23
- description: 'Squishy friends! Clingy, cute and mood-matching pet blobs for every home!',
24
- base_price: 95,
25
- mass: 60_000,
26
- },
27
- {
28
- id: 4,
29
- name: 'TuneTooth',
30
- description: 'Whistle while you eat! Edible instrument treats that play tunes when chewed.',
31
- base_price: 145,
32
- mass: 75_000,
33
- },
34
- {
35
- id: 5,
36
- name: 'SunPods',
37
- description: 'Miniature suns in your pocket providing on-demand light & warmth.',
38
- base_price: 295,
39
- mass: 135_000,
40
- },
41
- // {
42
- // id: 6,
43
- // name: 'Fuzzix',
44
- // description: 'Pocket-sized quantum fluff generator for instant comfy.',
45
- // base_price: 0,
46
- // mass: 0,
47
- // },
48
- {
49
- id: 7,
50
- name: 'GlowGo',
51
- description: 'Ingestible bioluminescent jelly, your inside glows in the dark!',
52
- base_price: 650,
53
- mass: 255_000,
54
- },
55
- // {
56
- // id: 8,
57
- // name: 'KrackleKaps',
58
- // description: 'Capsules packed with tiny firecrackers, spice up meals and parties.',
59
- // base_price: 0,
60
- // mass: 0,
61
- // },
62
- {
63
- id: 9,
64
- name: 'PlasmaMints',
65
- description: 'Hypercharged candy giving plasma breath capable of cutting through steel.',
66
- base_price: 3450,
67
- mass: 1_100_000,
68
- },
69
- {
70
- id: 10,
71
- name: 'TimeTreats',
72
- description: 'Confectionery morsels releasing slow-mo effect over a limited period.',
73
- base_price: 8500,
74
- mass: 2_100_000,
75
- },
76
- {
77
- id: 11,
78
- name: 'QuantumQuencher',
79
- description:
80
- 'Bottled hyper-fluid quenching thirst across multiple parallel realities simultaneously.',
81
- base_price: 20_500,
82
- mass: 4_100_000,
83
- },
84
- // {
85
- // id: 12,
86
- // name: 'TransmatterTruffles',
87
- // description: 'Delectable chocolates instantly teleporting consumers short distances.',
88
- // base_price: 0,
89
- // mass: 0,
90
- // },
91
- {
92
- id: 13,
93
- name: 'MemoryGum',
94
- description: 'Chewable gum storing or replaying memories while being chewed.',
95
- base_price: 52_500,
96
- mass: 9_500_000,
97
- },
98
- {
99
- id: 14,
100
- name: 'SymbioSnack',
101
- description: 'Edible alien larvae adopting owner’s taste preference upon consumption.',
102
- base_price: 115_000,
103
- mass: 16_000_000,
104
- },
105
- ]
106
-
107
- export const goodIds = goods.map((g) => g.id)
108
-
109
- export function getGood(good_id: UInt16Type): Good {
110
- const good = goods.find((g) => UInt16.from(good_id).equals(g.id))
111
- if (!good) {
112
- throw new Error('Good does not exist')
113
- }
114
- return Good.from({
115
- ...good,
116
- id: UInt16.from(good.id),
117
- base_price: UInt64.from(good.base_price),
118
- mass: UInt64.from(good.mass).multiplying(PRECISION),
119
- })
120
- }
121
-
122
- export function getGoods(): Good[] {
123
- return goods.map((g) => getGood(g.id))
124
- }
package/src/market.ts DELETED
@@ -1,214 +0,0 @@
1
- import {Coordinates, GoodPrice} from './types'
2
- import {getGood, getGoods} from './goods'
3
- import {Checksum256Type, UInt16Type, UInt64} from '@wharfkit/antelope'
4
- import {roll} from './rolls'
5
- import {ServerContract} from './contracts'
6
-
7
- export enum Rarities {
8
- legendary = 'LEGENDARY',
9
- epic = 'EPIC',
10
- rare = 'RARE',
11
- uncommon = 'UNCOMMON',
12
- common = 'COMMON',
13
- trash = 'TRASH',
14
- }
15
-
16
- export interface Rarity {
17
- rarity: Rarities // The rarity description of this price
18
- minMultiplier: number // The minimum multiplier for this rarity
19
- maxMultiplier: number // The maximum multiplier for this rarity
20
- }
21
-
22
- export function generateLocationSeed(
23
- epochSeed: Checksum256Type,
24
- location: Coordinates,
25
- entitySalt: string
26
- ) {
27
- return `${epochSeed}${location.x}${location.y}${entitySalt}`
28
- }
29
-
30
- export function getRarity(
31
- gameSeed: Checksum256Type,
32
- epochSeed: Checksum256Type,
33
- location: Coordinates,
34
- good_id: UInt16Type
35
- ): Rarity {
36
- const seed = `${epochSeed}${location.x}${location.y}${good_id}rarity`
37
- const rarityRoll = roll(gameSeed, seed)
38
-
39
- if (rarityRoll < 13) {
40
- // (Orange) ~0.02% chance = incredibly high value
41
- return {
42
- rarity: Rarities.legendary,
43
- minMultiplier: 2.25,
44
- maxMultiplier: 3.0,
45
- }
46
- } else if (rarityRoll < 176) {
47
- // (Purple) ~0.25% chance = super high value
48
- return {
49
- rarity: Rarities.epic,
50
- minMultiplier: 1.75,
51
- maxMultiplier: 2.25,
52
- }
53
- } else if (rarityRoll < 996) {
54
- // (Blue) ~1.25% chance = very high value
55
- return {
56
- rarity: Rarities.rare,
57
- minMultiplier: 1.4,
58
- maxMultiplier: 1.75,
59
- }
60
- } else if (rarityRoll < 2966) {
61
- // (Green) ~3.00% chance = high value
62
- return {
63
- rarity: Rarities.uncommon,
64
- minMultiplier: 1.225,
65
- maxMultiplier: 1.4,
66
- }
67
- } else if (rarityRoll < 19568) {
68
- // (White) ~25.33% chance = slightly higher value
69
- return {
70
- rarity: Rarities.common,
71
- minMultiplier: 1.07,
72
- maxMultiplier: 1.225,
73
- }
74
- } else if (rarityRoll < 45988) {
75
- // ~40.30% chance = no value change
76
- return {
77
- rarity: Rarities.trash,
78
- minMultiplier: 1,
79
- maxMultiplier: 1.07,
80
- } // Product is not available
81
- } else if (rarityRoll < 62508) {
82
- // (White) ~25.33% chance = slightly lower value
83
- return {
84
- rarity: Rarities.common,
85
- minMultiplier: 0.925,
86
- maxMultiplier: 1,
87
- }
88
- } else if (rarityRoll < 64518) {
89
- // (Green) ~3.00% chance = low value
90
- return {
91
- rarity: Rarities.uncommon,
92
- minMultiplier: 0.77,
93
- maxMultiplier: 0.925,
94
- }
95
- } else if (rarityRoll < 65437) {
96
- // (Blue) ~1.25% chance = very low value
97
- return {
98
- rarity: Rarities.rare,
99
- minMultiplier: 0.595,
100
- maxMultiplier: 0.77,
101
- }
102
- } else if (rarityRoll < 65523) {
103
- // (Purple) ~0.25% chance = super low value
104
- return {
105
- rarity: Rarities.epic,
106
- minMultiplier: 0.41,
107
- maxMultiplier: 0.595,
108
- }
109
- } else {
110
- // (Orange) ~0.02% chance = incredibly low value
111
- return {
112
- rarity: Rarities.legendary,
113
- minMultiplier: 0.285,
114
- maxMultiplier: 0.41,
115
- }
116
- }
117
- }
118
-
119
- export function getRarityMultiplier(
120
- gameSeed: Checksum256Type,
121
- epochSeed: Checksum256Type,
122
- location: Coordinates,
123
- good_id: UInt16Type
124
- ): number {
125
- const rarity = getRarity(gameSeed, epochSeed, location, good_id)
126
- const range = rarity.maxMultiplier - rarity.minMultiplier
127
- const seed = `${epochSeed}${location.x}${location.y}${good_id}raritymultiplier`
128
- const r = roll(gameSeed, seed)
129
- return rarity.minMultiplier + (r / 65535) * range
130
- }
131
-
132
- export function getLocationMultiplier(
133
- gameSeed: Checksum256Type,
134
- location: Coordinates,
135
- good_id: UInt16Type
136
- ): number {
137
- const seed = `${location.x}${location.y}${good_id}locationmultiplier`
138
- const r = roll(gameSeed, seed)
139
- if (r < 13) {
140
- return 0.75
141
- } else if (r < 176) {
142
- return 0.8
143
- } else if (r < 996) {
144
- return 0.85
145
- } else if (r < 2966) {
146
- return 0.9
147
- } else if (r < 19568) {
148
- return 0.95
149
- } else if (r < 45988) {
150
- return 1
151
- } else if (r < 62508) {
152
- return 1.05
153
- } else if (r < 64518) {
154
- return 1.1
155
- } else if (r < 65437) {
156
- return 1.15
157
- } else if (r < 65523) {
158
- return 1.2
159
- } else {
160
- return 1.25
161
- }
162
- }
163
-
164
- export function getSupply(
165
- gameSeed: Checksum256Type,
166
- state: ServerContract.Types.state_row,
167
- location: Coordinates,
168
- good_id: UInt16Type
169
- ): number {
170
- const seed = `${state.seed}${location.x}${location.y}${good_id}supply`
171
- const r = roll(gameSeed, seed)
172
- const percent = r / 65535
173
- const epoch = 1 + Number(state.epoch) / 90
174
- const ship = Math.pow(Number(state.ships), 1 / 3)
175
- return UInt64.from((128 / good_id) * percent * ship * epoch).toNumber()
176
- }
177
-
178
- export function marketprice(
179
- location: ServerContract.ActionParams.Type.coordinates,
180
- good_id: UInt16Type,
181
- gameSeed: Checksum256Type,
182
- state: ServerContract.Types.state_row
183
- ): GoodPrice {
184
- const good = getGood(good_id)
185
- let price = Number(good.base_price)
186
-
187
- // Rarity multiplier of the deal (changes with epoch)
188
- // Large impact range on price, from 0.285x to 3.0x
189
- const rarityMultiplier = getRarityMultiplier(gameSeed, state.seed, location, good_id)
190
- price *= rarityMultiplier
191
-
192
- // Location multiplier of the deal (static, based on game seed)
193
- // Small impact range on price, from 1.0x to 1.5x
194
- const locationMultiplier = getLocationMultiplier(gameSeed, location, good_id)
195
- price *= locationMultiplier
196
-
197
- // Determine the current supply of the good at the location
198
- const supply = getSupply(gameSeed, state, location, good_id)
199
-
200
- return GoodPrice.from({
201
- id: good_id,
202
- good,
203
- price: UInt64.from(price),
204
- supply: UInt64.from(supply),
205
- })
206
- }
207
-
208
- export function marketprices(
209
- location: ServerContract.ActionParams.Type.coordinates,
210
- gameSeed: Checksum256Type,
211
- state: ServerContract.Types.state_row
212
- ): GoodPrice[] {
213
- return getGoods().map((good) => marketprice(location, good.id, gameSeed, state))
214
- }
package/src/rolls.ts DELETED
@@ -1,8 +0,0 @@
1
- import {Checksum256Type} from '@wharfkit/antelope'
2
- import {hash512} from './hash'
3
-
4
- export function roll(game_seed: Checksum256Type, roll_seed: string): number {
5
- const hash = hash512(game_seed, roll_seed)
6
- // Combine the first two bytes to form a uint16_t value
7
- return (hash.array[0] << 8) | hash.array[1]
8
- }