feat: fullyStockedVendors cheat (#2246)
Reviewed-on: #2246 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
parent
7ca7147b78
commit
84f081312b
@ -41,6 +41,7 @@
|
|||||||
"noVendorPurchaseLimits": false,
|
"noVendorPurchaseLimits": false,
|
||||||
"noDeathMarks": false,
|
"noDeathMarks": false,
|
||||||
"noKimCooldowns": false,
|
"noKimCooldowns": false,
|
||||||
|
"fullyStockedVendors": false,
|
||||||
"syndicateMissionsRepeatable": false,
|
"syndicateMissionsRepeatable": false,
|
||||||
"unlockAllProfitTakerStages": false,
|
"unlockAllProfitTakerStages": false,
|
||||||
"instantFinishRivenChallenge": false,
|
"instantFinishRivenChallenge": false,
|
||||||
|
@ -48,6 +48,7 @@ export interface IConfig {
|
|||||||
noVendorPurchaseLimits?: boolean;
|
noVendorPurchaseLimits?: boolean;
|
||||||
noDeathMarks?: boolean;
|
noDeathMarks?: boolean;
|
||||||
noKimCooldowns?: boolean;
|
noKimCooldowns?: boolean;
|
||||||
|
fullyStockedVendors?: boolean;
|
||||||
syndicateMissionsRepeatable?: boolean;
|
syndicateMissionsRepeatable?: boolean;
|
||||||
unlockAllProfitTakerStages?: boolean;
|
unlockAllProfitTakerStages?: boolean;
|
||||||
instantFinishRivenChallenge?: boolean;
|
instantFinishRivenChallenge?: boolean;
|
||||||
|
@ -6,6 +6,7 @@ import { mixSeeds, SRng } from "@/src/services/rngService";
|
|||||||
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, IVendorOffer } from "warframe-public-export-plus";
|
import { ExportVendors, IRange, IVendor, IVendorOffer } from "warframe-public-export-plus";
|
||||||
|
import { config } from "./configService";
|
||||||
|
|
||||||
interface IGeneratableVendorInfo extends Omit<IVendorInfo, "ItemManifest" | "Expiry"> {
|
interface IGeneratableVendorInfo extends Omit<IVendorInfo, "ItemManifest" | "Expiry"> {
|
||||||
cycleOffset?: number;
|
cycleOffset?: number;
|
||||||
@ -59,20 +60,23 @@ const getCycleDuration = (manifest: IVendor): number => {
|
|||||||
return dur * unixTimesInMs.hour;
|
return dur * unixTimesInMs.hour;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getVendorManifestByTypeName = (typeName: string): IVendorManifest | undefined => {
|
export const getVendorManifestByTypeName = (typeName: string, fullStock?: boolean): IVendorManifest | undefined => {
|
||||||
for (const vendorInfo of generatableVendors) {
|
for (const vendorInfo of generatableVendors) {
|
||||||
if (vendorInfo.TypeName == typeName) {
|
if (vendorInfo.TypeName == typeName) {
|
||||||
return generateVendorManifest(vendorInfo);
|
return generateVendorManifest(vendorInfo, fullStock ?? config.fullyStockedVendors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typeName in ExportVendors) {
|
if (typeName in ExportVendors) {
|
||||||
const manifest = ExportVendors[typeName];
|
const manifest = ExportVendors[typeName];
|
||||||
return generateVendorManifest({
|
return generateVendorManifest(
|
||||||
_id: { $oid: getVendorOid(typeName) },
|
{
|
||||||
TypeName: typeName,
|
_id: { $oid: getVendorOid(typeName) },
|
||||||
RandomSeedType: manifest.randomSeedType,
|
TypeName: typeName,
|
||||||
cycleDuration: getCycleDuration(manifest)
|
RandomSeedType: manifest.randomSeedType,
|
||||||
});
|
cycleDuration: getCycleDuration(manifest)
|
||||||
|
},
|
||||||
|
fullStock ?? config.fullyStockedVendors
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
@ -80,18 +84,21 @@ export const getVendorManifestByTypeName = (typeName: string): IVendorManifest |
|
|||||||
export const getVendorManifestByOid = (oid: string): IVendorManifest | undefined => {
|
export const getVendorManifestByOid = (oid: string): IVendorManifest | undefined => {
|
||||||
for (const vendorInfo of generatableVendors) {
|
for (const vendorInfo of generatableVendors) {
|
||||||
if (vendorInfo._id.$oid == oid) {
|
if (vendorInfo._id.$oid == oid) {
|
||||||
return generateVendorManifest(vendorInfo);
|
return generateVendorManifest(vendorInfo, config.fullyStockedVendors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const [typeName, manifest] of Object.entries(ExportVendors)) {
|
for (const [typeName, manifest] of Object.entries(ExportVendors)) {
|
||||||
const typeNameOid = getVendorOid(typeName);
|
const typeNameOid = getVendorOid(typeName);
|
||||||
if (typeNameOid == oid) {
|
if (typeNameOid == oid) {
|
||||||
return generateVendorManifest({
|
return generateVendorManifest(
|
||||||
_id: { $oid: typeNameOid },
|
{
|
||||||
TypeName: typeName,
|
_id: { $oid: typeNameOid },
|
||||||
RandomSeedType: manifest.randomSeedType,
|
TypeName: typeName,
|
||||||
cycleDuration: getCycleDuration(manifest)
|
RandomSeedType: manifest.randomSeedType,
|
||||||
});
|
cycleDuration: getCycleDuration(manifest)
|
||||||
|
},
|
||||||
|
config.fullyStockedVendors
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -169,9 +176,26 @@ const getOfferId = (offer: IVendorOffer | IItemManifest): TOfferId => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let vendorManifestsUsingFullStock = false;
|
||||||
const vendorManifestCache: Record<string, IVendorManifest> = {};
|
const vendorManifestCache: Record<string, IVendorManifest> = {};
|
||||||
|
|
||||||
const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorManifest => {
|
const clearVendorCache = (): void => {
|
||||||
|
for (const k of Object.keys(vendorManifestCache)) {
|
||||||
|
delete vendorManifestCache[k];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const generateVendorManifest = (
|
||||||
|
vendorInfo: IGeneratableVendorInfo,
|
||||||
|
fullStock: boolean | undefined
|
||||||
|
): IVendorManifest => {
|
||||||
|
fullStock ??= config.fullyStockedVendors;
|
||||||
|
fullStock ??= false;
|
||||||
|
if (vendorManifestsUsingFullStock != fullStock) {
|
||||||
|
vendorManifestsUsingFullStock = fullStock;
|
||||||
|
clearVendorCache();
|
||||||
|
}
|
||||||
|
|
||||||
if (!(vendorInfo.TypeName in vendorManifestCache)) {
|
if (!(vendorInfo.TypeName in vendorManifestCache)) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { cycleOffset, cycleDuration, ...clientVendorInfo } = vendorInfo;
|
const { cycleOffset, cycleDuration, ...clientVendorInfo } = vendorInfo;
|
||||||
@ -208,7 +232,20 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
|
|||||||
const cycleIndex = Math.trunc((now - cycleOffset) / cycleDuration);
|
const cycleIndex = Math.trunc((now - cycleOffset) / cycleDuration);
|
||||||
const rng = new SRng(mixSeeds(vendorSeed, cycleIndex));
|
const rng = new SRng(mixSeeds(vendorSeed, cycleIndex));
|
||||||
const offersToAdd: IVendorOffer[] = [];
|
const offersToAdd: IVendorOffer[] = [];
|
||||||
if (!manifest.isOneBinPerCycle) {
|
if (manifest.isOneBinPerCycle) {
|
||||||
|
if (fullStock) {
|
||||||
|
for (const rawItem of manifest.items) {
|
||||||
|
offersToAdd.push(rawItem);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const binThisCycle = cycleIndex % 2; // Note: May want to check the actual number of bins, but this is only used for coda weapons right now.
|
||||||
|
for (const rawItem of manifest.items) {
|
||||||
|
if (rawItem.bin == binThisCycle) {
|
||||||
|
offersToAdd.push(rawItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Compute vendor requirements, subtracting existing offers
|
// Compute vendor requirements, subtracting existing offers
|
||||||
const remainingItemCapacity: Record<TOfferId, number> = {};
|
const remainingItemCapacity: Record<TOfferId, number> = {};
|
||||||
const missingItemsPerBin: Record<number, number> = {};
|
const missingItemsPerBin: Record<number, number> = {};
|
||||||
@ -254,12 +291,14 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
|
|||||||
manifest.numItems &&
|
manifest.numItems &&
|
||||||
(manifest.numItems.minValue != manifest.numItems.maxValue ||
|
(manifest.numItems.minValue != manifest.numItems.maxValue ||
|
||||||
manifest.numItems.minValue != numCountedOffers);
|
manifest.numItems.minValue != numCountedOffers);
|
||||||
const numItemsTarget = manifest.numItems
|
const numItemsTarget = fullStock
|
||||||
? numUncountedOffers +
|
? numUncountedOffers + numCountedOffers
|
||||||
(useRng
|
: manifest.numItems
|
||||||
? rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue)
|
? numUncountedOffers +
|
||||||
: manifest.numItems.minValue)
|
(useRng
|
||||||
: manifest.items.length;
|
? rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue)
|
||||||
|
: manifest.numItems.minValue)
|
||||||
|
: manifest.items.length;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
const rollableOffers = manifest.items.filter(x => x.probability !== undefined) as (Omit<
|
const rollableOffers = manifest.items.filter(x => x.probability !== undefined) as (Omit<
|
||||||
IVendorOffer,
|
IVendorOffer,
|
||||||
@ -282,13 +321,6 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
|
|||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
const 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) {
|
|
||||||
if (rawItem.bin == binThisCycle) {
|
|
||||||
offersToAdd.push(rawItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const cycleStart = cycleOffset + cycleIndex * cycleDuration;
|
const cycleStart = cycleOffset + cycleIndex * cycleDuration;
|
||||||
for (const rawItem of offersToAdd) {
|
for (const rawItem of offersToAdd) {
|
||||||
@ -387,34 +419,44 @@ if (args.dev) {
|
|||||||
logger.warn(`getCycleDuration self test failed`);
|
logger.warn(`getCycleDuration self test failed`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ads = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest")!
|
for (let i = 0; i != 2; ++i) {
|
||||||
.VendorInfo.ItemManifest;
|
const fullStock = !!i;
|
||||||
if (
|
|
||||||
ads.length != 5 ||
|
const ads = getVendorManifestByTypeName(
|
||||||
ads[0].Bin != "BIN_4" ||
|
"/Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest",
|
||||||
ads[1].Bin != "BIN_3" ||
|
fullStock
|
||||||
ads[2].Bin != "BIN_2" ||
|
)!.VendorInfo.ItemManifest;
|
||||||
ads[3].Bin != "BIN_1" ||
|
if (
|
||||||
ads[4].Bin != "BIN_0"
|
ads.length != 5 ||
|
||||||
) {
|
ads[0].Bin != "BIN_4" ||
|
||||||
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest`);
|
ads[1].Bin != "BIN_3" ||
|
||||||
|
ads[2].Bin != "BIN_2" ||
|
||||||
|
ads[3].Bin != "BIN_1" ||
|
||||||
|
ads[4].Bin != "BIN_0"
|
||||||
|
) {
|
||||||
|
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pall = getVendorManifestByTypeName(
|
||||||
|
"/Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest",
|
||||||
|
fullStock
|
||||||
|
)!.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`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const pall = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Hubs/IronwakeDondaVendorManifest")!
|
const cms = getVendorManifestByTypeName(
|
||||||
.VendorInfo.ItemManifest;
|
"/Lotus/Types/Game/VendorManifests/Hubs/RailjackCrewMemberVendorManifest",
|
||||||
if (
|
false
|
||||||
pall.length != 5 ||
|
)!.VendorInfo.ItemManifest;
|
||||||
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`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const cms = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Hubs/RailjackCrewMemberVendorManifest")!
|
|
||||||
.VendorInfo.ItemManifest;
|
|
||||||
if (
|
if (
|
||||||
cms.length != 9 ||
|
cms.length != 9 ||
|
||||||
cms[0].Bin != "BIN_2" ||
|
cms[0].Bin != "BIN_2" ||
|
||||||
@ -426,13 +468,15 @@ if (args.dev) {
|
|||||||
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/RailjackCrewMemberVendorManifest`);
|
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Hubs/RailjackCrewMemberVendorManifest`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const temple = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/TheHex/Temple1999VendorManifest")!
|
const temple = getVendorManifestByTypeName(
|
||||||
.VendorInfo.ItemManifest;
|
"/Lotus/Types/Game/VendorManifests/TheHex/Temple1999VendorManifest",
|
||||||
|
false
|
||||||
|
)!.VendorInfo.ItemManifest;
|
||||||
if (!temple.find(x => x.StoreItem == "/Lotus/StoreItems/Types/Items/MiscItems/Kuva")) {
|
if (!temple.find(x => x.StoreItem == "/Lotus/StoreItems/Types/Items/MiscItems/Kuva")) {
|
||||||
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/TheHex/Temple1999VendorManifest`);
|
logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/TheHex/Temple1999VendorManifest`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const nakak = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Ostron/MaskSalesmanManifest")!
|
const nakak = getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Ostron/MaskSalesmanManifest", false)!
|
||||||
.VendorInfo.ItemManifest;
|
.VendorInfo.ItemManifest;
|
||||||
if (
|
if (
|
||||||
nakak.length != 10 ||
|
nakak.length != 10 ||
|
||||||
|
@ -700,6 +700,10 @@
|
|||||||
<input class="form-check-input" type="checkbox" id="noKimCooldowns" />
|
<input class="form-check-input" type="checkbox" id="noKimCooldowns" />
|
||||||
<label class="form-check-label" for="noKimCooldowns" data-loc="cheats_noKimCooldowns"></label>
|
<label class="form-check-label" for="noKimCooldowns" data-loc="cheats_noKimCooldowns"></label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="fullyStockedVendors" />
|
||||||
|
<label class="form-check-label" for="fullyStockedVendors" data-loc="cheats_fullyStockedVendors"></label>
|
||||||
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox" id="syndicateMissionsRepeatable" />
|
<input class="form-check-input" type="checkbox" id="syndicateMissionsRepeatable" />
|
||||||
<label class="form-check-label" for="syndicateMissionsRepeatable" data-loc="cheats_syndicateMissionsRepeatable"></label>
|
<label class="form-check-label" for="syndicateMissionsRepeatable" data-loc="cheats_syndicateMissionsRepeatable"></label>
|
||||||
|
@ -158,6 +158,7 @@ dict = {
|
|||||||
cheats_noVendorPurchaseLimits: `Keine Kaufbeschränkungen bei Händlern`,
|
cheats_noVendorPurchaseLimits: `Keine Kaufbeschränkungen bei Händlern`,
|
||||||
cheats_noDeathMarks: `Keine Todesmarkierungen`,
|
cheats_noDeathMarks: `Keine Todesmarkierungen`,
|
||||||
cheats_noKimCooldowns: `Keine Wartezeit bei KIM`,
|
cheats_noKimCooldowns: `Keine Wartezeit bei KIM`,
|
||||||
|
cheats_fullyStockedVendors: `[UNTRANSLATED] Fully Stocked Vendors`,
|
||||||
cheats_syndicateMissionsRepeatable: `Syndikat-Missionen wiederholbar`,
|
cheats_syndicateMissionsRepeatable: `Syndikat-Missionen wiederholbar`,
|
||||||
cheats_unlockAllProfitTakerStages: `[UNTRANSLATED] Unlock All Profit Taker Stages`,
|
cheats_unlockAllProfitTakerStages: `[UNTRANSLATED] Unlock All Profit Taker Stages`,
|
||||||
cheats_instantFinishRivenChallenge: `Riven-Mod Herausforderung sofort abschließen`,
|
cheats_instantFinishRivenChallenge: `Riven-Mod Herausforderung sofort abschließen`,
|
||||||
|
@ -157,6 +157,7 @@ dict = {
|
|||||||
cheats_noVendorPurchaseLimits: `No Vendor Purchase Limits`,
|
cheats_noVendorPurchaseLimits: `No Vendor Purchase Limits`,
|
||||||
cheats_noDeathMarks: `No Death Marks`,
|
cheats_noDeathMarks: `No Death Marks`,
|
||||||
cheats_noKimCooldowns: `No KIM Cooldowns`,
|
cheats_noKimCooldowns: `No KIM Cooldowns`,
|
||||||
|
cheats_fullyStockedVendors: `Fully Stocked Vendors`,
|
||||||
cheats_syndicateMissionsRepeatable: `Syndicate Missions Repeatable`,
|
cheats_syndicateMissionsRepeatable: `Syndicate Missions Repeatable`,
|
||||||
cheats_unlockAllProfitTakerStages: `Unlock All Profit Taker Stages`,
|
cheats_unlockAllProfitTakerStages: `Unlock All Profit Taker Stages`,
|
||||||
cheats_instantFinishRivenChallenge: `Instant Finish Riven Challenge`,
|
cheats_instantFinishRivenChallenge: `Instant Finish Riven Challenge`,
|
||||||
|
@ -158,6 +158,7 @@ dict = {
|
|||||||
cheats_noVendorPurchaseLimits: `Sin límite de compras de vendedores`,
|
cheats_noVendorPurchaseLimits: `Sin límite de compras de vendedores`,
|
||||||
cheats_noDeathMarks: `Sin marcas de muerte`,
|
cheats_noDeathMarks: `Sin marcas de muerte`,
|
||||||
cheats_noKimCooldowns: `Sin tiempo de espera para conversaciones KIM`,
|
cheats_noKimCooldowns: `Sin tiempo de espera para conversaciones KIM`,
|
||||||
|
cheats_fullyStockedVendors: `[UNTRANSLATED] Fully Stocked Vendors`,
|
||||||
cheats_syndicateMissionsRepeatable: `Misiones de sindicato rejugables`,
|
cheats_syndicateMissionsRepeatable: `Misiones de sindicato rejugables`,
|
||||||
cheats_unlockAllProfitTakerStages: `Deslobquea todas las etapas del Roba-ganancias`,
|
cheats_unlockAllProfitTakerStages: `Deslobquea todas las etapas del Roba-ganancias`,
|
||||||
cheats_instantFinishRivenChallenge: `Terminar desafío de agrietado inmediatamente`,
|
cheats_instantFinishRivenChallenge: `Terminar desafío de agrietado inmediatamente`,
|
||||||
|
@ -158,6 +158,7 @@ dict = {
|
|||||||
cheats_noVendorPurchaseLimits: `Aucune limite d'achat chez les PNJ`,
|
cheats_noVendorPurchaseLimits: `Aucune limite d'achat chez les PNJ`,
|
||||||
cheats_noDeathMarks: `Aucune marque d'assassin`,
|
cheats_noDeathMarks: `Aucune marque d'assassin`,
|
||||||
cheats_noKimCooldowns: `Aucun cooldown sur le KIM`,
|
cheats_noKimCooldowns: `Aucun cooldown sur le KIM`,
|
||||||
|
cheats_fullyStockedVendors: `[UNTRANSLATED] Fully Stocked Vendors`,
|
||||||
cheats_syndicateMissionsRepeatable: `Mission syndicat répétables`,
|
cheats_syndicateMissionsRepeatable: `Mission syndicat répétables`,
|
||||||
cheats_unlockAllProfitTakerStages: `[UNTRANSLATED] Unlock All Profit Taker Stages`,
|
cheats_unlockAllProfitTakerStages: `[UNTRANSLATED] Unlock All Profit Taker Stages`,
|
||||||
cheats_instantFinishRivenChallenge: `Débloquer le challenge Riven instantanément`,
|
cheats_instantFinishRivenChallenge: `Débloquer le challenge Riven instantanément`,
|
||||||
|
@ -158,6 +158,7 @@ dict = {
|
|||||||
cheats_noVendorPurchaseLimits: `Отсутствие лимитов на покупки у вендоров`,
|
cheats_noVendorPurchaseLimits: `Отсутствие лимитов на покупки у вендоров`,
|
||||||
cheats_noDeathMarks: `Без меток сметри`,
|
cheats_noDeathMarks: `Без меток сметри`,
|
||||||
cheats_noKimCooldowns: `Чаты KIM без кулдауна`,
|
cheats_noKimCooldowns: `Чаты KIM без кулдауна`,
|
||||||
|
cheats_fullyStockedVendors: `[UNTRANSLATED] Fully Stocked Vendors`,
|
||||||
cheats_syndicateMissionsRepeatable: `[UNTRANSLATED] Syndicate Missions Repeatable`,
|
cheats_syndicateMissionsRepeatable: `[UNTRANSLATED] Syndicate Missions Repeatable`,
|
||||||
cheats_unlockAllProfitTakerStages: `[UNTRANSLATED] Unlock All Profit Taker Stages`,
|
cheats_unlockAllProfitTakerStages: `[UNTRANSLATED] Unlock All Profit Taker Stages`,
|
||||||
cheats_instantFinishRivenChallenge: `[UNTRANSLATED] Instant Finish Riven Challenge`,
|
cheats_instantFinishRivenChallenge: `[UNTRANSLATED] Instant Finish Riven Challenge`,
|
||||||
|
@ -158,6 +158,7 @@ dict = {
|
|||||||
cheats_noVendorPurchaseLimits: `商城或商人无购买限制`,
|
cheats_noVendorPurchaseLimits: `商城或商人无购买限制`,
|
||||||
cheats_noDeathMarks: `无死亡标记(不会被 Stalker/Grustrag 三霸/Zanuka 猎人等标记)`,
|
cheats_noDeathMarks: `无死亡标记(不会被 Stalker/Grustrag 三霸/Zanuka 猎人等标记)`,
|
||||||
cheats_noKimCooldowns: `无 KIM 冷却时间`,
|
cheats_noKimCooldowns: `无 KIM 冷却时间`,
|
||||||
|
cheats_fullyStockedVendors: `[UNTRANSLATED] Fully Stocked Vendors`,
|
||||||
cheats_syndicateMissionsRepeatable: `集团任务可重复`,
|
cheats_syndicateMissionsRepeatable: `集团任务可重复`,
|
||||||
cheats_unlockAllProfitTakerStages: `解锁利润收割者圆蛛所有阶段`,
|
cheats_unlockAllProfitTakerStages: `解锁利润收割者圆蛛所有阶段`,
|
||||||
cheats_instantFinishRivenChallenge: `立即完成裂罅挑战`,
|
cheats_instantFinishRivenChallenge: `立即完成裂罅挑战`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user