返回提交历史
Modified
src/services/serversideVendorsService.ts
+37
-12
Deleted
static/fixed_responses/getVendorInfo/MaskSalesmanManifest.json
+0
-301
XFEstudio/SpaceNinjaServer
feat: autogenerate mask vendor (#2216)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2216 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
3619bdfd
代码差异
2 个文件
+37
-313
@@ -18,7 +18,6 @@ import DeimosPetVendorManifest from "@/static/fixed_responses/getVendorInfo/Deim
18
18
import DuviriAcrithisVendorManifest from "@/static/fixed_responses/getVendorInfo/DuviriAcrithisVendorManifest.json";
19
19
import EntratiLabsEntratiLabsCommisionsManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabsCommisionsManifest.json";
20
20
import EntratiLabsEntratiLabVendorManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabVendorManifest.json";
21
import MaskSalesmanManifest from "@/static/fixed_responses/getVendorInfo/MaskSalesmanManifest.json";
22
21
import Nova1999ConquestShopManifest from "@/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json";
23
22
import OstronPetVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json";
24
23
import SolarisDebtTokenVendorRepossessionsManifest from "@/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorRepossessionsManifest.json";
@@ -35,7 +34,6 @@ const rawVendorManifests: IVendorManifest[] = [
35
34
DuviriAcrithisVendorManifest,
36
35
EntratiLabsEntratiLabsCommisionsManifest,
37
36
EntratiLabsEntratiLabVendorManifest,
38
MaskSalesmanManifest,
39
37
Nova1999ConquestShopManifest,
40
38
OstronPetVendorManifest,
41
39
SolarisDebtTokenVendorRepossessionsManifest
@@ -277,6 +275,7 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
277
275
278
276
// Add permanent offers
279
277
let numUncountedOffers = 0;
278
let numCountedOffers = 0;
280
279
let offset = 0;
281
280
for (const item of manifest.items) {
282
281
if (item.alwaysOffered || item.rotatedWeekly) {
@@ -287,11 +286,16 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
287
286
offersToAdd.push(item);
288
287
++offset;
289
288
}
289
} else {
290
numCountedOffers += 1 + item.duplicates;
290
291
}
291
292
}
292
293
293
294
// Add counted offers
294
const useRng = manifest.numItems && manifest.numItems.minValue != manifest.numItems.maxValue;
295
const useRng =
296
manifest.numItems &&
297
(manifest.numItems.minValue != manifest.numItems.maxValue ||
298
manifest.numItems.minValue != numCountedOffers);
295
299
const numItemsTarget = manifest.numItems
296
300
? numUncountedOffers +
297
301
(useRng
@@ -299,10 +303,13 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
299
303
: manifest.numItems.minValue)
300
304
: manifest.items.length;
301
305
let i = 0;
306
const rollableOffers = manifest.items.filter(x => x.probability !== undefined) as (Omit<
307
IVendorOffer,
308
"probability"
309
> & { probability: number })[];
302
310
while (info.ItemManifest.length + offersToAdd.length < numItemsTarget) {
303
const item = useRng ? rng.randomElement(manifest.items)! : manifest.items[i++];
311
const item = useRng ? rng.randomReward(rollableOffers)! : rollableOffers[i++];
304
312
if (
305
!item.alwaysOffered &&
306
313
remainingItemCapacity[getOfferId(item)] != 0 &&
307
314
(numOffersThatNeedToMatchABin == 0 || missingItemsPerBin[item.bin])
308
315
) {
@@ -313,7 +320,7 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
313
320
}
314
321
offersToAdd.splice(offset, 0, item);
315
322
}
316
if (i == manifest.items.length) {
323
if (i == rollableOffers.length) {
317
324
i = 0;
318
325
}
319
326
}
@@ -351,7 +358,7 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
351
358
}
352
359
};
353
360
if (rawItem.numRandomItemPrices) {
354
item.ItemPrices = [];
361
item.ItemPrices ??= [];
355
362
for (let i = 0; i != rawItem.numRandomItemPrices; ++i) {
356
363
let itemPrice: { type: string; count: IRange };
357
364
do {
@@ -391,11 +398,13 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
391
398
info.ItemManifest.push(item);
392
399
}
393
400
394
info.ItemManifest.sort((a, b) => {
395
const aBin = parseInt(a.Bin.substring(4));
396
const bBin = parseInt(b.Bin.substring(4));
397
return aBin == bBin ? 0 : aBin < bBin ? +1 : -1;
398
});
401
if (manifest.numItemsPerBin) {
402
info.ItemManifest.sort((a, b) => {
403
const aBin = parseInt(a.Bin.substring(4));
404
const bBin = parseInt(b.Bin.substring(4));
405
return aBin == bBin ? 0 : aBin < bBin ? +1 : -1;
406
});
407
}
399
408
400
409
// Update vendor expiry
401
410
let soonestOfferExpiry: number = Number.MAX_SAFE_INTEGER;
@@ -464,4 +473,20 @@ if (isDev) {
464
473
if (!temple.find(x => x.StoreItem == "/Lotus/StoreItems/Types/Items/MiscItems/Kuva")) {
465
474
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/TheHex/Temple1999VendorManifest`);
466
475
}
476
477
const nakak = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Ostron/MaskSalesmanManifest")!
478
.VendorInfo.ItemManifest;
479
if (
480
nakak.length != 10 ||
481
nakak[0].StoreItem != "/Lotus/StoreItems/Upgrades/Skins/Ostron/RevenantMask" ||
482
nakak[1].StoreItem != "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyThumper" ||
483
nakak[1].ItemPrices?.length != 4 ||
484
nakak[2].StoreItem != "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyThumperMedium" ||
485
nakak[2].ItemPrices?.length != 4 ||
486
nakak[3].StoreItem != "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyThumperLarge" ||
487
nakak[3].ItemPrices?.length != 4
488
// The remaining offers should be computed by weighted RNG.
489
) {
490
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Ostron/MaskSalesmanManifest`);
491
}
467
492
}
@@ -1,301 +0,0 @@
1
{
2
"VendorInfo": {
3
"_id": {
4
"$oid": "598a090d9a4a313746fd1f24"
5
},
6
"TypeName": "/Lotus/Types/Game/VendorManifests/Ostron/MaskSalesmanManifest",
7
"ItemManifest": [
8
{
9
"StoreItem": "/Lotus/StoreItems/Upgrades/Skins/Ostron/RevenantMask",
10
"ItemPrices": [
11
{
12
"ItemCount": 1,
13
"ItemType": "/Lotus/Types/Gameplay/Eidolon/Resources/CetusWispItem",
14
"ProductCategory": "MiscItems"
15
}
16
],
17
"Bin": "BIN_0",
18
"QuantityMultiplier": 1,
19
"Expiry": {
20
"$date": {
21
"$numberLong": "9999999000000"
22
}
23
},
24
"AllowMultipurchase": true,
25
"Id": {
26
"$oid": "63ed01ef4c37f93d0b797674"
27
}
28
},
29
{
30
"StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyThumper",
31
"ItemPrices": [
32
{
33
"ItemCount": 2,
34
"ItemType": "/Lotus/Types/Gameplay/Eidolon/Resources/CetusWispItem",
35
"ProductCategory": "MiscItems"
36
},
37
{
38
"ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/BothUncommonFishBPartItem",
39
"ItemCount": 10,
40
"ProductCategory": "MiscItems"
41
},
42
{
43
"ItemType": "/Lotus/Types/Gameplay/Eidolon/Resources/NistlebrushItem",
44
"ItemCount": 10,
45
"ProductCategory": "MiscItems"
46
},
47
{
48
"ItemType": "/Lotus/Types/Items/Gems/Eidolon/CommonOreAAlloyAItem",
49
"ItemCount": 32,
50
"ProductCategory": "MiscItems"
51
}
52
],
53
"Bin": "BIN_0",
54
"QuantityMultiplier": 1,
55
"Expiry": {
56
"$date": {
57
"$numberLong": "9999999000000"
58
}
59
},
60
"AllowMultipurchase": true,
61
"Id": {
62
"$oid": "63ed01ef4c37f93d0b797675"
63
}
64
},
65
{
66
"StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyThumperMedium",
67
"ItemPrices": [
68
{
69
"ItemCount": 4,
70
"ItemType": "/Lotus/Types/Gameplay/Eidolon/Resources/CetusWispItem",
71
"ProductCategory": "MiscItems"
72
},
73
{
74
"ItemType": "/Lotus/Types/Items/Gems/Eidolon/CommonGemBCutAItem",
75
"ItemCount": 24,
76
"ProductCategory": "MiscItems"
77
},
78
{
79
"ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/BothUncommonFishAPartItem",
80
"ItemCount": 18,
81
"ProductCategory": "MiscItems"
82
},
83
{
84
"ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/BothUncommonFishBPartItem",
85
"ItemCount": 27,
86
"ProductCategory": "MiscItems"
87
}
88
],
89
"Bin": "BIN_1",
90
"QuantityMultiplier": 1,
91
"Expiry": {
92
"$date": {
93
"$numberLong": "9999999000000"
94
}
95
},
96
"AllowMultipurchase": true,
97
"Id": {
98
"$oid": "63ed01ef4c37f93d0b797676"
99
}
100
},
101
{
102
"StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyThumperLarge",
103
"ItemPrices": [
104
{
105
"ItemCount": 6,
106
"ItemType": "/Lotus/Types/Gameplay/Eidolon/Resources/CetusWispItem",
107
"ProductCategory": "MiscItems"
108
},
109
{
110
"ItemType": "/Lotus/Types/Items/Gems/Eidolon/CommonGemACutAItem",
111
"ItemCount": 35,
112
"ProductCategory": "MiscItems"
113
},
114
{
115
"ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/BothCommonFishAPartItem",
116
"ItemCount": 95,
117
"ProductCategory": "MiscItems"
118
},
119
{
120
"ItemType": "/Lotus/Types/Gameplay/Eidolon/Resources/NistlebrushItem",
121
"ItemCount": 60,
122
"ProductCategory": "MiscItems"
123
}
124
],
125
"Bin": "BIN_0",
126
"QuantityMultiplier": 1,
127
"Expiry": {
128
"$date": {
129
"$numberLong": "9999999000000"
130
}
131
},
132
"AllowMultipurchase": true,
133
"Id": {
134
"$oid": "63ed01ef4c37f93d0b797677"
135
}
136
},
137
{
138
"StoreItem": "/Lotus/StoreItems/Types/Recipes/SynthicatorRecipes/FlareBlueBlueprint",
139
"ItemPrices": [
140
{
141
"ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/BothUncommonFishBPartItem",
142
"ItemCount": 10,
143
"ProductCategory": "MiscItems"
144
},
145
{
146
"ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/DayCommonFishCPartItem",
147
"ItemCount": 10,
148
"ProductCategory": "MiscItems"
149
}
150
],
151
"Bin": "BIN_0",
152
"QuantityMultiplier": 1,
153
"Expiry": {
154
"$date": {
155
"$numberLong": "9999999000000"
156
}
157
},
158
"AllowMultipurchase": true,
159
"Id": {
160
"$oid": "6651291214e90115b91b50a1"
161
}
162
},
163
{
164
"StoreItem": "/Lotus/StoreItems/Types/Recipes/SynthicatorRecipes/FlareRedBlueprint",
165
"ItemPrices": [
166
{
167
"ItemType": "/Lotus/Types/Items/Gems/Eidolon/CommonOreAAlloyAItem",
168
"ItemCount": 37,
169
"ProductCategory": "MiscItems"
170
},
171
{
172
"ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/BothUncommonFishAPartItem",
173
"ItemCount": 7,
174
"ProductCategory": "MiscItems"
175
}
176
],
177
"Bin": "BIN_0",
178
"QuantityMultiplier": 1,
179
"Expiry": {
180
"$date": {
181
"$numberLong": "9999999000000"
182
}
183
},
184
"AllowMultipurchase": true,
185
"Id": {
186
"$oid": "6651291214e90115b91b50a2"
187
}
188
},
189
{
190
"StoreItem": "/Lotus/StoreItems/Upgrades/Skins/Ostron/VoltMask",
191
"ItemPrices": [
192
{
193
"ItemType": "/Lotus/Types/Items/Gems/Eidolon/CommonOreBAlloyBItem",
194
"ItemCount": 34,
195
"ProductCategory": "MiscItems"
196
},
197
{
198
"ItemType": "/Lotus/Types/Gameplay/Eidolon/Resources/GrokdrulItem",
199
"ItemCount": 17,
200
"ProductCategory": "MiscItems"
201
}
202
],
203
"Bin": "BIN_0",
204
"QuantityMultiplier": 1,
205
"Expiry": {
206
"$date": {
207
"$numberLong": "9999999000000"
208
}
209
},
210
"AllowMultipurchase": true,
211
"Id": {
212
"$oid": "6651291214e90115b91b50a3"
213
}
214
},
215
{
216
"StoreItem": "/Lotus/StoreItems/Upgrades/Skins/Ostron/MagMask",
217
"ItemPrices": [
218
{
219
"ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/DayCommonFishBPartItem",
220
"ItemCount": 16,
221
"ProductCategory": "MiscItems"
222
},
223
{
224
"ItemType": "/Lotus/Types/Gameplay/Eidolon/Resources/ForestRodentPartItem",
225
"ItemCount": 5,
226
"ProductCategory": "MiscItems"
227
}
228
],
229
"Bin": "BIN_0",
230
"QuantityMultiplier": 1,
231
"Expiry": {
232
"$date": {
233
"$numberLong": "9999999000000"
234
}
235
},
236
"AllowMultipurchase": true,
237
"Id": {
238
"$oid": "6651291214e90115b91b50a4"
239
}
240
},
241
{
242
"StoreItem": "/Lotus/StoreItems/Upgrades/Skins/Ostron/ExcaliburMask",
243
"ItemPrices": [
244
{
245
"ItemType": "/Lotus/Types/Gameplay/Eidolon/Resources/BirdOfPreyPartItem",
246
"ItemCount": 5,
247
"ProductCategory": "MiscItems"
248
},
249
{
250
"ItemType": "/Lotus/Types/Gameplay/Eidolon/Resources/GrokdrulItem",
251
"ItemCount": 20,
252
"ProductCategory": "MiscItems"
253
}
254
],
255
"Bin": "BIN_0",
256
"QuantityMultiplier": 1,
257
"Expiry": {
258
"$date": {
259
"$numberLong": "9999999000000"
260
}
261
},
262
"AllowMultipurchase": true,
263
"Id": {
264
"$oid": "6651291214e90115b91b50a5"
265
}
266
},
267
{
268
"StoreItem": "/Lotus/StoreItems/Upgrades/Skins/Ostron/GrineerMask",
269
"ItemPrices": [
270
{
271
"ItemType": "/Lotus/Types/Items/Fish/Eidolon/FishParts/DayCommonFishBPartItem",
272
"ItemCount": 20,
273
"ProductCategory": "MiscItems"
274
},
275
{
276
"ItemType": "/Lotus/Types/Items/Gems/Eidolon/CommonOreAAlloyAItem",
277
"ItemCount": 31,
278
"ProductCategory": "MiscItems"
279
}
280
],
281
"Bin": "BIN_1",
282
"QuantityMultiplier": 1,
283
"Expiry": {
284
"$date": {
285
"$numberLong": "9999999000000"
286
}
287
},
288
"AllowMultipurchase": true,
289
"Id": {
290
"$oid": "6651291214e90115b91b50a6"
291
}
292
}
293
],
294
"PropertyTextHash": "6AACA376DA34B35B5C16F1B40DBC017D",
295
"Expiry": {
296
"$date": {
297
"$numberLong": "9999999000000"
298
}
299
}
300
}
301
}