XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESpaceNinjaServer

chore: auto-generate palladino's vendor manifest (#2160)

A bit ugly, but having the self test forces correctness. Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2160 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>

30531124
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

2 个文件 +51 -157
Modified src/services/serversideVendorsService.ts +51 -32
@@ -6,7 +6,7 @@ import { mixSeeds, SRng } from "@/src/services/rngService";
6 6 import { IMongoDate } from "@/src/types/commonTypes";
7 7 import { IItemManifest, IVendorInfo, IVendorManifest } from "@/src/types/vendorTypes";
8 8 import { logger } from "@/src/utils/logger";
9 import { ExportVendors, IRange, IVendor } from "warframe-public-export-plus";
9 import { ExportVendors, IRange, IVendor, IVendorOffer } from "warframe-public-export-plus";
10 10
11 11 import ArchimedeanVendorManifest from "@/static/fixed_responses/getVendorInfo/ArchimedeanVendorManifest.json";
12 12 import DeimosEntratiFragmentVendorProductsManifest from "@/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json";
@@ -21,7 +21,6 @@ import DeimosProspectorVendorManifest from "@/static/fixed_responses/getVendorIn
21 21 import DuviriAcrithisVendorManifest from "@/static/fixed_responses/getVendorInfo/DuviriAcrithisVendorManifest.json";
22 22 import EntratiLabsEntratiLabsCommisionsManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabsCommisionsManifest.json";
23 23 import EntratiLabsEntratiLabVendorManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabVendorManifest.json";
24 import HubsIronwakeDondaVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsIronwakeDondaVendorManifest.json";
25 24 import HubsRailjackCrewMemberVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsRailjackCrewMemberVendorManifest.json";
26 25 import MaskSalesmanManifest from "@/static/fixed_responses/getVendorInfo/MaskSalesmanManifest.json";
27 26 import Nova1999ConquestShopManifest from "@/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json";
@@ -47,7 +46,6 @@ const rawVendorManifests: IVendorManifest[] = [
47 46 DuviriAcrithisVendorManifest,
48 47 EntratiLabsEntratiLabsCommisionsManifest,
49 48 EntratiLabsEntratiLabVendorManifest,
50 HubsIronwakeDondaVendorManifest, // uses preprocessing
51 49 HubsRailjackCrewMemberVendorManifest,
52 50 MaskSalesmanManifest,
53 51 Nova1999ConquestShopManifest,
@@ -83,10 +81,6 @@ const generatableVendors: IGeneratableVendorInfo[] = [
83 81 cycleOffset: 1744934400_000,
84 82 cycleDuration: 4 * unixTimesInMs.day
85 83 }
86 // {
87 // _id: { $oid: "5dbb4c41e966f7886c3ce939" },
88 // TypeName: "/Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest"
89 // }
90 84 ];
91 85
92 86 const getVendorOid = (typeName: string): string => {
@@ -261,13 +255,8 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
261 255 const cycleIndex = Math.trunc((Date.now() - cycleOffset) / cycleDuration);
262 256 const rng = new SRng(mixSeeds(vendorSeed, cycleIndex));
263 257 const manifest = ExportVendors[vendorInfo.TypeName];
264 const offersToAdd = [];
265 if (
266 manifest.numItems &&
267 (manifest.numItems.minValue != manifest.numItems.maxValue ||
268 manifest.items.length != manifest.numItems.minValue) &&
269 !manifest.isOneBinPerCycle
270 ) {
258 const offersToAdd: IVendorOffer[] = [];
259 if (!manifest.isOneBinPerCycle) {
271 260 const remainingItemCapacity: Record<string, number> = {};
272 261 for (const item of manifest.items) {
273 262 remainingItemCapacity[item.storeItem] = 1 + item.duplicates;
@@ -275,31 +264,48 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
275 264 for (const offer of info.ItemManifest) {
276 265 remainingItemCapacity[offer.StoreItem] -= 1;
277 266 }
278 const numItemsTarget = rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue);
279 while (info.ItemManifest.length + offersToAdd.length < numItemsTarget) {
280 // TODO: Consider per-bin item limits
281 // TODO: Consider item probability weightings
282 const item = rng.randomElement(manifest.items)!;
283 if (remainingItemCapacity[item.storeItem] != 0) {
284 remainingItemCapacity[item.storeItem] -= 1;
285 offersToAdd.push(item);
267 if (manifest.numItems && manifest.items.length != manifest.numItems.minValue) {
268 const numItemsTarget = rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue);
269 while (info.ItemManifest.length + offersToAdd.length < numItemsTarget) {
270 // TODO: Consider per-bin item limits
271 // TODO: Consider item probability weightings
272 const item = rng.randomElement(manifest.items)!;
273 if (remainingItemCapacity[item.storeItem] != 0) {
274 remainingItemCapacity[item.storeItem] -= 1;
275 offersToAdd.push(item);
276 }
277 }
278 } else {
279 for (const item of manifest.items) {
280 if (!item.alwaysOffered && remainingItemCapacity[item.storeItem] != 0) {
281 remainingItemCapacity[item.storeItem] -= 1;
282 offersToAdd.push(item);
283 }
284 }
285 for (const e of Object.entries(remainingItemCapacity)) {
286 const item = manifest.items.find(x => x.storeItem == e[0])!;
287 if (!item.alwaysOffered) {
288 while (e[1] != 0) {
289 e[1] -= 1;
290 offersToAdd.push(item);
291 }
292 }
286 293 }
294 for (const item of manifest.items) {
295 if (item.alwaysOffered && remainingItemCapacity[item.storeItem] != 0) {
296 remainingItemCapacity[item.storeItem] -= 1;
297 offersToAdd.push(item);
298 }
299 }
300 offersToAdd.reverse();
287 301 }
288 302 } else {
289 let binThisCycle;
290 if (manifest.isOneBinPerCycle) {
291 binThisCycle = cycleIndex % 2; // Note: May want to auto-compute the bin size, but this is only used for coda weapons right now.
292 }
303 const binThisCycle = cycleIndex % 2; // Note: May want to auto-compute the bin size, but this is only used for coda weapons right now.
293 304 for (const rawItem of manifest.items) {
294 if (!manifest.isOneBinPerCycle || rawItem.bin == binThisCycle) {
305 if (rawItem.bin == binThisCycle) {
295 306 offersToAdd.push(rawItem);
296 307 }
297 308 }
298
299 // For most vendors, the offers seem to roughly be in reverse order from the manifest. Coda weapons are an odd exception.
300 if (!manifest.isOneBinPerCycle) {
301 offersToAdd.reverse();
302 }
303 309 }
304 310 const cycleStart = cycleOffset + cycleIndex * cycleDuration;
305 311 for (const rawItem of offersToAdd) {
@@ -388,4 +394,17 @@ if (isDev) {
388 394 ) {
389 395 logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest`);
390 396 }
397
398 const pall = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest")!
399 .VendorInfo.ItemManifest;
400 if (
401 pall.length != 5 ||
402 pall[0].StoreItem != "/Lotus/StoreItems/Types/Items/ShipDecos/HarrowQuestKeyOrnament" ||
403 pall[1].StoreItem != "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack" ||
404 pall[2].StoreItem != "/Lotus/StoreItems/Types/StoreItems/CreditBundles/150000Credits" ||
405 pall[3].StoreItem != "/Lotus/StoreItems/Types/Items/MiscItems/Kuva" ||
406 pall[4].StoreItem != "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack"
407 ) {
408 logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest`);
409 }
391 410 }
Deleted static/fixed_responses/getVendorInfo/HubsIronwakeDondaVendorManifest.json +0 -125
@@ -1,125 +0,0 @@
1 {
2 "VendorInfo": {
3 "_id": {
4 "$oid": "5dbb4c41e966f7886c3ce939"
5 },
6 "TypeName": "/Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest",
7 "ItemManifest": [
8 {
9 "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/HarrowQuestKeyOrnament",
10 "ItemPrices": [
11 {
12 "ItemCount": 25,
13 "ItemType": "/Lotus/Types/Items/MiscItems/PrimeBucks",
14 "ProductCategory": "MiscItems"
15 }
16 ],
17 "Bin": "BIN_0",
18 "QuantityMultiplier": 1,
19 "Expiry": {
20 "$date": {
21 "$numberLong": "604800000"
22 }
23 },
24 "AllowMultipurchase": true,
25 "Id": {
26 "$oid": "66fd60b20ba592c4c95e945f"
27 }
28 },
29 {
30 "StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack",
31 "ItemPrices": [
32 {
33 "ItemCount": 10,
34 "ItemType": "/Lotus/Types/Items/MiscItems/RivenFragment",
35 "ProductCategory": "MiscItems"
36 }
37 ],
38 "Bin": "BIN_0",
39 "QuantityMultiplier": 1,
40 "Expiry": {
41 "$date": {
42 "$numberLong": "604800000"
43 }
44 },
45 "PurchaseQuantityLimit": 1,
46 "AllowMultipurchase": false,
47 "Id": {
48 "$oid": "66fd60b20ba592c4c95e9468"
49 }
50 },
51 {
52 "StoreItem": "/Lotus/StoreItems/Types/StoreItems/CreditBundles/150000Credits",
53 "ItemPrices": [
54 {
55 "ItemCount": 5,
56 "ItemType": "/Lotus/Types/Items/MiscItems/RivenFragment",
57 "ProductCategory": "MiscItems"
58 }
59 ],
60 "Bin": "BIN_0",
61 "QuantityMultiplier": 1,
62 "Expiry": {
63 "$date": {
64 "$numberLong": "604800000"
65 }
66 },
67 "PurchaseQuantityLimit": 1,
68 "AllowMultipurchase": false,
69 "Id": {
70 "$oid": "66fd60b20ba592c4c95e9469"
71 }
72 },
73 {
74 "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Kuva",
75 "ItemPrices": [
76 {
77 "ItemCount": 10,
78 "ItemType": "/Lotus/Types/Items/MiscItems/RivenFragment",
79 "ProductCategory": "MiscItems"
80 }
81 ],
82 "Bin": "BIN_0",
83 "QuantityMultiplier": 35000,
84 "Expiry": {
85 "$date": {
86 "$numberLong": "604800000"
87 }
88 },
89 "PurchaseQuantityLimit": 1,
90 "AllowMultipurchase": false,
91 "Id": {
92 "$oid": "66fd60b20ba592c4c95e946a"
93 }
94 },
95 {
96 "StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack",
97 "ItemPrices": [
98 {
99 "ItemCount": 10,
100 "ItemType": "/Lotus/Types/Items/MiscItems/RivenFragment",
101 "ProductCategory": "MiscItems"
102 }
103 ],
104 "Bin": "BIN_0",
105 "QuantityMultiplier": 1,
106 "Expiry": {
107 "$date": {
108 "$numberLong": "604800000"
109 }
110 },
111 "PurchaseQuantityLimit": 1,
112 "AllowMultipurchase": false,
113 "Id": {
114 "$oid": "66fd60b20ba592c4c95e946b"
115 }
116 }
117 ],
118 "PropertyTextHash": "62B64A8065B7C0FA345895D4BC234621",
119 "Expiry": {
120 "$date": {
121 "$numberLong": "604800000"
122 }
123 }
124 }
125 }