chore: auto-generate palladino's vendor manifest
A bit ugly, but having the self test forces correctness.
This commit is contained in:
parent
8b27fcf459
commit
0a5b2c8358
@ -6,7 +6,7 @@ import { mixSeeds, SRng } from "@/src/services/rngService";
|
|||||||
import { IMongoDate } from "@/src/types/commonTypes";
|
import { IMongoDate } from "@/src/types/commonTypes";
|
||||||
import { IItemManifest, IVendorInfo, IVendorManifest } from "@/src/types/vendorTypes";
|
import { IItemManifest, IVendorInfo, IVendorManifest } from "@/src/types/vendorTypes";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { ExportVendors, IRange, IVendor } from "warframe-public-export-plus";
|
import { ExportVendors, IRange, IVendor, IVendorOffer } from "warframe-public-export-plus";
|
||||||
|
|
||||||
import ArchimedeanVendorManifest from "@/static/fixed_responses/getVendorInfo/ArchimedeanVendorManifest.json";
|
import ArchimedeanVendorManifest from "@/static/fixed_responses/getVendorInfo/ArchimedeanVendorManifest.json";
|
||||||
import DeimosEntratiFragmentVendorProductsManifest from "@/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json";
|
import DeimosEntratiFragmentVendorProductsManifest from "@/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json";
|
||||||
@ -21,7 +21,6 @@ import DeimosProspectorVendorManifest from "@/static/fixed_responses/getVendorIn
|
|||||||
import DuviriAcrithisVendorManifest from "@/static/fixed_responses/getVendorInfo/DuviriAcrithisVendorManifest.json";
|
import DuviriAcrithisVendorManifest from "@/static/fixed_responses/getVendorInfo/DuviriAcrithisVendorManifest.json";
|
||||||
import EntratiLabsEntratiLabsCommisionsManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabsCommisionsManifest.json";
|
import EntratiLabsEntratiLabsCommisionsManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabsCommisionsManifest.json";
|
||||||
import EntratiLabsEntratiLabVendorManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabVendorManifest.json";
|
import EntratiLabsEntratiLabVendorManifest from "@/static/fixed_responses/getVendorInfo/EntratiLabsEntratiLabVendorManifest.json";
|
||||||
import HubsIronwakeDondaVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsIronwakeDondaVendorManifest.json";
|
|
||||||
import HubsRailjackCrewMemberVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsRailjackCrewMemberVendorManifest.json";
|
import HubsRailjackCrewMemberVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsRailjackCrewMemberVendorManifest.json";
|
||||||
import MaskSalesmanManifest from "@/static/fixed_responses/getVendorInfo/MaskSalesmanManifest.json";
|
import MaskSalesmanManifest from "@/static/fixed_responses/getVendorInfo/MaskSalesmanManifest.json";
|
||||||
import Nova1999ConquestShopManifest from "@/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json";
|
import Nova1999ConquestShopManifest from "@/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json";
|
||||||
@ -47,7 +46,6 @@ const rawVendorManifests: IVendorManifest[] = [
|
|||||||
DuviriAcrithisVendorManifest,
|
DuviriAcrithisVendorManifest,
|
||||||
EntratiLabsEntratiLabsCommisionsManifest,
|
EntratiLabsEntratiLabsCommisionsManifest,
|
||||||
EntratiLabsEntratiLabVendorManifest,
|
EntratiLabsEntratiLabVendorManifest,
|
||||||
HubsIronwakeDondaVendorManifest, // uses preprocessing
|
|
||||||
HubsRailjackCrewMemberVendorManifest,
|
HubsRailjackCrewMemberVendorManifest,
|
||||||
MaskSalesmanManifest,
|
MaskSalesmanManifest,
|
||||||
Nova1999ConquestShopManifest,
|
Nova1999ConquestShopManifest,
|
||||||
@ -83,10 +81,6 @@ const generatableVendors: IGeneratableVendorInfo[] = [
|
|||||||
cycleOffset: 1744934400_000,
|
cycleOffset: 1744934400_000,
|
||||||
cycleDuration: 4 * unixTimesInMs.day
|
cycleDuration: 4 * unixTimesInMs.day
|
||||||
}
|
}
|
||||||
// {
|
|
||||||
// _id: { $oid: "5dbb4c41e966f7886c3ce939" },
|
|
||||||
// TypeName: "/Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest"
|
|
||||||
// }
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const getVendorOid = (typeName: string): string => {
|
const getVendorOid = (typeName: string): string => {
|
||||||
@ -261,13 +255,8 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
|
|||||||
const cycleIndex = Math.trunc((Date.now() - cycleOffset) / cycleDuration);
|
const cycleIndex = Math.trunc((Date.now() - cycleOffset) / cycleDuration);
|
||||||
const rng = new SRng(mixSeeds(vendorSeed, cycleIndex));
|
const rng = new SRng(mixSeeds(vendorSeed, cycleIndex));
|
||||||
const manifest = ExportVendors[vendorInfo.TypeName];
|
const manifest = ExportVendors[vendorInfo.TypeName];
|
||||||
const offersToAdd = [];
|
const offersToAdd: IVendorOffer[] = [];
|
||||||
if (
|
if (!manifest.isOneBinPerCycle) {
|
||||||
manifest.numItems &&
|
|
||||||
(manifest.numItems.minValue != manifest.numItems.maxValue ||
|
|
||||||
manifest.items.length != manifest.numItems.minValue) &&
|
|
||||||
!manifest.isOneBinPerCycle
|
|
||||||
) {
|
|
||||||
const remainingItemCapacity: Record<string, number> = {};
|
const remainingItemCapacity: Record<string, number> = {};
|
||||||
for (const item of manifest.items) {
|
for (const item of manifest.items) {
|
||||||
remainingItemCapacity[item.storeItem] = 1 + item.duplicates;
|
remainingItemCapacity[item.storeItem] = 1 + item.duplicates;
|
||||||
@ -275,31 +264,48 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
|
|||||||
for (const offer of info.ItemManifest) {
|
for (const offer of info.ItemManifest) {
|
||||||
remainingItemCapacity[offer.StoreItem] -= 1;
|
remainingItemCapacity[offer.StoreItem] -= 1;
|
||||||
}
|
}
|
||||||
const numItemsTarget = rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue);
|
if (manifest.numItems && manifest.items.length != manifest.numItems.minValue) {
|
||||||
while (info.ItemManifest.length + offersToAdd.length < numItemsTarget) {
|
const numItemsTarget = rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue);
|
||||||
// TODO: Consider per-bin item limits
|
while (info.ItemManifest.length + offersToAdd.length < numItemsTarget) {
|
||||||
// TODO: Consider item probability weightings
|
// TODO: Consider per-bin item limits
|
||||||
const item = rng.randomElement(manifest.items)!;
|
// TODO: Consider item probability weightings
|
||||||
if (remainingItemCapacity[item.storeItem] != 0) {
|
const item = rng.randomElement(manifest.items)!;
|
||||||
remainingItemCapacity[item.storeItem] -= 1;
|
if (remainingItemCapacity[item.storeItem] != 0) {
|
||||||
offersToAdd.push(item);
|
remainingItemCapacity[item.storeItem] -= 1;
|
||||||
|
offersToAdd.push(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (const item of manifest.items) {
|
||||||
|
if (!item.alwaysOffered && remainingItemCapacity[item.storeItem] != 0) {
|
||||||
|
remainingItemCapacity[item.storeItem] -= 1;
|
||||||
|
offersToAdd.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const e of Object.entries(remainingItemCapacity)) {
|
||||||
|
const item = manifest.items.find(x => x.storeItem == e[0])!;
|
||||||
|
if (!item.alwaysOffered) {
|
||||||
|
while (e[1] != 0) {
|
||||||
|
e[1] -= 1;
|
||||||
|
offersToAdd.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const item of manifest.items) {
|
||||||
|
if (item.alwaysOffered && remainingItemCapacity[item.storeItem] != 0) {
|
||||||
|
remainingItemCapacity[item.storeItem] -= 1;
|
||||||
|
offersToAdd.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offersToAdd.reverse();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let binThisCycle;
|
const binThisCycle = cycleIndex % 2; // Note: May want to auto-compute the bin size, but this is only used for coda weapons right now.
|
||||||
if (manifest.isOneBinPerCycle) {
|
|
||||||
binThisCycle = cycleIndex % 2; // Note: May want to auto-compute the bin size, but this is only used for coda weapons right now.
|
|
||||||
}
|
|
||||||
for (const rawItem of manifest.items) {
|
for (const rawItem of manifest.items) {
|
||||||
if (!manifest.isOneBinPerCycle || rawItem.bin == binThisCycle) {
|
if (rawItem.bin == binThisCycle) {
|
||||||
offersToAdd.push(rawItem);
|
offersToAdd.push(rawItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For most vendors, the offers seem to roughly be in reverse order from the manifest. Coda weapons are an odd exception.
|
|
||||||
if (!manifest.isOneBinPerCycle) {
|
|
||||||
offersToAdd.reverse();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const cycleStart = cycleOffset + cycleIndex * cycleDuration;
|
const cycleStart = cycleOffset + cycleIndex * cycleDuration;
|
||||||
for (const rawItem of offersToAdd) {
|
for (const rawItem of offersToAdd) {
|
||||||
@ -388,4 +394,17 @@ if (isDev) {
|
|||||||
) {
|
) {
|
||||||
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest`);
|
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pall = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest")!
|
||||||
|
.VendorInfo.ItemManifest;
|
||||||
|
if (
|
||||||
|
pall.length != 5 ||
|
||||||
|
pall[0].StoreItem != "/Lotus/StoreItems/Types/Items/ShipDecos/HarrowQuestKeyOrnament" ||
|
||||||
|
pall[1].StoreItem != "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack" ||
|
||||||
|
pall[2].StoreItem != "/Lotus/StoreItems/Types/StoreItems/CreditBundles/150000Credits" ||
|
||||||
|
pall[3].StoreItem != "/Lotus/StoreItems/Types/Items/MiscItems/Kuva" ||
|
||||||
|
pall[4].StoreItem != "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack"
|
||||||
|
) {
|
||||||
|
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
{
|
|
||||||
"VendorInfo": {
|
|
||||||
"_id": {
|
|
||||||
"$oid": "5dbb4c41e966f7886c3ce939"
|
|
||||||
},
|
|
||||||
"TypeName": "/Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest",
|
|
||||||
"ItemManifest": [
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/HarrowQuestKeyOrnament",
|
|
||||||
"ItemPrices": [
|
|
||||||
{
|
|
||||||
"ItemCount": 25,
|
|
||||||
"ItemType": "/Lotus/Types/Items/MiscItems/PrimeBucks",
|
|
||||||
"ProductCategory": "MiscItems"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 1,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "604800000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e945f"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack",
|
|
||||||
"ItemPrices": [
|
|
||||||
{
|
|
||||||
"ItemCount": 10,
|
|
||||||
"ItemType": "/Lotus/Types/Items/MiscItems/RivenFragment",
|
|
||||||
"ProductCategory": "MiscItems"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 1,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "604800000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"PurchaseQuantityLimit": 1,
|
|
||||||
"AllowMultipurchase": false,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e9468"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/StoreItems/CreditBundles/150000Credits",
|
|
||||||
"ItemPrices": [
|
|
||||||
{
|
|
||||||
"ItemCount": 5,
|
|
||||||
"ItemType": "/Lotus/Types/Items/MiscItems/RivenFragment",
|
|
||||||
"ProductCategory": "MiscItems"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 1,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "604800000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"PurchaseQuantityLimit": 1,
|
|
||||||
"AllowMultipurchase": false,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e9469"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Kuva",
|
|
||||||
"ItemPrices": [
|
|
||||||
{
|
|
||||||
"ItemCount": 10,
|
|
||||||
"ItemType": "/Lotus/Types/Items/MiscItems/RivenFragment",
|
|
||||||
"ProductCategory": "MiscItems"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 35000,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "604800000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"PurchaseQuantityLimit": 1,
|
|
||||||
"AllowMultipurchase": false,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e946a"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/RivenModPack",
|
|
||||||
"ItemPrices": [
|
|
||||||
{
|
|
||||||
"ItemCount": 10,
|
|
||||||
"ItemType": "/Lotus/Types/Items/MiscItems/RivenFragment",
|
|
||||||
"ProductCategory": "MiscItems"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 1,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "604800000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"PurchaseQuantityLimit": 1,
|
|
||||||
"AllowMultipurchase": false,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e946b"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"PropertyTextHash": "62B64A8065B7C0FA345895D4BC234621",
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "604800000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user