Compare commits
8 Commits
ac1928e02e
...
fd6b6ec9ab
Author | SHA1 | Date | |
---|---|---|---|
fd6b6ec9ab | |||
58bdb2d2ec | |||
c4c622d82b | |||
44a129ab0b | |||
5a7caa5ba9 | |||
a9c5e30994 | |||
f0547cb9e6 | |||
ef3d3b92c7 |
18
.eslintrc
18
.eslintrc
@ -11,17 +11,17 @@
|
|||||||
"node": true
|
"node": true
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"@typescript-eslint/explicit-function-return-type": "warn",
|
"@typescript-eslint/explicit-function-return-type": "error",
|
||||||
"@typescript-eslint/restrict-template-expressions": "warn",
|
"@typescript-eslint/restrict-template-expressions": "error",
|
||||||
"@typescript-eslint/restrict-plus-operands": "warn",
|
"@typescript-eslint/restrict-plus-operands": "error",
|
||||||
"@typescript-eslint/no-unsafe-member-access": "warn",
|
"@typescript-eslint/no-unsafe-member-access": "error",
|
||||||
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_", "caughtErrors": "none" }],
|
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_", "caughtErrors": "none" }],
|
||||||
"@typescript-eslint/no-unsafe-argument": "error",
|
"@typescript-eslint/no-unsafe-argument": "error",
|
||||||
"@typescript-eslint/no-unsafe-call": "warn",
|
"@typescript-eslint/no-unsafe-call": "error",
|
||||||
"@typescript-eslint/no-unsafe-assignment": "warn",
|
"@typescript-eslint/no-unsafe-assignment": "error",
|
||||||
"@typescript-eslint/no-explicit-any": "warn",
|
"@typescript-eslint/no-explicit-any": "error",
|
||||||
"no-loss-of-precision": "warn",
|
"no-loss-of-precision": "error",
|
||||||
"@typescript-eslint/no-unnecessary-condition": "warn",
|
"@typescript-eslint/no-unnecessary-condition": "error",
|
||||||
"@typescript-eslint/no-base-to-string": "off",
|
"@typescript-eslint/no-base-to-string": "off",
|
||||||
"no-case-declarations": "error",
|
"no-case-declarations": "error",
|
||||||
"prettier/prettier": "error",
|
"prettier/prettier": "error",
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
"fastClanAscension": false,
|
"fastClanAscension": false,
|
||||||
"missionsCanGiveAllRelics": false,
|
"missionsCanGiveAllRelics": false,
|
||||||
"unlockAllSimarisResearchEntries": false,
|
"unlockAllSimarisResearchEntries": false,
|
||||||
|
"disableDailyTribute": false,
|
||||||
"spoofMasteryRank": -1,
|
"spoofMasteryRank": -1,
|
||||||
"nightwaveStandingMultiplier": 1,
|
"nightwaveStandingMultiplier": 1,
|
||||||
"unfaithfulBugFixes": {
|
"unfaithfulBugFixes": {
|
||||||
@ -75,7 +76,8 @@
|
|||||||
"duviriOverride": "",
|
"duviriOverride": "",
|
||||||
"nightwaveOverride": "",
|
"nightwaveOverride": "",
|
||||||
"allTheFissures": "",
|
"allTheFissures": "",
|
||||||
"circuitGameModes": null
|
"circuitGameModes": null,
|
||||||
|
"darvoStockMultiplier": 1
|
||||||
},
|
},
|
||||||
"dev": {
|
"dev": {
|
||||||
"keepVendorsExpired": false
|
"keepVendorsExpired": false
|
||||||
|
@ -13,7 +13,8 @@ import {
|
|||||||
addItem,
|
addItem,
|
||||||
addRecipes,
|
addRecipes,
|
||||||
occupySlot,
|
occupySlot,
|
||||||
combineInventoryChanges
|
combineInventoryChanges,
|
||||||
|
addKubrowPetPrint
|
||||||
} from "@/src/services/inventoryService";
|
} from "@/src/services/inventoryService";
|
||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||||
@ -119,6 +120,9 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pet.Details!.Status = canSetActive ? Status.StatusAvailable : Status.StatusStasis;
|
pet.Details!.Status = canSetActive ? Status.StatusAvailable : Status.StatusStasis;
|
||||||
|
} else if (recipe.secretIngredientAction == "SIA_DISTILL_PRINT") {
|
||||||
|
const pet = inventory.KubrowPets.id(pendingRecipe.KubrowPet!)!;
|
||||||
|
addKubrowPetPrint(inventory, pet, InventoryChanges);
|
||||||
} else if (recipe.secretIngredientAction != "SIA_UNBRAND") {
|
} else if (recipe.secretIngredientAction != "SIA_UNBRAND") {
|
||||||
InventoryChanges = {
|
InventoryChanges = {
|
||||||
...InventoryChanges,
|
...InventoryChanges,
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
import { DailyDeal } from "@/src/models/worldStateModel";
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
|
|
||||||
export const getDailyDealStockLevelsController: RequestHandler = (req, res) => {
|
export const getDailyDealStockLevelsController: RequestHandler = async (req, res) => {
|
||||||
|
const dailyDeal = (await DailyDeal.findOne({ StoreItem: req.query.productName }, "AmountSold"))!;
|
||||||
res.json({
|
res.json({
|
||||||
StoreItem: req.query.productName,
|
StoreItem: req.query.productName,
|
||||||
AmountSold: 0
|
AmountSold: dailyDeal.AmountSold
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -9,15 +9,26 @@ import {
|
|||||||
updateCurrency
|
updateCurrency
|
||||||
} from "@/src/services/inventoryService";
|
} from "@/src/services/inventoryService";
|
||||||
import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
|
import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
|
||||||
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
import { handleDailyDealPurchase, handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
||||||
import { IOid } from "@/src/types/commonTypes";
|
import { IOid } from "@/src/types/commonTypes";
|
||||||
import { IInventoryChanges, IPurchaseParams, PurchaseSource } from "@/src/types/purchaseTypes";
|
import { IPurchaseParams, IPurchaseResponse, PurchaseSource } from "@/src/types/purchaseTypes";
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
import { ExportBundles, ExportFlavour } from "warframe-public-export-plus";
|
import { ExportBundles, ExportFlavour } from "warframe-public-export-plus";
|
||||||
|
|
||||||
|
const checkPurchaseParams = (params: IPurchaseParams): boolean => {
|
||||||
|
switch (params.Source) {
|
||||||
|
case PurchaseSource.Market:
|
||||||
|
return params.UsePremium;
|
||||||
|
|
||||||
|
case PurchaseSource.DailyDeal:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
export const giftingController: RequestHandler = async (req, res) => {
|
export const giftingController: RequestHandler = async (req, res) => {
|
||||||
const data = getJSONfromString<IGiftingRequest>(String(req.body));
|
const data = getJSONfromString<IGiftingRequest>(String(req.body));
|
||||||
if (data.PurchaseParams.Source != PurchaseSource.Market || !data.PurchaseParams.UsePremium) {
|
if (!checkPurchaseParams(data.PurchaseParams)) {
|
||||||
throw new Error(`unexpected purchase params in gifting request: ${String(req.body)}`);
|
throw new Error(`unexpected purchase params in gifting request: ${String(req.body)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,16 +69,19 @@ export const giftingController: RequestHandler = async (req, res) => {
|
|||||||
}
|
}
|
||||||
senderInventory.GiftsRemaining -= 1;
|
senderInventory.GiftsRemaining -= 1;
|
||||||
|
|
||||||
const inventoryChanges: IInventoryChanges = updateCurrency(
|
const response: IPurchaseResponse = {
|
||||||
senderInventory,
|
InventoryChanges: {}
|
||||||
data.PurchaseParams.ExpectedPrice,
|
};
|
||||||
true
|
if (data.PurchaseParams.Source == PurchaseSource.DailyDeal) {
|
||||||
);
|
await handleDailyDealPurchase(senderInventory, data.PurchaseParams, response);
|
||||||
|
} else {
|
||||||
|
updateCurrency(senderInventory, data.PurchaseParams.ExpectedPrice, true, response.InventoryChanges);
|
||||||
|
}
|
||||||
if (data.PurchaseParams.StoreItem in ExportBundles) {
|
if (data.PurchaseParams.StoreItem in ExportBundles) {
|
||||||
const bundle = ExportBundles[data.PurchaseParams.StoreItem];
|
const bundle = ExportBundles[data.PurchaseParams.StoreItem];
|
||||||
if (bundle.giftingBonus) {
|
if (bundle.giftingBonus) {
|
||||||
combineInventoryChanges(
|
combineInventoryChanges(
|
||||||
inventoryChanges,
|
response.InventoryChanges,
|
||||||
(await handleStoreItemAcquisition(bundle.giftingBonus, senderInventory)).InventoryChanges
|
(await handleStoreItemAcquisition(bundle.giftingBonus, senderInventory)).InventoryChanges
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -99,9 +113,7 @@ export const giftingController: RequestHandler = async (req, res) => {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
res.json({
|
res.json(response);
|
||||||
InventoryChanges: inventoryChanges
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IGiftingRequest {
|
interface IGiftingRequest {
|
||||||
|
@ -24,6 +24,8 @@ import { IPersonalRoomsClient } from "@/src/types/personalRoomsTypes";
|
|||||||
import { Ship } from "@/src/models/shipModel";
|
import { Ship } from "@/src/models/shipModel";
|
||||||
import { toLegacyOid, toOid, version_compare } from "@/src/helpers/inventoryHelpers";
|
import { toLegacyOid, toOid, version_compare } from "@/src/helpers/inventoryHelpers";
|
||||||
import { Inbox } from "@/src/models/inboxModel";
|
import { Inbox } from "@/src/models/inboxModel";
|
||||||
|
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
||||||
|
import { DailyDeal } from "@/src/models/worldStateModel";
|
||||||
|
|
||||||
export const inventoryController: RequestHandler = async (request, response) => {
|
export const inventoryController: RequestHandler = async (request, response) => {
|
||||||
const account = await getAccountForRequest(request);
|
const account = await getAccountForRequest(request);
|
||||||
@ -37,6 +39,8 @@ export const inventoryController: RequestHandler = async (request, response) =>
|
|||||||
|
|
||||||
// Handle daily reset
|
// Handle daily reset
|
||||||
if (!inventory.NextRefill || Date.now() >= inventory.NextRefill.getTime()) {
|
if (!inventory.NextRefill || Date.now() >= inventory.NextRefill.getTime()) {
|
||||||
|
const today = Math.trunc(Date.now() / 86400000);
|
||||||
|
|
||||||
for (const key of allDailyAffiliationKeys) {
|
for (const key of allDailyAffiliationKeys) {
|
||||||
inventory[key] = 16000 + inventory.PlayerLevel * 500;
|
inventory[key] = 16000 + inventory.PlayerLevel * 500;
|
||||||
}
|
}
|
||||||
@ -47,12 +51,12 @@ export const inventoryController: RequestHandler = async (request, response) =>
|
|||||||
inventory.LibraryAvailableDailyTaskInfo = createLibraryDailyTask();
|
inventory.LibraryAvailableDailyTaskInfo = createLibraryDailyTask();
|
||||||
|
|
||||||
if (inventory.NextRefill) {
|
if (inventory.NextRefill) {
|
||||||
|
const lastLoginDay = Math.trunc(inventory.NextRefill.getTime() / 86400000) - 1;
|
||||||
|
const daysPassed = today - lastLoginDay;
|
||||||
|
|
||||||
if (config.noArgonCrystalDecay) {
|
if (config.noArgonCrystalDecay) {
|
||||||
inventory.FoundToday = undefined;
|
inventory.FoundToday = undefined;
|
||||||
} else {
|
} else {
|
||||||
const lastLoginDay = Math.trunc(inventory.NextRefill.getTime() / 86400000) - 1;
|
|
||||||
const today = Math.trunc(Date.now() / 86400000);
|
|
||||||
const daysPassed = today - lastLoginDay;
|
|
||||||
for (let i = 0; i != daysPassed; ++i) {
|
for (let i = 0; i != daysPassed; ++i) {
|
||||||
const numArgonCrystals =
|
const numArgonCrystals =
|
||||||
inventory.MiscItems.find(x => x.ItemType == "/Lotus/Types/Items/MiscItems/ArgonCrystal")
|
inventory.MiscItems.find(x => x.ItemType == "/Lotus/Types/Items/MiscItems/ArgonCrystal")
|
||||||
@ -84,11 +88,29 @@ export const inventoryController: RequestHandler = async (request, response) =>
|
|||||||
inventory.FoundToday = undefined;
|
inventory.FoundToday = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inventory.UsedDailyDeals.length != 0) {
|
||||||
|
if (daysPassed == 1) {
|
||||||
|
const todayAt0Utc = today * 86400000;
|
||||||
|
const darvoIndex = Math.trunc((todayAt0Utc - 25200000) / (26 * unixTimesInMs.hour));
|
||||||
|
const darvoStart = darvoIndex * (26 * unixTimesInMs.hour) + 25200000;
|
||||||
|
const darvoOid =
|
||||||
|
((darvoStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "adc51a72f7324d95";
|
||||||
|
const deal = await DailyDeal.findById(darvoOid);
|
||||||
|
if (deal) {
|
||||||
|
inventory.UsedDailyDeals = inventory.UsedDailyDeals.filter(x => x == deal.StoreItem); // keep only the deal that came into this new day with us
|
||||||
|
} else {
|
||||||
|
inventory.UsedDailyDeals = [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inventory.UsedDailyDeals = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanupInventory(inventory);
|
cleanupInventory(inventory);
|
||||||
|
|
||||||
inventory.NextRefill = new Date((Math.trunc(Date.now() / 86400000) + 1) * 86400000);
|
inventory.NextRefill = new Date((today + 1) * 86400000); // tomorrow at 0 UTC
|
||||||
//await inventory.save();
|
//await inventory.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,9 +313,6 @@ export const getInventoryResponse = async (
|
|||||||
applyCheatsToInfestedFoundry(inventoryResponse.InfestedFoundry);
|
applyCheatsToInfestedFoundry(inventoryResponse.InfestedFoundry);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Omitting this field so opening the navigation resyncs the inventory which is more desirable for typical usage.
|
|
||||||
inventoryResponse.LastInventorySync = undefined;
|
|
||||||
|
|
||||||
// Set 2FA enabled so trading post can be used
|
// Set 2FA enabled so trading post can be used
|
||||||
inventoryResponse.HWIDProtectEnabled = true;
|
inventoryResponse.HWIDProtectEnabled = true;
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
setAccountGotLoginRewardToday
|
setAccountGotLoginRewardToday
|
||||||
} from "@/src/services/loginRewardService";
|
} from "@/src/services/loginRewardService";
|
||||||
import { getInventory } from "@/src/services/inventoryService";
|
import { getInventory } from "@/src/services/inventoryService";
|
||||||
|
import { config } from "@/src/services/configService";
|
||||||
|
|
||||||
export const loginRewardsController: RequestHandler = async (req, res) => {
|
export const loginRewardsController: RequestHandler = async (req, res) => {
|
||||||
const account = await getAccountForRequest(req);
|
const account = await getAccountForRequest(req);
|
||||||
@ -15,7 +16,7 @@ export const loginRewardsController: RequestHandler = async (req, res) => {
|
|||||||
const isMilestoneDay = account.LoginDays == 5 || account.LoginDays % 50 == 0;
|
const isMilestoneDay = account.LoginDays == 5 || account.LoginDays % 50 == 0;
|
||||||
const nextMilestoneDay = account.LoginDays < 5 ? 5 : (Math.trunc(account.LoginDays / 50) + 1) * 50;
|
const nextMilestoneDay = account.LoginDays < 5 ? 5 : (Math.trunc(account.LoginDays / 50) + 1) * 50;
|
||||||
|
|
||||||
if (today == account.LastLoginRewardDate) {
|
if (today == account.LastLoginRewardDate || config.disableDailyTribute) {
|
||||||
res.json({
|
res.json({
|
||||||
DailyTributeInfo: {
|
DailyTributeInfo: {
|
||||||
IsMilestoneDay: isMilestoneDay,
|
IsMilestoneDay: isMilestoneDay,
|
||||||
|
@ -11,6 +11,7 @@ export const purchaseController: RequestHandler = async (req, res) => {
|
|||||||
const inventory = await getInventory(accountId);
|
const inventory = await getInventory(accountId);
|
||||||
const response = await handlePurchase(purchaseRequest, inventory);
|
const response = await handlePurchase(purchaseRequest, inventory);
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
|
//console.log(JSON.stringify(response, null, 2));
|
||||||
res.json(response);
|
res.json(response);
|
||||||
sendWsBroadcastTo(accountId, { update_inventory: true });
|
sendWsBroadcastTo(accountId, { update_inventory: true });
|
||||||
};
|
};
|
||||||
|
@ -45,9 +45,9 @@ export const startRecipeController: RequestHandler = async (req, res) => {
|
|||||||
for (let i = 0; i != recipe.ingredients.length; ++i) {
|
for (let i = 0; i != recipe.ingredients.length; ++i) {
|
||||||
if (startRecipeRequest.Ids[i] && startRecipeRequest.Ids[i][0] != "/") {
|
if (startRecipeRequest.Ids[i] && startRecipeRequest.Ids[i][0] != "/") {
|
||||||
if (recipe.ingredients[i].ItemType == "/Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem") {
|
if (recipe.ingredients[i].ItemType == "/Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem") {
|
||||||
const index = inventory.KubrowPetEggs!.findIndex(x => x._id.equals(startRecipeRequest.Ids[i]));
|
const index = inventory.KubrowPetEggs.findIndex(x => x._id.equals(startRecipeRequest.Ids[i]));
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
inventory.KubrowPetEggs!.splice(index, 1);
|
inventory.KubrowPetEggs.splice(index, 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const category = ExportWeapons[recipe.ingredients[i].ItemType].productCategory;
|
const category = ExportWeapons[recipe.ingredients[i].ItemType].productCategory;
|
||||||
@ -72,6 +72,10 @@ export const startRecipeController: RequestHandler = async (req, res) => {
|
|||||||
if (recipe.secretIngredientAction == "SIA_CREATE_KUBROW") {
|
if (recipe.secretIngredientAction == "SIA_CREATE_KUBROW") {
|
||||||
inventoryChanges = addKubrowPet(inventory, getRandomElement(recipe.secretIngredients!)!.ItemType);
|
inventoryChanges = addKubrowPet(inventory, getRandomElement(recipe.secretIngredients!)!.ItemType);
|
||||||
pr.KubrowPet = new Types.ObjectId(fromOid(inventoryChanges.KubrowPets![0].ItemId));
|
pr.KubrowPet = new Types.ObjectId(fromOid(inventoryChanges.KubrowPets![0].ItemId));
|
||||||
|
} else if (recipe.secretIngredientAction == "SIA_DISTILL_PRINT") {
|
||||||
|
pr.KubrowPet = new Types.ObjectId(startRecipeRequest.Ids[recipe.ingredients.length]);
|
||||||
|
const pet = inventory.KubrowPets.id(pr.KubrowPet)!;
|
||||||
|
pet.Details!.PrintsRemaining -= 1;
|
||||||
} else if (recipe.secretIngredientAction == "SIA_SPECTRE_LOADOUT_COPY") {
|
} else if (recipe.secretIngredientAction == "SIA_SPECTRE_LOADOUT_COPY") {
|
||||||
const spectreLoadout: ISpectreLoadout = {
|
const spectreLoadout: ISpectreLoadout = {
|
||||||
ItemType: recipe.resultType,
|
ItemType: recipe.resultType,
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
import { getWorldState, populateFissures } from "@/src/services/worldStateService";
|
import { getWorldState, populateDailyDeal, populateFissures } from "@/src/services/worldStateService";
|
||||||
import { version_compare } from "@/src/helpers/inventoryHelpers";
|
import { version_compare } from "@/src/helpers/inventoryHelpers";
|
||||||
|
|
||||||
export const worldStateController: RequestHandler = async (req, res) => {
|
export const worldStateController: RequestHandler = async (req, res) => {
|
||||||
const buildLabel = req.query.buildLabel as string | undefined;
|
const buildLabel = req.query.buildLabel as string | undefined;
|
||||||
const worldState = getWorldState(buildLabel);
|
const worldState = getWorldState(buildLabel);
|
||||||
|
|
||||||
|
const populatePromises = [populateDailyDeal(worldState)];
|
||||||
|
|
||||||
// Omitting void fissures for versions prior to Dante Unbound to avoid script errors.
|
// Omitting void fissures for versions prior to Dante Unbound to avoid script errors.
|
||||||
if (!buildLabel || version_compare(buildLabel, "2024.03.24.20.00") >= 0) {
|
if (!buildLabel || version_compare(buildLabel, "2024.03.24.20.00") >= 0) {
|
||||||
await populateFissures(worldState);
|
populatePromises.push(populateFissures(worldState));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Promise.all(populatePromises);
|
||||||
|
|
||||||
res.json(worldState);
|
res.json(worldState);
|
||||||
};
|
};
|
||||||
|
@ -91,7 +91,7 @@ import {
|
|||||||
ICrewMemberSkillEfficiency,
|
ICrewMemberSkillEfficiency,
|
||||||
ICrewMemberDatabase,
|
ICrewMemberDatabase,
|
||||||
ICrewMemberClient,
|
ICrewMemberClient,
|
||||||
ISortieRewardAttenuation,
|
IRewardAttenuation,
|
||||||
IInvasionProgressDatabase,
|
IInvasionProgressDatabase,
|
||||||
IInvasionProgressClient,
|
IInvasionProgressClient,
|
||||||
IAccolades,
|
IAccolades,
|
||||||
@ -99,7 +99,9 @@ import {
|
|||||||
ILotusCustomization,
|
ILotusCustomization,
|
||||||
IEndlessXpReward,
|
IEndlessXpReward,
|
||||||
IPersonalGoalProgressDatabase,
|
IPersonalGoalProgressDatabase,
|
||||||
IPersonalGoalProgressClient
|
IPersonalGoalProgressClient,
|
||||||
|
IKubrowPetPrintClient,
|
||||||
|
IKubrowPetPrintDatabase
|
||||||
} from "../../types/inventoryTypes/inventoryTypes";
|
} from "../../types/inventoryTypes/inventoryTypes";
|
||||||
import { IOid } from "../../types/commonTypes";
|
import { IOid } from "../../types/commonTypes";
|
||||||
import {
|
import {
|
||||||
@ -1008,6 +1010,27 @@ const traitsSchema = new Schema<ITraits>(
|
|||||||
{ _id: false }
|
{ _id: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const kubrowPetPrintSchema = new Schema<IKubrowPetPrintDatabase>({
|
||||||
|
ItemType: String,
|
||||||
|
Name: String,
|
||||||
|
IsMale: Boolean,
|
||||||
|
Size: Number,
|
||||||
|
DominantTraits: traitsSchema,
|
||||||
|
RecessiveTraits: traitsSchema
|
||||||
|
});
|
||||||
|
kubrowPetPrintSchema.set("toJSON", {
|
||||||
|
virtuals: true,
|
||||||
|
transform(_doc, obj) {
|
||||||
|
const db = obj as IKubrowPetPrintDatabase;
|
||||||
|
const client = obj as IKubrowPetPrintClient;
|
||||||
|
|
||||||
|
client.ItemId = toOid(db._id);
|
||||||
|
|
||||||
|
delete obj._id;
|
||||||
|
delete obj.__v;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const detailsSchema = new Schema<IKubrowPetDetailsDatabase>(
|
const detailsSchema = new Schema<IKubrowPetDetailsDatabase>(
|
||||||
{
|
{
|
||||||
Name: String,
|
Name: String,
|
||||||
@ -1394,10 +1417,10 @@ lastSortieRewardSchema.set("toJSON", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const sortieRewardAttenutationSchema = new Schema<ISortieRewardAttenuation>(
|
const rewardAttenutationSchema = new Schema<IRewardAttenuation>(
|
||||||
{
|
{
|
||||||
Tag: String,
|
Tag: { type: String, required: true },
|
||||||
Atten: Number
|
Atten: { type: Number, required: true }
|
||||||
},
|
},
|
||||||
{ _id: false }
|
{ _id: false }
|
||||||
);
|
);
|
||||||
@ -1511,7 +1534,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
|
|
||||||
KubrowPetEggs: [kubrowPetEggSchema],
|
KubrowPetEggs: [kubrowPetEggSchema],
|
||||||
//Prints Cat(3 Prints)\Kubrow(2 Prints) Pets
|
//Prints Cat(3 Prints)\Kubrow(2 Prints) Pets
|
||||||
//KubrowPetPrints: [Schema.Types.Mixed],
|
KubrowPetPrints: [kubrowPetPrintSchema],
|
||||||
|
|
||||||
//Item for EquippedGear example:Scaner,LoadoutTechSummon etc
|
//Item for EquippedGear example:Scaner,LoadoutTechSummon etc
|
||||||
Consumables: [typeCountSchema],
|
Consumables: [typeCountSchema],
|
||||||
@ -1625,6 +1648,9 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
PendingSpectreLoadouts: { type: [spectreLoadoutsSchema], default: undefined },
|
PendingSpectreLoadouts: { type: [spectreLoadoutsSchema], default: undefined },
|
||||||
SpectreLoadouts: { type: [spectreLoadoutsSchema], default: undefined },
|
SpectreLoadouts: { type: [spectreLoadoutsSchema], default: undefined },
|
||||||
|
|
||||||
|
//Darvo Deal
|
||||||
|
UsedDailyDeals: [String],
|
||||||
|
|
||||||
//New Quest Email
|
//New Quest Email
|
||||||
EmailItems: [typeCountSchema],
|
EmailItems: [typeCountSchema],
|
||||||
|
|
||||||
@ -1640,7 +1666,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
CompletedSorties: [String],
|
CompletedSorties: [String],
|
||||||
LastSortieReward: { type: [lastSortieRewardSchema], default: undefined },
|
LastSortieReward: { type: [lastSortieRewardSchema], default: undefined },
|
||||||
LastLiteSortieReward: { type: [lastSortieRewardSchema], default: undefined },
|
LastLiteSortieReward: { type: [lastSortieRewardSchema], default: undefined },
|
||||||
SortieRewardAttenuation: { type: [sortieRewardAttenutationSchema], default: undefined },
|
SortieRewardAttenuation: { type: [rewardAttenutationSchema], default: undefined },
|
||||||
|
|
||||||
// Resource Extractor Drones
|
// Resource Extractor Drones
|
||||||
Drones: [droneSchema],
|
Drones: [droneSchema],
|
||||||
@ -1741,7 +1767,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
//ChallengeInstanceStates: [Schema.Types.Mixed],
|
//ChallengeInstanceStates: [Schema.Types.Mixed],
|
||||||
RecentVendorPurchases: { type: [recentVendorPurchaseSchema], default: undefined },
|
RecentVendorPurchases: { type: [recentVendorPurchaseSchema], default: undefined },
|
||||||
//Robotics: [Schema.Types.Mixed],
|
//Robotics: [Schema.Types.Mixed],
|
||||||
//UsedDailyDeals: [Schema.Types.Mixed],
|
|
||||||
CollectibleSeries: { type: [collectibleEntrySchema], default: undefined },
|
CollectibleSeries: { type: [collectibleEntrySchema], default: undefined },
|
||||||
HasResetAccount: { type: Boolean, default: false },
|
HasResetAccount: { type: Boolean, default: false },
|
||||||
|
|
||||||
@ -1780,7 +1805,9 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
|
|
||||||
HubNpcCustomizations: { type: [hubNpcCustomizationSchema], default: undefined },
|
HubNpcCustomizations: { type: [hubNpcCustomizationSchema], default: undefined },
|
||||||
|
|
||||||
ClaimedJunctionChallengeRewards: { type: [String], default: undefined }
|
ClaimedJunctionChallengeRewards: { type: [String], default: undefined },
|
||||||
|
|
||||||
|
SpecialItemRewardAttenuation: { type: [rewardAttenutationSchema], default: undefined }
|
||||||
},
|
},
|
||||||
{ timestamps: { createdAt: "Created", updatedAt: false } }
|
{ timestamps: { createdAt: "Created", updatedAt: false } }
|
||||||
);
|
);
|
||||||
@ -1850,6 +1877,7 @@ export type InventoryDocumentProps = {
|
|||||||
CrewShipSalvagedWeaponSkins: Types.DocumentArray<IUpgradeDatabase>;
|
CrewShipSalvagedWeaponSkins: Types.DocumentArray<IUpgradeDatabase>;
|
||||||
PersonalTechProjects: Types.DocumentArray<IPersonalTechProjectDatabase>;
|
PersonalTechProjects: Types.DocumentArray<IPersonalTechProjectDatabase>;
|
||||||
CrewMembers: Types.DocumentArray<ICrewMemberDatabase>;
|
CrewMembers: Types.DocumentArray<ICrewMemberDatabase>;
|
||||||
|
KubrowPetPrints: Types.DocumentArray<IKubrowPetPrintDatabase>;
|
||||||
} & { [K in TEquipmentKey]: Types.DocumentArray<IEquipmentDatabase> };
|
} & { [K in TEquipmentKey]: Types.DocumentArray<IEquipmentDatabase> };
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { IFissureDatabase } from "@/src/types/worldStateTypes";
|
import { IDailyDealDatabase, IFissureDatabase } from "@/src/types/worldStateTypes";
|
||||||
import { model, Schema } from "mongoose";
|
import { model, Schema } from "mongoose";
|
||||||
|
|
||||||
const fissureSchema = new Schema<IFissureDatabase>({
|
const fissureSchema = new Schema<IFissureDatabase>({
|
||||||
@ -12,3 +12,19 @@ const fissureSchema = new Schema<IFissureDatabase>({
|
|||||||
fissureSchema.index({ Expiry: 1 }, { expireAfterSeconds: 0 }); // With this, MongoDB will automatically delete expired entries.
|
fissureSchema.index({ Expiry: 1 }, { expireAfterSeconds: 0 }); // With this, MongoDB will automatically delete expired entries.
|
||||||
|
|
||||||
export const Fissure = model<IFissureDatabase>("Fissure", fissureSchema);
|
export const Fissure = model<IFissureDatabase>("Fissure", fissureSchema);
|
||||||
|
|
||||||
|
const dailyDealSchema = new Schema<IDailyDealDatabase>({
|
||||||
|
StoreItem: { type: String, required: true },
|
||||||
|
Activation: { type: Date, required: true },
|
||||||
|
Expiry: { type: Date, required: true },
|
||||||
|
Discount: { type: Number, required: true },
|
||||||
|
OriginalPrice: { type: Number, required: true },
|
||||||
|
SalePrice: { type: Number, required: true },
|
||||||
|
AmountTotal: { type: Number, required: true },
|
||||||
|
AmountSold: { type: Number, required: true }
|
||||||
|
});
|
||||||
|
|
||||||
|
dailyDealSchema.index({ StoreItem: 1 }, { unique: true });
|
||||||
|
dailyDealSchema.index({ Expiry: 1 }, { expireAfterSeconds: 86400 });
|
||||||
|
|
||||||
|
export const DailyDeal = model<IDailyDealDatabase>("DailyDeal", dailyDealSchema);
|
||||||
|
@ -65,6 +65,7 @@ export interface IConfig {
|
|||||||
fastClanAscension?: boolean;
|
fastClanAscension?: boolean;
|
||||||
missionsCanGiveAllRelics?: boolean;
|
missionsCanGiveAllRelics?: boolean;
|
||||||
unlockAllSimarisResearchEntries?: boolean;
|
unlockAllSimarisResearchEntries?: boolean;
|
||||||
|
disableDailyTribute?: boolean;
|
||||||
spoofMasteryRank?: number;
|
spoofMasteryRank?: number;
|
||||||
nightwaveStandingMultiplier?: number;
|
nightwaveStandingMultiplier?: number;
|
||||||
unfaithfulBugFixes?: {
|
unfaithfulBugFixes?: {
|
||||||
@ -83,6 +84,7 @@ export interface IConfig {
|
|||||||
nightwaveOverride?: string;
|
nightwaveOverride?: string;
|
||||||
allTheFissures?: string;
|
allTheFissures?: string;
|
||||||
circuitGameModes?: string[];
|
circuitGameModes?: string[];
|
||||||
|
darvoStockMultiplier?: number;
|
||||||
};
|
};
|
||||||
dev?: {
|
dev?: {
|
||||||
keepVendorsExpired?: boolean;
|
keepVendorsExpired?: boolean;
|
||||||
|
@ -296,6 +296,12 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial<
|
|||||||
db[key] = client[key];
|
db[key] = client[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// IRewardAtten[]
|
||||||
|
for (const key of ["SortieRewardAttenuation", "SpecialItemRewardAttenuation"] as const) {
|
||||||
|
if (client[key] !== undefined) {
|
||||||
|
db[key] = client[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
if (client.XPInfo !== undefined) {
|
if (client.XPInfo !== undefined) {
|
||||||
db.XPInfo = client.XPInfo;
|
db.XPInfo = client.XPInfo;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,8 @@ import {
|
|||||||
ICalendarProgress,
|
ICalendarProgress,
|
||||||
INemesisWeaponTargetFingerprint,
|
INemesisWeaponTargetFingerprint,
|
||||||
INemesisPetTargetFingerprint,
|
INemesisPetTargetFingerprint,
|
||||||
IDialogueDatabase
|
IDialogueDatabase,
|
||||||
|
IKubrowPetPrintClient
|
||||||
} from "@/src/types/inventoryTypes/inventoryTypes";
|
} from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
|
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
|
||||||
import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
||||||
@ -43,6 +44,7 @@ import {
|
|||||||
} from "../types/inventoryTypes/commonInventoryTypes";
|
} from "../types/inventoryTypes/commonInventoryTypes";
|
||||||
import {
|
import {
|
||||||
ExportArcanes,
|
ExportArcanes,
|
||||||
|
ExportBoosters,
|
||||||
ExportBundles,
|
ExportBundles,
|
||||||
ExportChallenges,
|
ExportChallenges,
|
||||||
ExportCustoms,
|
ExportCustoms,
|
||||||
@ -424,7 +426,6 @@ export const addItem = async (
|
|||||||
ItemType: "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg",
|
ItemType: "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg",
|
||||||
_id: new Types.ObjectId()
|
_id: new Types.ObjectId()
|
||||||
};
|
};
|
||||||
inventory.KubrowPetEggs ??= [];
|
|
||||||
inventory.KubrowPetEggs.push(egg);
|
inventory.KubrowPetEggs.push(egg);
|
||||||
changes.push({
|
changes.push({
|
||||||
ItemType: egg.ItemType,
|
ItemType: egg.ItemType,
|
||||||
@ -671,6 +672,17 @@ export const addItem = async (
|
|||||||
return await addEmailItem(inventory, typeName);
|
return await addEmailItem(inventory, typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boosters are an odd case. They're only added like this via Baro's Void Surplus afaik.
|
||||||
|
{
|
||||||
|
const boosterEntry = Object.entries(ExportBoosters).find(arr => arr[1].typeName == typeName);
|
||||||
|
if (boosterEntry) {
|
||||||
|
addBooster(typeName, quantity, inventory);
|
||||||
|
return {
|
||||||
|
Boosters: [{ ItemType: typeName, ExpiryDate: quantity }]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Path-based duck typing
|
// Path-based duck typing
|
||||||
switch (typeName.substr(1).split("/")[1]) {
|
switch (typeName.substr(1).split("/")[1]) {
|
||||||
case "Powersuits":
|
case "Powersuits":
|
||||||
@ -784,7 +796,11 @@ export const addItem = async (
|
|||||||
typeName.substr(1).split("/")[3] == "CatbrowPet" ||
|
typeName.substr(1).split("/")[3] == "CatbrowPet" ||
|
||||||
typeName.substr(1).split("/")[3] == "KubrowPet"
|
typeName.substr(1).split("/")[3] == "KubrowPet"
|
||||||
) {
|
) {
|
||||||
if (typeName != "/Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem") {
|
if (
|
||||||
|
typeName != "/Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem" &&
|
||||||
|
typeName != "/Lotus/Types/Game/KubrowPet/BlankTraitPrint" &&
|
||||||
|
typeName != "/Lotus/Types/Game/KubrowPet/ImprintedTraitPrint"
|
||||||
|
) {
|
||||||
return addKubrowPet(inventory, typeName, undefined, premiumPurchase);
|
return addKubrowPet(inventory, typeName, undefined, premiumPurchase);
|
||||||
}
|
}
|
||||||
} else if (typeName.startsWith("/Lotus/Types/Game/CrewShip/CrewMember/")) {
|
} else if (typeName.startsWith("/Lotus/Types/Game/CrewShip/CrewMember/")) {
|
||||||
@ -1048,8 +1064,13 @@ export const addKubrowPet = (
|
|||||||
const configs: IItemConfig[] = applyDefaultUpgrades(inventory, kubrowPet?.defaultUpgrades);
|
const configs: IItemConfig[] = applyDefaultUpgrades(inventory, kubrowPet?.defaultUpgrades);
|
||||||
|
|
||||||
if (!details) {
|
if (!details) {
|
||||||
let traits: ITraits;
|
const isCatbrow = [
|
||||||
|
"/Lotus/Types/Game/CatbrowPet/CheshireCatbrowPetPowerSuit",
|
||||||
|
"/Lotus/Types/Game/CatbrowPet/MirrorCatbrowPetPowerSuit",
|
||||||
|
"/Lotus/Types/Game/CatbrowPet/VampireCatbrowPetPowerSuit"
|
||||||
|
].includes(kubrowPetName);
|
||||||
|
|
||||||
|
let traits: ITraits;
|
||||||
if (kubrowPetName == "/Lotus/Types/Game/CatbrowPet/VampireCatbrowPetPowerSuit") {
|
if (kubrowPetName == "/Lotus/Types/Game/CatbrowPet/VampireCatbrowPetPowerSuit") {
|
||||||
traits = {
|
traits = {
|
||||||
BaseColor: "/Lotus/Types/Game/CatbrowPet/Colors/CatbrowPetColorBaseVampire",
|
BaseColor: "/Lotus/Types/Game/CatbrowPet/Colors/CatbrowPetColorBaseVampire",
|
||||||
@ -1064,12 +1085,7 @@ export const addKubrowPet = (
|
|||||||
Tail: "/Lotus/Types/Game/CatbrowPet/Tails/CatbrowTailVampire"
|
Tail: "/Lotus/Types/Game/CatbrowPet/Tails/CatbrowTailVampire"
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const isCatbrow = [
|
|
||||||
"/Lotus/Types/Game/CatbrowPet/MirrorCatbrowPetPowerSuit",
|
|
||||||
"/Lotus/Types/Game/CatbrowPet/CheshireCatbrowPetPowerSuit"
|
|
||||||
].includes(kubrowPetName);
|
|
||||||
const traitsPool = isCatbrow ? catbrowDetails : kubrowDetails;
|
const traitsPool = isCatbrow ? catbrowDetails : kubrowDetails;
|
||||||
|
|
||||||
traits = {
|
traits = {
|
||||||
BaseColor: getRandomWeightedReward(traitsPool.Colors, kubrowWeights)!.type,
|
BaseColor: getRandomWeightedReward(traitsPool.Colors, kubrowWeights)!.type,
|
||||||
SecondaryColor: getRandomWeightedReward(traitsPool.Colors, kubrowWeights)!.type,
|
SecondaryColor: getRandomWeightedReward(traitsPool.Colors, kubrowWeights)!.type,
|
||||||
@ -1088,7 +1104,7 @@ export const addKubrowPet = (
|
|||||||
Name: "",
|
Name: "",
|
||||||
IsPuppy: !premiumPurchase,
|
IsPuppy: !premiumPurchase,
|
||||||
HasCollar: true,
|
HasCollar: true,
|
||||||
PrintsRemaining: 3,
|
PrintsRemaining: isCatbrow ? 3 : 2,
|
||||||
Status: premiumPurchase ? Status.StatusStasis : Status.StatusIncubating,
|
Status: premiumPurchase ? Status.StatusStasis : Status.StatusIncubating,
|
||||||
HatchDate: premiumPurchase ? new Date() : new Date(Date.now() + 10 * unixTimesInMs.hour), // On live, this seems to be somewhat randomised so that the pet hatches 9~11 hours after start.
|
HatchDate: premiumPurchase ? new Date() : new Date(Date.now() + 10 * unixTimesInMs.hour), // On live, this seems to be somewhat randomised so that the pet hatches 9~11 hours after start.
|
||||||
IsMale: !!getRandomInt(0, 1),
|
IsMale: !!getRandomInt(0, 1),
|
||||||
@ -1112,6 +1128,26 @@ export const addKubrowPet = (
|
|||||||
return inventoryChanges;
|
return inventoryChanges;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const addKubrowPetPrint = (
|
||||||
|
inventory: TInventoryDatabaseDocument,
|
||||||
|
pet: IEquipmentDatabase,
|
||||||
|
inventoryChanges: IInventoryChanges
|
||||||
|
): void => {
|
||||||
|
inventoryChanges.KubrowPetPrints ??= [];
|
||||||
|
inventoryChanges.KubrowPetPrints.push(
|
||||||
|
inventory.KubrowPetPrints[
|
||||||
|
inventory.KubrowPetPrints.push({
|
||||||
|
ItemType: "/Lotus/Types/Game/KubrowPet/ImprintedTraitPrint",
|
||||||
|
Name: pet.Details!.Name,
|
||||||
|
IsMale: pet.Details!.IsMale,
|
||||||
|
Size: pet.Details!.Size,
|
||||||
|
DominantTraits: pet.Details!.DominantTraits,
|
||||||
|
RecessiveTraits: pet.Details!.RecessiveTraits
|
||||||
|
}) - 1
|
||||||
|
].toJSON<IKubrowPetPrintClient>()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const updateSlots = (
|
export const updateSlots = (
|
||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
slotName: SlotNames,
|
slotName: SlotNames,
|
||||||
@ -1330,7 +1366,7 @@ export const addCustomization = (
|
|||||||
customizationName: string,
|
customizationName: string,
|
||||||
inventoryChanges: IInventoryChanges = {}
|
inventoryChanges: IInventoryChanges = {}
|
||||||
): IInventoryChanges => {
|
): IInventoryChanges => {
|
||||||
if (!inventory.FlavourItems.find(x => x.ItemType == customizationName)) {
|
if (!inventory.FlavourItems.some(x => x.ItemType == customizationName)) {
|
||||||
const flavourItemIndex = inventory.FlavourItems.push({ ItemType: customizationName }) - 1;
|
const flavourItemIndex = inventory.FlavourItems.push({ ItemType: customizationName }) - 1;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
inventoryChanges.FlavourItems ??= [];
|
inventoryChanges.FlavourItems ??= [];
|
||||||
@ -1346,7 +1382,7 @@ export const addSkin = (
|
|||||||
typeName: string,
|
typeName: string,
|
||||||
inventoryChanges: IInventoryChanges = {}
|
inventoryChanges: IInventoryChanges = {}
|
||||||
): IInventoryChanges => {
|
): IInventoryChanges => {
|
||||||
if (inventory.WeaponSkins.find(x => x.ItemType == typeName)) {
|
if (inventory.WeaponSkins.some(x => x.ItemType == typeName)) {
|
||||||
logger.debug(`refusing to add WeaponSkin ${typeName} because account already owns it`);
|
logger.debug(`refusing to add WeaponSkin ${typeName} because account already owns it`);
|
||||||
} else {
|
} else {
|
||||||
const index = inventory.WeaponSkins.push({ ItemType: typeName, IsNew: true }) - 1;
|
const index = inventory.WeaponSkins.push({ ItemType: typeName, IsNew: true }) - 1;
|
||||||
|
@ -525,7 +525,6 @@ export const addMissionInventoryUpdates = async (
|
|||||||
}
|
}
|
||||||
case "KubrowPetEggs": {
|
case "KubrowPetEggs": {
|
||||||
for (const egg of value) {
|
for (const egg of value) {
|
||||||
inventory.KubrowPetEggs ??= [];
|
|
||||||
inventory.KubrowPetEggs.push({
|
inventory.KubrowPetEggs.push({
|
||||||
ItemType: egg.ItemType,
|
ItemType: egg.ItemType,
|
||||||
_id: new Types.ObjectId()
|
_id: new Types.ObjectId()
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
updateCurrency,
|
updateCurrency,
|
||||||
updateSlots
|
updateSlots
|
||||||
} from "@/src/services/inventoryService";
|
} from "@/src/services/inventoryService";
|
||||||
import { getRandomWeightedRewardUc } from "@/src/services/rngService";
|
import { getRandomReward, getRandomWeightedRewardUc } from "@/src/services/rngService";
|
||||||
import { applyStandingToVendorManifest, getVendorManifestByOid } from "@/src/services/serversideVendorsService";
|
import { applyStandingToVendorManifest, getVendorManifestByOid } from "@/src/services/serversideVendorsService";
|
||||||
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
|
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import {
|
import {
|
||||||
@ -16,7 +16,8 @@ import {
|
|||||||
IPurchaseResponse,
|
IPurchaseResponse,
|
||||||
SlotPurchase,
|
SlotPurchase,
|
||||||
IInventoryChanges,
|
IInventoryChanges,
|
||||||
PurchaseSource
|
PurchaseSource,
|
||||||
|
IPurchaseParams
|
||||||
} from "@/src/types/purchaseTypes";
|
} from "@/src/types/purchaseTypes";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { getWorldState } from "./worldStateService";
|
import { getWorldState } from "./worldStateService";
|
||||||
@ -35,6 +36,8 @@ import {
|
|||||||
import { config } from "./configService";
|
import { config } from "./configService";
|
||||||
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
||||||
import { fromStoreItem, toStoreItem } from "./itemDataService";
|
import { fromStoreItem, toStoreItem } from "./itemDataService";
|
||||||
|
import { DailyDeal } from "../models/worldStateModel";
|
||||||
|
import { fromMongoDate, toMongoDate } from "../helpers/inventoryHelpers";
|
||||||
|
|
||||||
export const getStoreItemCategory = (storeItem: string): string => {
|
export const getStoreItemCategory = (storeItem: string): string => {
|
||||||
const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/");
|
const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/");
|
||||||
@ -51,6 +54,58 @@ export const getStoreItemTypesCategory = (typesItem: string): string => {
|
|||||||
return typeElements[1];
|
return typeElements[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const tallyVendorPurchase = (
|
||||||
|
inventory: TInventoryDatabaseDocument,
|
||||||
|
inventoryChanges: IInventoryChanges,
|
||||||
|
VendorType: string,
|
||||||
|
ItemId: string,
|
||||||
|
numPurchased: number,
|
||||||
|
Expiry: Date
|
||||||
|
): void => {
|
||||||
|
if (!config.noVendorPurchaseLimits) {
|
||||||
|
inventory.RecentVendorPurchases ??= [];
|
||||||
|
let vendorPurchases = inventory.RecentVendorPurchases.find(x => x.VendorType == VendorType);
|
||||||
|
if (!vendorPurchases) {
|
||||||
|
vendorPurchases =
|
||||||
|
inventory.RecentVendorPurchases[
|
||||||
|
inventory.RecentVendorPurchases.push({
|
||||||
|
VendorType: VendorType,
|
||||||
|
PurchaseHistory: []
|
||||||
|
}) - 1
|
||||||
|
];
|
||||||
|
}
|
||||||
|
let historyEntry = vendorPurchases.PurchaseHistory.find(x => x.ItemId == ItemId);
|
||||||
|
if (historyEntry) {
|
||||||
|
if (Date.now() >= historyEntry.Expiry.getTime()) {
|
||||||
|
historyEntry.NumPurchased = numPurchased;
|
||||||
|
historyEntry.Expiry = Expiry;
|
||||||
|
} else {
|
||||||
|
historyEntry.NumPurchased += numPurchased;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
historyEntry =
|
||||||
|
vendorPurchases.PurchaseHistory[
|
||||||
|
vendorPurchases.PurchaseHistory.push({
|
||||||
|
ItemId: ItemId,
|
||||||
|
NumPurchased: numPurchased,
|
||||||
|
Expiry: Expiry
|
||||||
|
}) - 1
|
||||||
|
];
|
||||||
|
}
|
||||||
|
inventoryChanges.NewVendorPurchase = {
|
||||||
|
VendorType: VendorType,
|
||||||
|
PurchaseHistory: [
|
||||||
|
{
|
||||||
|
ItemId: ItemId,
|
||||||
|
NumPurchased: historyEntry.NumPurchased,
|
||||||
|
Expiry: toMongoDate(Expiry)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
inventoryChanges.RecentVendorPurchases = inventoryChanges.NewVendorPurchase;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const handlePurchase = async (
|
export const handlePurchase = async (
|
||||||
purchaseRequest: IPurchaseRequest,
|
purchaseRequest: IPurchaseRequest,
|
||||||
inventory: TInventoryDatabaseDocument
|
inventory: TInventoryDatabaseDocument
|
||||||
@ -97,20 +152,7 @@ export const handlePurchase = async (
|
|||||||
if (offer.LocTagRandSeed !== undefined) {
|
if (offer.LocTagRandSeed !== undefined) {
|
||||||
seed = BigInt(offer.LocTagRandSeed);
|
seed = BigInt(offer.LocTagRandSeed);
|
||||||
}
|
}
|
||||||
if (!config.noVendorPurchaseLimits && ItemId) {
|
if (ItemId) {
|
||||||
inventory.RecentVendorPurchases ??= [];
|
|
||||||
let vendorPurchases = inventory.RecentVendorPurchases.find(
|
|
||||||
x => x.VendorType == manifest!.VendorInfo.TypeName
|
|
||||||
);
|
|
||||||
if (!vendorPurchases) {
|
|
||||||
vendorPurchases =
|
|
||||||
inventory.RecentVendorPurchases[
|
|
||||||
inventory.RecentVendorPurchases.push({
|
|
||||||
VendorType: manifest.VendorInfo.TypeName,
|
|
||||||
PurchaseHistory: []
|
|
||||||
}) - 1
|
|
||||||
];
|
|
||||||
}
|
|
||||||
let expiry = parseInt(offer.Expiry.$date.$numberLong);
|
let expiry = parseInt(offer.Expiry.$date.$numberLong);
|
||||||
if (purchaseRequest.PurchaseParams.IsWeekly) {
|
if (purchaseRequest.PurchaseParams.IsWeekly) {
|
||||||
const EPOCH = 1734307200 * 1000; // Monday
|
const EPOCH = 1734307200 * 1000; // Monday
|
||||||
@ -118,34 +160,14 @@ export const handlePurchase = async (
|
|||||||
const weekStart = EPOCH + week * 604800000;
|
const weekStart = EPOCH + week * 604800000;
|
||||||
expiry = weekStart + 604800000;
|
expiry = weekStart + 604800000;
|
||||||
}
|
}
|
||||||
const historyEntry = vendorPurchases.PurchaseHistory.find(x => x.ItemId == ItemId);
|
tallyVendorPurchase(
|
||||||
let numPurchased = purchaseRequest.PurchaseParams.Quantity;
|
inventory,
|
||||||
if (historyEntry) {
|
prePurchaseInventoryChanges,
|
||||||
if (Date.now() >= historyEntry.Expiry.getTime()) {
|
manifest.VendorInfo.TypeName,
|
||||||
historyEntry.NumPurchased = numPurchased;
|
ItemId,
|
||||||
historyEntry.Expiry = new Date(expiry);
|
purchaseRequest.PurchaseParams.Quantity,
|
||||||
} else {
|
new Date(expiry)
|
||||||
numPurchased += historyEntry.NumPurchased;
|
);
|
||||||
historyEntry.NumPurchased += purchaseRequest.PurchaseParams.Quantity;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
vendorPurchases.PurchaseHistory.push({
|
|
||||||
ItemId: ItemId,
|
|
||||||
NumPurchased: purchaseRequest.PurchaseParams.Quantity,
|
|
||||||
Expiry: new Date(expiry)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
prePurchaseInventoryChanges.NewVendorPurchase = {
|
|
||||||
VendorType: manifest.VendorInfo.TypeName,
|
|
||||||
PurchaseHistory: [
|
|
||||||
{
|
|
||||||
ItemId: ItemId,
|
|
||||||
NumPurchased: numPurchased,
|
|
||||||
Expiry: { $date: { $numberLong: expiry.toString() } }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
prePurchaseInventoryChanges.RecentVendorPurchases = prePurchaseInventoryChanges.NewVendorPurchase;
|
|
||||||
}
|
}
|
||||||
purchaseRequest.PurchaseParams.Quantity *= offer.QuantityMultiplier;
|
purchaseRequest.PurchaseParams.Quantity *= offer.QuantityMultiplier;
|
||||||
} else {
|
} else {
|
||||||
@ -191,7 +213,7 @@ export const handlePurchase = async (
|
|||||||
throw new Error(`vendor purchase should not have an expected price`);
|
throw new Error(`vendor purchase should not have an expected price`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config.dontSubtractPurchaseItemCost) {
|
if (offer.PrimePrice && !config.dontSubtractPurchaseItemCost) {
|
||||||
const invItem: IMiscItem = {
|
const invItem: IMiscItem = {
|
||||||
ItemType: "/Lotus/Types/Items/MiscItems/PrimeBucks",
|
ItemType: "/Lotus/Types/Items/MiscItems/PrimeBucks",
|
||||||
ItemCount: offer.PrimePrice * purchaseRequest.PurchaseParams.Quantity * -1
|
ItemCount: offer.PrimePrice * purchaseRequest.PurchaseParams.Quantity * -1
|
||||||
@ -200,6 +222,17 @@ export const handlePurchase = async (
|
|||||||
purchaseResponse.InventoryChanges.MiscItems ??= [];
|
purchaseResponse.InventoryChanges.MiscItems ??= [];
|
||||||
purchaseResponse.InventoryChanges.MiscItems.push(invItem);
|
purchaseResponse.InventoryChanges.MiscItems.push(invItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (offer.Limit) {
|
||||||
|
tallyVendorPurchase(
|
||||||
|
inventory,
|
||||||
|
purchaseResponse.InventoryChanges,
|
||||||
|
"VoidTrader",
|
||||||
|
offer.ItemType,
|
||||||
|
purchaseRequest.PurchaseParams.Quantity,
|
||||||
|
fromMongoDate(worldState.VoidTraders[0].Expiry)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -240,6 +273,12 @@ export const handlePurchase = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PurchaseSource.DailyDeal:
|
||||||
|
if (purchaseRequest.PurchaseParams.ExpectedPrice) {
|
||||||
|
throw new Error(`daily deal purchase should not have an expected price`);
|
||||||
|
}
|
||||||
|
await handleDailyDealPurchase(inventory, purchaseRequest.PurchaseParams, purchaseResponse);
|
||||||
|
break;
|
||||||
case PurchaseSource.Vendor:
|
case PurchaseSource.Vendor:
|
||||||
if (purchaseRequest.PurchaseParams.SourceId! in ExportVendors) {
|
if (purchaseRequest.PurchaseParams.SourceId! in ExportVendors) {
|
||||||
const vendor = ExportVendors[purchaseRequest.PurchaseParams.SourceId!];
|
const vendor = ExportVendors[purchaseRequest.PurchaseParams.SourceId!];
|
||||||
@ -328,6 +367,25 @@ const handleItemPrices = (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const handleDailyDealPurchase = async (
|
||||||
|
inventory: TInventoryDatabaseDocument,
|
||||||
|
purchaseParams: IPurchaseParams,
|
||||||
|
purchaseResponse: IPurchaseResponse
|
||||||
|
): Promise<void> => {
|
||||||
|
const dailyDeal = (await DailyDeal.findOne({ StoreItem: purchaseParams.StoreItem }))!;
|
||||||
|
dailyDeal.AmountSold += 1;
|
||||||
|
await dailyDeal.save();
|
||||||
|
|
||||||
|
if (!config.dontSubtractPurchasePlatinumCost) {
|
||||||
|
updateCurrency(inventory, dailyDeal.SalePrice, true, purchaseResponse.InventoryChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config.noVendorPurchaseLimits) {
|
||||||
|
inventory.UsedDailyDeals.push(purchaseParams.StoreItem);
|
||||||
|
purchaseResponse.DailyDealUsed = purchaseParams.StoreItem;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const handleBundleAcqusition = async (
|
export const handleBundleAcqusition = async (
|
||||||
storeItemName: string,
|
storeItemName: string,
|
||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
@ -482,12 +540,57 @@ const handleBoosterPackPurchase = async (
|
|||||||
"attempt to roll over 100 booster packs in a single go. possible but unlikely to be desirable for the user or the server."
|
"attempt to roll over 100 booster packs in a single go. possible but unlikely to be desirable for the user or the server."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const specialItemReward = pack.components.find(x => x.PityIncreaseRate);
|
||||||
for (let i = 0; i != quantity; ++i) {
|
for (let i = 0; i != quantity; ++i) {
|
||||||
|
if (specialItemReward) {
|
||||||
|
{
|
||||||
|
const normalComponents = [];
|
||||||
|
for (const comp of pack.components) {
|
||||||
|
if (!comp.PityIncreaseRate) {
|
||||||
|
const { Probability, ...rest } = comp;
|
||||||
|
normalComponents.push({
|
||||||
|
...rest,
|
||||||
|
probability: Probability!
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const result = getRandomReward(normalComponents)!;
|
||||||
|
logger.debug(`booster pack rolled`, result);
|
||||||
|
purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};';
|
||||||
|
combineInventoryChanges(
|
||||||
|
purchaseResponse.InventoryChanges,
|
||||||
|
await addItem(inventory, result.Item, result.Amount)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inventory.WeaponSkins.some(x => x.ItemType == specialItemReward.Item)) {
|
||||||
|
inventory.SpecialItemRewardAttenuation ??= [];
|
||||||
|
let atten = inventory.SpecialItemRewardAttenuation.find(x => x.Tag == specialItemReward.Item);
|
||||||
|
if (!atten) {
|
||||||
|
atten =
|
||||||
|
inventory.SpecialItemRewardAttenuation[
|
||||||
|
inventory.SpecialItemRewardAttenuation.push({
|
||||||
|
Tag: specialItemReward.Item,
|
||||||
|
Atten: specialItemReward.Probability!
|
||||||
|
}) - 1
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (Math.random() < atten.Atten) {
|
||||||
|
purchaseResponse.BoosterPackItems += toStoreItem(specialItemReward.Item) + ',{"lvl":0};';
|
||||||
|
combineInventoryChanges(
|
||||||
|
purchaseResponse.InventoryChanges,
|
||||||
|
await addItem(inventory, specialItemReward.Item)
|
||||||
|
);
|
||||||
|
// TOVERIFY: Is the SpecialItemRewardAttenuation entry removed now?
|
||||||
|
} else {
|
||||||
|
atten.Atten += specialItemReward.PityIncreaseRate!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
const disallowedItems = new Set();
|
const disallowedItems = new Set();
|
||||||
for (let roll = 0; roll != pack.rarityWeightsPerRoll.length; ) {
|
for (let roll = 0; roll != pack.rarityWeightsPerRoll.length; ) {
|
||||||
const weights = pack.rarityWeightsPerRoll[roll];
|
const weights = pack.rarityWeightsPerRoll[roll];
|
||||||
const result = getRandomWeightedRewardUc(pack.components, weights);
|
const result = getRandomWeightedRewardUc(pack.components, weights)!;
|
||||||
if (result) {
|
|
||||||
logger.debug(`booster pack rolled`, result);
|
logger.debug(`booster pack rolled`, result);
|
||||||
if (disallowedItems.has(result.Item)) {
|
if (disallowedItems.has(result.Item)) {
|
||||||
logger.debug(`oops, can't use that one; trying again`);
|
logger.debug(`oops, can't use that one; trying again`);
|
||||||
@ -497,11 +600,14 @@ const handleBoosterPackPurchase = async (
|
|||||||
disallowedItems.add(result.Item);
|
disallowedItems.add(result.Item);
|
||||||
}
|
}
|
||||||
purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};';
|
purchaseResponse.BoosterPackItems += toStoreItem(result.Item) + ',{"lvl":0};';
|
||||||
combineInventoryChanges(purchaseResponse.InventoryChanges, await addItem(inventory, result.Item, 1));
|
combineInventoryChanges(
|
||||||
}
|
purchaseResponse.InventoryChanges,
|
||||||
|
await addItem(inventory, result.Item, result.Amount)
|
||||||
|
);
|
||||||
++roll;
|
++roll;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return purchaseResponse;
|
return purchaseResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import fissureMissions from "@/static/fixed_responses/worldState/fissureMissions
|
|||||||
import sortieTilesets from "@/static/fixed_responses/worldState/sortieTilesets.json";
|
import sortieTilesets from "@/static/fixed_responses/worldState/sortieTilesets.json";
|
||||||
import sortieTilesetMissions from "@/static/fixed_responses/worldState/sortieTilesetMissions.json";
|
import sortieTilesetMissions from "@/static/fixed_responses/worldState/sortieTilesetMissions.json";
|
||||||
import syndicateMissions from "@/static/fixed_responses/worldState/syndicateMissions.json";
|
import syndicateMissions from "@/static/fixed_responses/worldState/syndicateMissions.json";
|
||||||
|
import darvoDeals from "@/static/fixed_responses/worldState/darvoDeals.json";
|
||||||
import { buildConfig } from "@/src/services/buildConfigService";
|
import { buildConfig } from "@/src/services/buildConfigService";
|
||||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
@ -27,7 +28,7 @@ import {
|
|||||||
} from "../types/worldStateTypes";
|
} from "../types/worldStateTypes";
|
||||||
import { toMongoDate, toOid, version_compare } from "../helpers/inventoryHelpers";
|
import { toMongoDate, toOid, version_compare } from "../helpers/inventoryHelpers";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { Fissure } from "../models/worldStateModel";
|
import { DailyDeal, Fissure } from "../models/worldStateModel";
|
||||||
|
|
||||||
const sortieBosses = [
|
const sortieBosses = [
|
||||||
"SORTIE_BOSS_HYENA",
|
"SORTIE_BOSS_HYENA",
|
||||||
@ -1122,6 +1123,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
GlobalUpgrades: [],
|
GlobalUpgrades: [],
|
||||||
VoidTraders: [],
|
VoidTraders: [],
|
||||||
VoidStorms: [],
|
VoidStorms: [],
|
||||||
|
DailyDeals: [],
|
||||||
EndlessXpChoices: [],
|
EndlessXpChoices: [],
|
||||||
KnownCalendarSeasons: [],
|
KnownCalendarSeasons: [],
|
||||||
...staticWorldState,
|
...staticWorldState,
|
||||||
@ -1561,6 +1563,24 @@ export const populateFissures = async (worldState: IWorldState): Promise<void> =
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const populateDailyDeal = async (worldState: IWorldState): Promise<void> => {
|
||||||
|
const dailyDeals = await DailyDeal.find({});
|
||||||
|
for (const dailyDeal of dailyDeals) {
|
||||||
|
if (dailyDeal.Expiry.getTime() > Date.now()) {
|
||||||
|
worldState.DailyDeals.push({
|
||||||
|
StoreItem: dailyDeal.StoreItem,
|
||||||
|
Activation: toMongoDate(dailyDeal.Activation),
|
||||||
|
Expiry: toMongoDate(dailyDeal.Expiry),
|
||||||
|
Discount: dailyDeal.Discount,
|
||||||
|
OriginalPrice: dailyDeal.OriginalPrice,
|
||||||
|
SalePrice: dailyDeal.SalePrice,
|
||||||
|
AmountTotal: Math.round(dailyDeal.AmountTotal * (config.worldState?.darvoStockMultiplier ?? 1)),
|
||||||
|
AmountSold: dailyDeal.AmountSold
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const idToBountyCycle = (id: string): number => {
|
export const idToBountyCycle = (id: string): number => {
|
||||||
return Math.trunc((parseInt(id.substring(0, 8), 16) * 1000) / 9000_000);
|
return Math.trunc((parseInt(id.substring(0, 8), 16) * 1000) / 9000_000);
|
||||||
};
|
};
|
||||||
@ -1689,7 +1709,7 @@ const nightwaveTagToSeason: Record<string, number> = {
|
|||||||
RadioLegionSyndicate: 0 // The Wolf of Saturn Six
|
RadioLegionSyndicate: 0 // The Wolf of Saturn Six
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateWorldStateCollections = async (): Promise<void> => {
|
const updateFissures = async (): Promise<void> => {
|
||||||
const fissures = await Fissure.find();
|
const fissures = await Fissure.find();
|
||||||
|
|
||||||
const activeNodes = new Set<string>();
|
const activeNodes = new Set<string>();
|
||||||
@ -1742,3 +1762,38 @@ export const updateWorldStateCollections = async (): Promise<void> => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateDailyDeal = async (): Promise<void> => {
|
||||||
|
let darvoIndex = Math.trunc((Date.now() - 25200000) / (26 * unixTimesInMs.hour));
|
||||||
|
let darvoEnd;
|
||||||
|
do {
|
||||||
|
const darvoStart = darvoIndex * (26 * unixTimesInMs.hour) + 25200000;
|
||||||
|
darvoEnd = darvoStart + 26 * unixTimesInMs.hour;
|
||||||
|
const darvoOid = ((darvoStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "adc51a72f7324d95";
|
||||||
|
if (!(await DailyDeal.findById(darvoOid))) {
|
||||||
|
const seed = new SRng(darvoIndex).randomInt(0, 100_000);
|
||||||
|
const rng = new SRng(seed);
|
||||||
|
let deal;
|
||||||
|
do {
|
||||||
|
deal = rng.randomReward(darvoDeals)!; // Using an actual sampling collected over roughly a year because I can't extrapolate an algorithm from it with enough certainty.
|
||||||
|
//const [storeItem, meta] = rng.randomElement(Object.entries(darvoDeals))!;
|
||||||
|
//const discount = Math.min(rng.randomInt(1, 9) * 10, (meta as { MaxDiscount?: number }).MaxDiscount ?? 1);
|
||||||
|
} while (await DailyDeal.exists({ StoreItem: deal.StoreItem }));
|
||||||
|
await DailyDeal.insertOne({
|
||||||
|
_id: darvoOid,
|
||||||
|
StoreItem: deal.StoreItem,
|
||||||
|
Activation: new Date(darvoStart),
|
||||||
|
Expiry: new Date(darvoEnd),
|
||||||
|
Discount: deal.Discount,
|
||||||
|
OriginalPrice: deal.OriginalPrice,
|
||||||
|
SalePrice: deal.SalePrice, //Math.trunc(deal.OriginalPrice * (1 - discount))
|
||||||
|
AmountTotal: deal.AmountTotal,
|
||||||
|
AmountSold: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} while (darvoEnd < Date.now() + 6 * unixTimesInMs.minute && ++darvoIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateWorldStateCollections = async (): Promise<void> => {
|
||||||
|
await Promise.all([updateFissures(), updateDailyDeal()]);
|
||||||
|
};
|
||||||
|
@ -40,6 +40,7 @@ export interface IInventoryDatabase
|
|||||||
| "InfestedFoundry"
|
| "InfestedFoundry"
|
||||||
| "DialogueHistory"
|
| "DialogueHistory"
|
||||||
| "KubrowPetEggs"
|
| "KubrowPetEggs"
|
||||||
|
| "KubrowPetPrints"
|
||||||
| "PendingCoupon"
|
| "PendingCoupon"
|
||||||
| "Drones"
|
| "Drones"
|
||||||
| "RecentVendorPurchases"
|
| "RecentVendorPurchases"
|
||||||
@ -79,7 +80,8 @@ export interface IInventoryDatabase
|
|||||||
KahlLoadOuts: IOperatorConfigDatabase[];
|
KahlLoadOuts: IOperatorConfigDatabase[];
|
||||||
InfestedFoundry?: IInfestedFoundryDatabase;
|
InfestedFoundry?: IInfestedFoundryDatabase;
|
||||||
DialogueHistory?: IDialogueHistoryDatabase;
|
DialogueHistory?: IDialogueHistoryDatabase;
|
||||||
KubrowPetEggs?: IKubrowPetEggDatabase[];
|
KubrowPetEggs: IKubrowPetEggDatabase[];
|
||||||
|
KubrowPetPrints: IKubrowPetPrintDatabase[];
|
||||||
PendingCoupon?: IPendingCouponDatabase;
|
PendingCoupon?: IPendingCouponDatabase;
|
||||||
Drones: IDroneDatabase[];
|
Drones: IDroneDatabase[];
|
||||||
RecentVendorPurchases?: IRecentVendorPurchaseDatabase[];
|
RecentVendorPurchases?: IRecentVendorPurchaseDatabase[];
|
||||||
@ -287,6 +289,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
ArchwingEnabled?: boolean;
|
ArchwingEnabled?: boolean;
|
||||||
PendingSpectreLoadouts?: ISpectreLoadout[];
|
PendingSpectreLoadouts?: ISpectreLoadout[];
|
||||||
SpectreLoadouts?: ISpectreLoadout[];
|
SpectreLoadouts?: ISpectreLoadout[];
|
||||||
|
UsedDailyDeals: string[];
|
||||||
EmailItems: ITypeCount[];
|
EmailItems: ITypeCount[];
|
||||||
CompletedSyndicates: string[];
|
CompletedSyndicates: string[];
|
||||||
FocusXP?: IFocusXP;
|
FocusXP?: IFocusXP;
|
||||||
@ -295,7 +298,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
CompletedSorties: string[];
|
CompletedSorties: string[];
|
||||||
LastSortieReward?: ILastSortieRewardClient[];
|
LastSortieReward?: ILastSortieRewardClient[];
|
||||||
LastLiteSortieReward?: ILastSortieRewardClient[];
|
LastLiteSortieReward?: ILastSortieRewardClient[];
|
||||||
SortieRewardAttenuation?: ISortieRewardAttenuation[];
|
SortieRewardAttenuation?: IRewardAttenuation[];
|
||||||
Drones: IDroneClient[];
|
Drones: IDroneClient[];
|
||||||
StepSequencers: IStepSequencer[];
|
StepSequencers: IStepSequencer[];
|
||||||
ActiveAvatarImageType?: string;
|
ActiveAvatarImageType?: string;
|
||||||
@ -306,7 +309,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
FocusUpgrades: IFocusUpgrade[];
|
FocusUpgrades: IFocusUpgrade[];
|
||||||
HasContributedToDojo?: boolean;
|
HasContributedToDojo?: boolean;
|
||||||
HWIDProtectEnabled?: boolean;
|
HWIDProtectEnabled?: boolean;
|
||||||
//KubrowPetPrints: IKubrowPetPrint[];
|
KubrowPetPrints: IKubrowPetPrintClient[];
|
||||||
AlignmentReplay?: IAlignment;
|
AlignmentReplay?: IAlignment;
|
||||||
PersonalGoalProgress?: IPersonalGoalProgressClient[];
|
PersonalGoalProgress?: IPersonalGoalProgressClient[];
|
||||||
ThemeStyle: string;
|
ThemeStyle: string;
|
||||||
@ -351,7 +354,6 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
//LeagueTickets: any[];
|
//LeagueTickets: any[];
|
||||||
//Quests: any[];
|
//Quests: any[];
|
||||||
//Robotics: any[];
|
//Robotics: any[];
|
||||||
//UsedDailyDeals: any[];
|
|
||||||
LibraryPersonalTarget?: string;
|
LibraryPersonalTarget?: string;
|
||||||
LibraryPersonalProgress: ILibraryPersonalProgress[];
|
LibraryPersonalProgress: ILibraryPersonalProgress[];
|
||||||
CollectibleSeries?: ICollectibleEntry[];
|
CollectibleSeries?: ICollectibleEntry[];
|
||||||
@ -381,6 +383,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
HubNpcCustomizations?: IHubNpcCustomization[];
|
HubNpcCustomizations?: IHubNpcCustomization[];
|
||||||
Ship?: IOrbiter; // U22 and below, response only
|
Ship?: IOrbiter; // U22 and below, response only
|
||||||
ClaimedJunctionChallengeRewards?: string[]; // U39
|
ClaimedJunctionChallengeRewards?: string[]; // U39
|
||||||
|
SpecialItemRewardAttenuation?: IRewardAttenuation[]; // Baro's Void Surplus
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAffiliation {
|
export interface IAffiliation {
|
||||||
@ -722,8 +725,8 @@ export interface IKubrowPetEggDatabase {
|
|||||||
_id: Types.ObjectId;
|
_id: Types.ObjectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IKubrowPetPrint {
|
export interface IKubrowPetPrintClient {
|
||||||
ItemType: KubrowPetPrintItemType;
|
ItemType: "/Lotus/Types/Game/KubrowPet/ImprintedTraitPrint";
|
||||||
Name: string;
|
Name: string;
|
||||||
IsMale: boolean;
|
IsMale: boolean;
|
||||||
Size: number; // seems to be 0.7 to 1.0
|
Size: number; // seems to be 0.7 to 1.0
|
||||||
@ -733,6 +736,10 @@ export interface IKubrowPetPrint {
|
|||||||
InheritedModularParts?: any[];
|
InheritedModularParts?: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IKubrowPetPrintDatabase extends Omit<IKubrowPetPrintClient, "ItemId" | "InheritedModularParts"> {
|
||||||
|
_id: Types.ObjectId;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ITraits {
|
export interface ITraits {
|
||||||
BaseColor: string;
|
BaseColor: string;
|
||||||
SecondaryColor: string;
|
SecondaryColor: string;
|
||||||
@ -746,15 +753,11 @@ export interface ITraits {
|
|||||||
Tail?: string;
|
Tail?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum KubrowPetPrintItemType {
|
|
||||||
LotusTypesGameKubrowPetImprintedTraitPrint = "/Lotus/Types/Game/KubrowPet/ImprintedTraitPrint"
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IKubrowPetDetailsDatabase {
|
export interface IKubrowPetDetailsDatabase {
|
||||||
Name?: string;
|
Name?: string;
|
||||||
IsPuppy?: boolean;
|
IsPuppy?: boolean;
|
||||||
HasCollar: boolean;
|
HasCollar: boolean;
|
||||||
PrintsRemaining?: number;
|
PrintsRemaining: number;
|
||||||
Status: Status;
|
Status: Status;
|
||||||
HatchDate?: Date;
|
HatchDate?: Date;
|
||||||
DominantTraits: ITraits;
|
DominantTraits: ITraits;
|
||||||
@ -783,7 +786,7 @@ export interface ILastSortieRewardDatabase extends Omit<ILastSortieRewardClient,
|
|||||||
SortieId: Types.ObjectId;
|
SortieId: Types.ObjectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISortieRewardAttenuation {
|
export interface IRewardAttenuation {
|
||||||
Tag: string;
|
Tag: string;
|
||||||
Atten: number;
|
Atten: number;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,8 @@ import {
|
|||||||
ITypeCount,
|
ITypeCount,
|
||||||
IRecentVendorPurchaseClient,
|
IRecentVendorPurchaseClient,
|
||||||
TEquipmentKey,
|
TEquipmentKey,
|
||||||
ICrewMemberClient
|
ICrewMemberClient,
|
||||||
|
IKubrowPetPrintClient
|
||||||
} from "./inventoryTypes/inventoryTypes";
|
} from "./inventoryTypes/inventoryTypes";
|
||||||
|
|
||||||
export enum PurchaseSource {
|
export enum PurchaseSource {
|
||||||
@ -78,6 +79,7 @@ export type IInventoryChanges = {
|
|||||||
NewVendorPurchase?: IRecentVendorPurchaseClient; // >= 38.5.0
|
NewVendorPurchase?: IRecentVendorPurchaseClient; // >= 38.5.0
|
||||||
RecentVendorPurchases?: IRecentVendorPurchaseClient; // < 38.5.0
|
RecentVendorPurchases?: IRecentVendorPurchaseClient; // < 38.5.0
|
||||||
CrewMembers?: ICrewMemberClient[];
|
CrewMembers?: ICrewMemberClient[];
|
||||||
|
KubrowPetPrints?: IKubrowPetPrintClient[];
|
||||||
} & Record<
|
} & Record<
|
||||||
Exclude<
|
Exclude<
|
||||||
string,
|
string,
|
||||||
@ -105,6 +107,7 @@ export interface IPurchaseResponse {
|
|||||||
Standing?: IAffiliationMods[];
|
Standing?: IAffiliationMods[];
|
||||||
FreeFavorsUsed?: IAffiliationMods[];
|
FreeFavorsUsed?: IAffiliationMods[];
|
||||||
BoosterPackItems?: string;
|
BoosterPackItems?: string;
|
||||||
|
DailyDealUsed?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IBinChanges = {
|
export type IBinChanges = {
|
||||||
|
@ -15,6 +15,7 @@ export interface IWorldState {
|
|||||||
NodeOverrides: INodeOverride[];
|
NodeOverrides: INodeOverride[];
|
||||||
VoidTraders: IVoidTrader[];
|
VoidTraders: IVoidTrader[];
|
||||||
VoidStorms: IVoidStorm[];
|
VoidStorms: IVoidStorm[];
|
||||||
|
DailyDeals: IDailyDeal[];
|
||||||
PVPChallengeInstances: IPVPChallengeInstance[];
|
PVPChallengeInstances: IPVPChallengeInstance[];
|
||||||
EndlessXpChoices: IEndlessXpChoice[];
|
EndlessXpChoices: IEndlessXpChoice[];
|
||||||
SeasonInfo?: {
|
SeasonInfo?: {
|
||||||
@ -159,6 +160,7 @@ export interface IVoidTraderOffer {
|
|||||||
ItemType: string;
|
ItemType: string;
|
||||||
PrimePrice: number;
|
PrimePrice: number;
|
||||||
RegularPrice: number;
|
RegularPrice: number;
|
||||||
|
Limit?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVoidStorm {
|
export interface IVoidStorm {
|
||||||
@ -169,6 +171,28 @@ export interface IVoidStorm {
|
|||||||
ActiveMissionTier: string;
|
ActiveMissionTier: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IDailyDeal {
|
||||||
|
StoreItem: string;
|
||||||
|
Activation: IMongoDate;
|
||||||
|
Expiry: IMongoDate;
|
||||||
|
Discount: number;
|
||||||
|
OriginalPrice: number;
|
||||||
|
SalePrice: number;
|
||||||
|
AmountTotal: number;
|
||||||
|
AmountSold: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDailyDealDatabase {
|
||||||
|
StoreItem: string;
|
||||||
|
Activation: Date;
|
||||||
|
Expiry: Date;
|
||||||
|
Discount: number;
|
||||||
|
OriginalPrice: number;
|
||||||
|
SalePrice: number;
|
||||||
|
AmountTotal: number;
|
||||||
|
AmountSold: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IPVPChallengeInstance {
|
export interface IPVPChallengeInstance {
|
||||||
_id: IOid;
|
_id: IOid;
|
||||||
challengeTypeRefID: string;
|
challengeTypeRefID: string;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"evergreen": [
|
"evergreen": [
|
||||||
{ "ItemType": "/Lotus/StoreItems/Types/Keys/MummyQuestKeyBlueprint", "PrimePrice": 100, "RegularPrice": 25000 },
|
{ "ItemType": "/Lotus/StoreItems/Types/Keys/MummyQuestKeyBlueprint", "PrimePrice": 100, "RegularPrice": 25000 },
|
||||||
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/FootstepsMaple", "PrimePrice": 15, "RegularPrice": 1000 }
|
{ "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/FootstepsMaple", "PrimePrice": 15, "RegularPrice": 1000 },
|
||||||
|
{ "ItemType": "/Lotus/StoreItems/Types/BoosterPacks/BaroTreasureBox", "PrimePrice": 0, "RegularPrice": 50000, "Limit": 1 }
|
||||||
],
|
],
|
||||||
"armorSets": [
|
"armorSets": [
|
||||||
[
|
[
|
||||||
|
158
static/fixed_responses/worldState/darvoDeals.json
Normal file
158
static/fixed_responses/worldState/darvoDeals.json
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
[
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Archwing/DemolitionJetPack/DemolitionJetPack", "Discount": 60, "OriginalPrice": 275, "SalePrice": 110, "AmountTotal": 300, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Bard/Bard", "Discount": 30, "OriginalPrice": 225, "SalePrice": 157, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Ember/Ember", "Discount": 30, "OriginalPrice": 225, "SalePrice": 157, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Ember/Ember", "Discount": 60, "OriginalPrice": 225, "SalePrice": 90, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Magician/Magician", "Discount": 20, "OriginalPrice": 200, "SalePrice": 160, "AmountTotal": 200, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Magician/Magician", "Discount": 30, "OriginalPrice": 200, "SalePrice": 140, "AmountTotal": 200, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Magician/Magician", "Discount": 40, "OriginalPrice": 200, "SalePrice": 120, "AmountTotal": 200, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Magician/Magician", "Discount": 50, "OriginalPrice": 200, "SalePrice": 100, "AmountTotal": 200, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Sandman/Sandman", "Discount": 20, "OriginalPrice": 225, "SalePrice": 180, "AmountTotal": 100, "probability": 4 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Sandman/Sandman", "Discount": 30, "OriginalPrice": 225, "SalePrice": 157, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Trapper/Trapper", "Discount": 40, "OriginalPrice": 300, "SalePrice": 180, "AmountTotal": 150, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Powersuits/Trapper/Trapper", "Discount": 50, "OriginalPrice": 300, "SalePrice": 150, "AmountTotal": 100, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Game/CatbrowPet/CatbrowGeneticSignature", "Discount": 20, "OriginalPrice": 5, "SalePrice": 4, "AmountTotal": 500, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Game/CatbrowPet/CatbrowGeneticSignature", "Discount": 30, "OriginalPrice": 5, "SalePrice": 3, "AmountTotal": 415, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Game/KubrowPet/Eggs/KubrowEgg", "Discount": 50, "OriginalPrice": 10, "SalePrice": 5, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Game/KubrowPet/Eggs/KubrowEgg", "Discount": 60, "OriginalPrice": 10, "SalePrice": 4, "AmountTotal": 100, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Forma", "Discount": 30, "OriginalPrice": 20, "SalePrice": 14, "AmountTotal": 150, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Forma", "Discount": 45, "OriginalPrice": 20, "SalePrice": 11, "AmountTotal": 150, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/OrokinReactor", "Discount": 40, "OriginalPrice": 20, "SalePrice": 12, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/BioComponent", "Discount": 10, "OriginalPrice": 10, "SalePrice": 9, "AmountTotal": 200, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/BioComponent", "Discount": 20, "OriginalPrice": 10, "SalePrice": 8, "AmountTotal": 165, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/BioComponent", "Discount": 30, "OriginalPrice": 10, "SalePrice": 7, "AmountTotal": 135, "probability": 5 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/BioComponent", "Discount": 40, "OriginalPrice": 10, "SalePrice": 6, "AmountTotal": 100, "probability": 5 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/ChemComponent", "Discount": 10, "OriginalPrice": 10, "SalePrice": 9, "AmountTotal": 200, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/ChemComponent", "Discount": 20, "OriginalPrice": 10, "SalePrice": 8, "AmountTotal": 165, "probability": 5 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/ChemComponent", "Discount": 30, "OriginalPrice": 10, "SalePrice": 7, "AmountTotal": 135, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/EnergyComponent", "Discount": 10, "OriginalPrice": 10, "SalePrice": 9, "AmountTotal": 200, "probability": 5 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/EnergyComponent", "Discount": 20, "OriginalPrice": 10, "SalePrice": 8, "AmountTotal": 165, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/EnergyComponent", "Discount": 30, "OriginalPrice": 10, "SalePrice": 7, "AmountTotal": 135, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Types/Items/Research/EnergyComponent", "Discount": 40, "OriginalPrice": 10, "SalePrice": 6, "AmountTotal": 100, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/AttackLensGreater", "Discount": 10, "OriginalPrice": 40, "SalePrice": 36, "AmountTotal": 150, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/AttackLensGreater", "Discount": 20, "OriginalPrice": 40, "SalePrice": 32, "AmountTotal": 125, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/AttackLensGreater", "Discount": 40, "OriginalPrice": 40, "SalePrice": 24, "AmountTotal": 75, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/DefenseLensGreater", "Discount": 10, "OriginalPrice": 40, "SalePrice": 36, "AmountTotal": 150, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/DefenseLensGreater", "Discount": 40, "OriginalPrice": 40, "SalePrice": 24, "AmountTotal": 75, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/DefenseLensGreater", "Discount": 50, "OriginalPrice": 40, "SalePrice": 20, "AmountTotal": 50, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/PowerLensGreater", "Discount": 50, "OriginalPrice": 40, "SalePrice": 20, "AmountTotal": 50, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/TacticLensGreater", "Discount": 10, "OriginalPrice": 40, "SalePrice": 36, "AmountTotal": 150, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/TacticLensGreater", "Discount": 20, "OriginalPrice": 40, "SalePrice": 32, "AmountTotal": 125, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/TacticLensGreater", "Discount": 30, "OriginalPrice": 40, "SalePrice": 28, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/TacticLensGreater", "Discount": 40, "OriginalPrice": 40, "SalePrice": 24, "AmountTotal": 75, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/TacticLensGreater", "Discount": 50, "OriginalPrice": 40, "SalePrice": 20, "AmountTotal": 50, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Upgrades/Focus/WardLensGreater", "Discount": 40, "OriginalPrice": 40, "SalePrice": 24, "AmountTotal": 75, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Bow/Longbow/CrpBow", "Discount": 20, "OriginalPrice": 235, "SalePrice": 188, "AmountTotal": 300, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Bow/Longbow/CrpBow", "Discount": 30, "OriginalPrice": 235, "SalePrice": 164, "AmountTotal": 250, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Bow/Longbow/CrpBow", "Discount": 50, "OriginalPrice": 235, "SalePrice": 117, "AmountTotal": 150, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Bow/Longbow/CrpBow", "Discount": 60, "OriginalPrice": 235, "SalePrice": 94, "AmountTotal": 100, "probability": 5 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Melee/KickAndPunch/KickPunchWeapon", "Discount": 20, "OriginalPrice": 125, "SalePrice": 100, "AmountTotal": 100, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Melee/KickAndPunch/KickPunchWeapon", "Discount": 30, "OriginalPrice": 125, "SalePrice": 87, "AmountTotal": 90, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Melee/KickAndPunch/KickPunchWeapon", "Discount": 60, "OriginalPrice": 125, "SalePrice": 50, "AmountTotal": 65, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Pistols/CorpusMinigun/CorpusMinigun", "Discount": 30, "OriginalPrice": 175, "SalePrice": 122, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Pistols/CorpusMinigun/CorpusMinigun", "Discount": 40, "OriginalPrice": 175, "SalePrice": 105, "AmountTotal": 90, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Pistols/CorpusMinigun/CorpusMinigun", "Discount": 50, "OriginalPrice": 175, "SalePrice": 87, "AmountTotal": 80, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Pistols/CorpusMinigun/CorpusMinigun", "Discount": 60, "OriginalPrice": 175, "SalePrice": 70, "AmountTotal": 70, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Corpus/Pistols/CorpusMinigun/CorpusMinigun", "Discount": 70, "OriginalPrice": 175, "SalePrice": 52, "AmountTotal": 60, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/GrineerPistol/GrineerLightPistol", "Discount": 10, "OriginalPrice": 75, "SalePrice": 67, "AmountTotal": 100, "probability": 6 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/GrineerPistol/GrineerLightPistol", "Discount": 20, "OriginalPrice": 75, "SalePrice": 60, "AmountTotal": 100, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/GrineerPistol/GrineerLightPistol", "Discount": 30, "OriginalPrice": 75, "SalePrice": 52, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/LongGuns/BurstRifle/GrnBurstRifle", "Discount": 30, "OriginalPrice": 225, "SalePrice": 157, "AmountTotal": 500, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/LongGuns/BurstRifle/GrnBurstRifle", "Discount": 40, "OriginalPrice": 225, "SalePrice": 135, "AmountTotal": 500, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/LongGuns/BurstRifle/GrnBurstRifle", "Discount": 60, "OriginalPrice": 225, "SalePrice": 90, "AmountTotal": 500, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/LongGuns/GrnSpark/GrnSparkRifle", "Discount": 20, "OriginalPrice": 150, "SalePrice": 120, "AmountTotal": 300, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/LongGuns/GrnSpark/GrnSparkRifle", "Discount": 30, "OriginalPrice": 150, "SalePrice": 105, "AmountTotal": 250, "probability": 4 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/LongGuns/GrnSpark/GrnSparkRifle", "Discount": 50, "OriginalPrice": 150, "SalePrice": 75, "AmountTotal": 150, "probability": 4 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/Melee/GrineerMachetteAndCleaver/DualCleaverWeapon", "Discount": 30, "OriginalPrice": 225, "SalePrice": 157, "AmountTotal": 200, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/Melee/GrineerMachetteAndCleaver/DualCleaverWeapon", "Discount": 40, "OriginalPrice": 225, "SalePrice": 135, "AmountTotal": 175, "probability": 4 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/Melee/GrineerMachetteAndCleaver/DualCleaverWeapon", "Discount": 50, "OriginalPrice": 225, "SalePrice": 112, "AmountTotal": 150, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/Melee/GrineerMachetteAndCleaver/DualCleaverWeapon", "Discount": 60, "OriginalPrice": 225, "SalePrice": 90, "AmountTotal": 125, "probability": 5 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Grineer/Melee/GrineerMachetteAndCleaver/DualCleaverWeapon", "Discount": 70, "OriginalPrice": 225, "SalePrice": 67, "AmountTotal": 100, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Infested/Melee/Swords/Mire/MireSword", "Discount": 10, "OriginalPrice": 150, "SalePrice": 135, "AmountTotal": 300, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Infested/Melee/Swords/Mire/MireSword", "Discount": 20, "OriginalPrice": 150, "SalePrice": 120, "AmountTotal": 270, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Infested/Melee/Swords/Mire/MireSword", "Discount": 30, "OriginalPrice": 150, "SalePrice": 105, "AmountTotal": 240, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Infested/Melee/Swords/Mire/MireSword", "Discount": 40, "OriginalPrice": 150, "SalePrice": 90, "AmountTotal": 205, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Infested/Melee/Swords/Mire/MireSword", "Discount": 60, "OriginalPrice": 150, "SalePrice": 60, "AmountTotal": 145, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Infested/Melee/Swords/Mire/MireSword", "Discount": 80, "OriginalPrice": 150, "SalePrice": 30, "AmountTotal": 80, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Akimbo/AkimboShotGun", "Discount": 20, "OriginalPrice": 225, "SalePrice": 180, "AmountTotal": 200, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Akimbo/AkimboShotGun", "Discount": 40, "OriginalPrice": 225, "SalePrice": 135, "AmountTotal": 165, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Akimbo/AkimboShotGun", "Discount": 50, "OriginalPrice": 225, "SalePrice": 112, "AmountTotal": 150, "probability": 5 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Dagger/Dagger", "Discount": 30, "OriginalPrice": 75, "SalePrice": 52, "AmountTotal": 350, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Dagger/Dagger", "Discount": 40, "OriginalPrice": 75, "SalePrice": 45, "AmountTotal": 300, "probability": 7 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Dagger/Dagger", "Discount": 50, "OriginalPrice": 75, "SalePrice": 37, "AmountTotal": 250, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Dagger/Dagger", "Discount": 60, "OriginalPrice": 75, "SalePrice": 30, "AmountTotal": 200, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/DualShortSword/DualHeatSwords", "Discount": 30, "OriginalPrice": 175, "SalePrice": 122, "AmountTotal": 200, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/DualShortSword/DualHeatSwords", "Discount": 70, "OriginalPrice": 175, "SalePrice": 52, "AmountTotal": 200, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Fist/Fist", "Discount": 10, "OriginalPrice": 125, "SalePrice": 112, "AmountTotal": 500, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Fist/Fist", "Discount": 20, "OriginalPrice": 125, "SalePrice": 100, "AmountTotal": 250, "probability": 6 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Gauntlet/Gauntlet", "Discount": 20, "OriginalPrice": 125, "SalePrice": 100, "AmountTotal": 100, "probability": 5 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Gauntlet/Gauntlet", "Discount": 30, "OriginalPrice": 125, "SalePrice": 87, "AmountTotal": 125, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Gauntlet/Gauntlet", "Discount": 40, "OriginalPrice": 125, "SalePrice": 75, "AmountTotal": 150, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Glaives/Boomerang/BoomerangWeapon", "Discount": 30, "OriginalPrice": 150, "SalePrice": 105, "AmountTotal": 300, "probability": 4 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Glaives/Boomerang/BoomerangWeapon", "Discount": 40, "OriginalPrice": 150, "SalePrice": 90, "AmountTotal": 250, "probability": 4 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Glaives/Boomerang/BoomerangWeapon", "Discount": 50, "OriginalPrice": 150, "SalePrice": 75, "AmountTotal": 200, "probability": 5 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Hammer/IceHammer/IceHammer", "Discount": 20, "OriginalPrice": 165, "SalePrice": 132, "AmountTotal": 300, "probability": 4 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Hammer/IceHammer/IceHammer", "Discount": 30, "OriginalPrice": 165, "SalePrice": 115, "AmountTotal": 250, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Hammer/IceHammer/IceHammer", "Discount": 40, "OriginalPrice": 165, "SalePrice": 99, "AmountTotal": 200, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Hammer/IceHammer/IceHammer", "Discount": 50, "OriginalPrice": 165, "SalePrice": 82, "AmountTotal": 150, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Hammer/IceHammer/IceHammer", "Discount": 60, "OriginalPrice": 165, "SalePrice": 66, "AmountTotal": 100, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/LongSword/LongSword", "Discount": 50, "OriginalPrice": 150, "SalePrice": 75, "AmountTotal": 300, "probability": 4 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/LongSword/LongSword", "Discount": 60, "OriginalPrice": 150, "SalePrice": 60, "AmountTotal": 265, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/LongSword/LongSword", "Discount": 70, "OriginalPrice": 150, "SalePrice": 45, "AmountTotal": 225, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/LongSword/LongSword", "Discount": 90, "OriginalPrice": 150, "SalePrice": 15, "AmountTotal": 150, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Scythe/EtherScytheWeapon", "Discount": 40, "OriginalPrice": 230, "SalePrice": 138, "AmountTotal": 250, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Scythe/EtherScytheWeapon", "Discount": 60, "OriginalPrice": 230, "SalePrice": 92, "AmountTotal": 150, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/GreatSword/TennoGreatSword", "Discount": 20, "OriginalPrice": 175, "SalePrice": 140, "AmountTotal": 100, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/GreatSword/TennoGreatSword", "Discount": 30, "OriginalPrice": 175, "SalePrice": 122, "AmountTotal": 100, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/GreatSword/TennoGreatSword", "Discount": 40, "OriginalPrice": 175, "SalePrice": 105, "AmountTotal": 100, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/GreatSword/TennoGreatSword", "Discount": 90, "OriginalPrice": 175, "SalePrice": 17, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{
|
||||||
|
"StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/SwordsAndBoards/MeleeContestWinnerOne/TennoSwordShield",
|
||||||
|
"Discount": 30,
|
||||||
|
"OriginalPrice": 150,
|
||||||
|
"SalePrice": 105,
|
||||||
|
"AmountTotal": 100,
|
||||||
|
"probability": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/SwordsAndBoards/MeleeContestWinnerOne/TennoSwordShield",
|
||||||
|
"Discount": 70,
|
||||||
|
"OriginalPrice": 150,
|
||||||
|
"SalePrice": 45,
|
||||||
|
"AmountTotal": 100,
|
||||||
|
"probability": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Melee/SwordsAndBoards/MeleeContestWinnerOne/TennoSwordShield",
|
||||||
|
"Discount": 90,
|
||||||
|
"OriginalPrice": 150,
|
||||||
|
"SalePrice": 15,
|
||||||
|
"AmountTotal": 100,
|
||||||
|
"probability": 1
|
||||||
|
},
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/CrossBow", "Discount": 30, "OriginalPrice": 175, "SalePrice": 122, "AmountTotal": 300, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/CrossBow", "Discount": 40, "OriginalPrice": 175, "SalePrice": 105, "AmountTotal": 250, "probability": 6 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/CrossBow", "Discount": 50, "OriginalPrice": 175, "SalePrice": 87, "AmountTotal": 200, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/CrossBow", "Discount": 60, "OriginalPrice": 175, "SalePrice": 70, "AmountTotal": 150, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/HandShotGun", "Discount": 20, "OriginalPrice": 190, "SalePrice": 152, "AmountTotal": 300, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/HandShotGun", "Discount": 30, "OriginalPrice": 190, "SalePrice": 133, "AmountTotal": 200, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/HandShotGun", "Discount": 40, "OriginalPrice": 190, "SalePrice": 114, "AmountTotal": 100, "probability": 5 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/RevolverPistol", "Discount": 20, "OriginalPrice": 190, "SalePrice": 152, "AmountTotal": 200, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/RevolverPistol", "Discount": 30, "OriginalPrice": 190, "SalePrice": 133, "AmountTotal": 150, "probability": 4 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/RevolverPistol", "Discount": 40, "OriginalPrice": 190, "SalePrice": 114, "AmountTotal": 100, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistol/RevolverPistol", "Discount": 50, "OriginalPrice": 190, "SalePrice": 95, "AmountTotal": 50, "probability": 4 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistols/TnBardPistol/TnBardPistolGun", "Discount": 20, "OriginalPrice": 190, "SalePrice": 152, "AmountTotal": 300, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistols/TnBardPistol/TnBardPistolGun", "Discount": 30, "OriginalPrice": 190, "SalePrice": 133, "AmountTotal": 250, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistols/TnBardPistol/TnBardPistolGun", "Discount": 40, "OriginalPrice": 190, "SalePrice": 114, "AmountTotal": 200, "probability": 2 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistols/TnBardPistol/TnBardPistolGun", "Discount": 50, "OriginalPrice": 190, "SalePrice": 95, "AmountTotal": 150, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Pistols/TnBardPistol/TnBardPistolGun", "Discount": 60, "OriginalPrice": 190, "SalePrice": 76, "AmountTotal": 100, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Rifle/TennoSniperRifle", "Discount": 10, "OriginalPrice": 250, "SalePrice": 225, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Rifle/TennoSniperRifle", "Discount": 30, "OriginalPrice": 250, "SalePrice": 175, "AmountTotal": 100, "probability": 3 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Rifle/TennoSniperRifle", "Discount": 50, "OriginalPrice": 250, "SalePrice": 125, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Shotgun/QuadShotgun", "Discount": 50, "OriginalPrice": 225, "SalePrice": 112, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/Shotgun/QuadShotgun", "Discount": 70, "OriginalPrice": 225, "SalePrice": 67, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/ThrowingWeapons/Kunai", "Discount": 10, "OriginalPrice": 175, "SalePrice": 157, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/ThrowingWeapons/Kunai", "Discount": 20, "OriginalPrice": 175, "SalePrice": 140, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/ThrowingWeapons/Kunai", "Discount": 30, "OriginalPrice": 175, "SalePrice": 122, "AmountTotal": 100, "probability": 1 },
|
||||||
|
{ "StoreItem": "/Lotus/StoreItems/Weapons/Tenno/ThrowingWeapons/Kunai", "Discount": 40, "OriginalPrice": 175, "SalePrice": 105, "AmountTotal": 100, "probability": 2 }
|
||||||
|
]
|
@ -510,18 +510,6 @@
|
|||||||
"PrimeAccessAvailability": { "State": "PRIME1" },
|
"PrimeAccessAvailability": { "State": "PRIME1" },
|
||||||
"PrimeVaultAvailabilities": [false, false, false, false, false],
|
"PrimeVaultAvailabilities": [false, false, false, false, false],
|
||||||
"PrimeTokenAvailability": true,
|
"PrimeTokenAvailability": true,
|
||||||
"DailyDeals": [
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Upgrades/Focus/PowerLensGreater",
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715058000000" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Discount": 50,
|
|
||||||
"OriginalPrice": 40,
|
|
||||||
"SalePrice": 20,
|
|
||||||
"AmountTotal": 50,
|
|
||||||
"AmountSold": 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"LibraryInfo": { "LastCompletedTargetType": "/Lotus/Types/Game/Library/Targets/Research7Target" },
|
"LibraryInfo": { "LastCompletedTargetType": "/Lotus/Types/Game/Library/Targets/Research7Target" },
|
||||||
"PVPChallengeInstances": [
|
"PVPChallengeInstances": [
|
||||||
{
|
{
|
||||||
|
@ -780,6 +780,10 @@
|
|||||||
<input class="form-check-input" type="checkbox" id="unlockAllSimarisResearchEntries" />
|
<input class="form-check-input" type="checkbox" id="unlockAllSimarisResearchEntries" />
|
||||||
<label class="form-check-label" for="unlockAllSimarisResearchEntries" data-loc="cheats_unlockAllSimarisResearchEntries"></label>
|
<label class="form-check-label" for="unlockAllSimarisResearchEntries" data-loc="cheats_unlockAllSimarisResearchEntries"></label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="disableDailyTribute" />
|
||||||
|
<label class="form-check-label" for="disableDailyTribute" data-loc="cheats_disableDailyTribute"></label>
|
||||||
|
</div>
|
||||||
<form class="form-group mt-2" onsubmit="doSaveConfigInt('spoofMasteryRank'); return false;">
|
<form class="form-group mt-2" onsubmit="doSaveConfigInt('spoofMasteryRank'); return false;">
|
||||||
<label class="form-label" for="spoofMasteryRank" data-loc="cheats_spoofMasteryRank"></label>
|
<label class="form-label" for="spoofMasteryRank" data-loc="cheats_spoofMasteryRank"></label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
@ -911,6 +915,13 @@
|
|||||||
<button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
|
<button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<form class="form-group mt-2" onsubmit="doSaveConfigFloat('worldState.darvoStockMultiplier'); return false;">
|
||||||
|
<label class="form-label" for="worldState.circuitGameModes" data-loc="worldState_darvoStockMultiplier"></label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input id="worldState.darvoStockMultiplier" class="form-control" type="number" step="0.01" placeholder="1" />
|
||||||
|
<button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1931,6 +1931,16 @@ function doSaveConfigInt(id) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function doSaveConfigFloat(id) {
|
||||||
|
$.post({
|
||||||
|
url: "/custom/setConfig?" + window.authz + "&wsid=" + wsid,
|
||||||
|
contentType: "application/json",
|
||||||
|
data: JSON.stringify({
|
||||||
|
[id]: parseFloat(document.getElementById(id).value)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function doSaveConfigStringArray(id) {
|
function doSaveConfigStringArray(id) {
|
||||||
$.post({
|
$.post({
|
||||||
url: "/custom/setConfig?" + window.authz + "&wsid=" + wsid,
|
url: "/custom/setConfig?" + window.authz + "&wsid=" + wsid,
|
||||||
@ -1967,8 +1977,6 @@ single.getRoute("/webui/cheats").on("beforeload", function () {
|
|||||||
if (x != null) {
|
if (x != null) {
|
||||||
if (x.type == "checkbox") {
|
if (x.type == "checkbox") {
|
||||||
x.checked = value;
|
x.checked = value;
|
||||||
} else if (x.type == "number") {
|
|
||||||
x.setAttribute("value", value);
|
|
||||||
} else if (x.classList.contains("tags-input")) {
|
} else if (x.classList.contains("tags-input")) {
|
||||||
x.value = value.join(", ");
|
x.value = value.join(", ");
|
||||||
x.oninput();
|
x.oninput();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// German translation by Animan8000
|
// German translation by Animan8000
|
||||||
dict = {
|
dict = {
|
||||||
general_inventoryUpdateNote: `Hinweis: Änderungen, die hier vorgenommen werden, werden erst im Spiel angewendet, sobald das Inventar synchronisiert wird. Die Sternenkarte zu besuchen, sollte der einfachste Weg sein, dies auszulösen.`,
|
general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command, visiting a dojo/relay, or relogging.`,
|
||||||
general_addButton: `Hinzufügen`,
|
general_addButton: `Hinzufügen`,
|
||||||
general_setButton: `[UNTRANSLATED] Set`,
|
general_setButton: `[UNTRANSLATED] Set`,
|
||||||
general_removeButton: `[UNTRANSLATED] Remove`,
|
general_removeButton: `[UNTRANSLATED] Remove`,
|
||||||
@ -182,6 +182,7 @@ dict = {
|
|||||||
cheats_fastClanAscension: `Schneller Clan-Aufstieg`,
|
cheats_fastClanAscension: `Schneller Clan-Aufstieg`,
|
||||||
cheats_missionsCanGiveAllRelics: `[UNTRANSLATED] Missions Can Give All Relics`,
|
cheats_missionsCanGiveAllRelics: `[UNTRANSLATED] Missions Can Give All Relics`,
|
||||||
cheats_unlockAllSimarisResearchEntries: `[UNTRANSLATED] Unlock All Simaris Research Entries`,
|
cheats_unlockAllSimarisResearchEntries: `[UNTRANSLATED] Unlock All Simaris Research Entries`,
|
||||||
|
cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
|
||||||
cheats_spoofMasteryRank: `Gefälschter Meisterschaftsrang (-1 zum deaktivieren)`,
|
cheats_spoofMasteryRank: `Gefälschter Meisterschaftsrang (-1 zum deaktivieren)`,
|
||||||
cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
|
cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
|
||||||
cheats_save: `[UNTRANSLATED] Save`,
|
cheats_save: `[UNTRANSLATED] Save`,
|
||||||
@ -238,6 +239,7 @@ dict = {
|
|||||||
worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`,
|
worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`,
|
||||||
worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`,
|
worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`,
|
||||||
worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`,
|
worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`,
|
||||||
|
worldState_darvoStockMultiplier: `[UNTRANSLATED] Darvo Stock Multiplier`,
|
||||||
|
|
||||||
import_importNote: `Du kannst hier eine vollständige oder teilweise Inventarantwort (Client-Darstellung) einfügen. Alle Felder, die vom Importer unterstützt werden, <b>werden in deinem Account überschrieben</b>.`,
|
import_importNote: `Du kannst hier eine vollständige oder teilweise Inventarantwort (Client-Darstellung) einfügen. Alle Felder, die vom Importer unterstützt werden, <b>werden in deinem Account überschrieben</b>.`,
|
||||||
import_submit: `Absenden`,
|
import_submit: `Absenden`,
|
||||||
@ -262,7 +264,7 @@ dict = {
|
|||||||
upgrade_WarframeGlobeEffectEnergy: `[UNTRANSLATED] +|VAL|% Energy Orb Effectiveness`,
|
upgrade_WarframeGlobeEffectEnergy: `[UNTRANSLATED] +|VAL|% Energy Orb Effectiveness`,
|
||||||
upgrade_WarframeGlobeEffectHealth: `[UNTRANSLATED] +|VAL|% Health Orb Effectiveness`,
|
upgrade_WarframeGlobeEffectHealth: `[UNTRANSLATED] +|VAL|% Health Orb Effectiveness`,
|
||||||
upgrade_WarframeHealthMax: `[UNTRANSLATED] +|VAL| Health`,
|
upgrade_WarframeHealthMax: `[UNTRANSLATED] +|VAL| Health`,
|
||||||
upgrade_WarframeHPBoostFromImpact: `[UNTRANSLATED] +|VAL1| Health per enemy killed with Blast Damage (Max |VAL2| Health)`,
|
upgrade_WarframeHPBoostFromImpact: `[UNTRANSLATED] +|VAL1| Health on kill with Blast Damage (Max |VAL2| Health)`,
|
||||||
upgrade_WarframeParkourVelocity: `[UNTRANSLATED] +|VAL|% Parkour Velocity`,
|
upgrade_WarframeParkourVelocity: `[UNTRANSLATED] +|VAL|% Parkour Velocity`,
|
||||||
upgrade_WarframeRadiationDamageBoost: `[UNTRANSLATED] +|VAL|% Ability Damage on enemies affected by Radiation Status`,
|
upgrade_WarframeRadiationDamageBoost: `[UNTRANSLATED] +|VAL|% Ability Damage on enemies affected by Radiation Status`,
|
||||||
upgrade_WarframeRegen: `[UNTRANSLATED] +|VAL| Health Regen/s`,
|
upgrade_WarframeRegen: `[UNTRANSLATED] +|VAL| Health Regen/s`,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
dict = {
|
dict = {
|
||||||
general_inventoryUpdateNote: `Note: Changes made here will only be applied in-game when the game syncs the inventory. Visiting the navigation should be the easiest way to trigger that.`,
|
general_inventoryUpdateNote: `Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command, visiting a dojo/relay, or relogging.`,
|
||||||
general_addButton: `Add`,
|
general_addButton: `Add`,
|
||||||
general_setButton: `Set`,
|
general_setButton: `Set`,
|
||||||
general_removeButton: `Remove`,
|
general_removeButton: `Remove`,
|
||||||
@ -181,6 +181,7 @@ dict = {
|
|||||||
cheats_fastClanAscension: `Fast Clan Ascension`,
|
cheats_fastClanAscension: `Fast Clan Ascension`,
|
||||||
cheats_missionsCanGiveAllRelics: `Missions Can Give All Relics`,
|
cheats_missionsCanGiveAllRelics: `Missions Can Give All Relics`,
|
||||||
cheats_unlockAllSimarisResearchEntries: `Unlock All Simaris Research Entries`,
|
cheats_unlockAllSimarisResearchEntries: `Unlock All Simaris Research Entries`,
|
||||||
|
cheats_disableDailyTribute: `Disable Daily Tribute`,
|
||||||
cheats_spoofMasteryRank: `Spoofed Mastery Rank (-1 to disable)`,
|
cheats_spoofMasteryRank: `Spoofed Mastery Rank (-1 to disable)`,
|
||||||
cheats_nightwaveStandingMultiplier: `Nightwave Standing Multiplier`,
|
cheats_nightwaveStandingMultiplier: `Nightwave Standing Multiplier`,
|
||||||
cheats_save: `Save`,
|
cheats_save: `Save`,
|
||||||
@ -237,6 +238,7 @@ dict = {
|
|||||||
worldState_allAtOnceNormal: `All At Once, Normal`,
|
worldState_allAtOnceNormal: `All At Once, Normal`,
|
||||||
worldState_allAtOnceSteelPath: `All At Once, Steel Path`,
|
worldState_allAtOnceSteelPath: `All At Once, Steel Path`,
|
||||||
worldState_theCircuitOverride: `The Circuit Override`,
|
worldState_theCircuitOverride: `The Circuit Override`,
|
||||||
|
worldState_darvoStockMultiplier: `Darvo Stock Multiplier`,
|
||||||
|
|
||||||
import_importNote: `You can provide a full or partial inventory response (client respresentation) here. All fields that are supported by the importer <b>will be overwritten</b> in your account.`,
|
import_importNote: `You can provide a full or partial inventory response (client respresentation) here. All fields that are supported by the importer <b>will be overwritten</b> in your account.`,
|
||||||
import_submit: `Submit`,
|
import_submit: `Submit`,
|
||||||
@ -261,7 +263,7 @@ dict = {
|
|||||||
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% Energy Orb Effectiveness`,
|
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% Energy Orb Effectiveness`,
|
||||||
upgrade_WarframeGlobeEffectHealth: `+|VAL|% Health Orb Effectiveness`,
|
upgrade_WarframeGlobeEffectHealth: `+|VAL|% Health Orb Effectiveness`,
|
||||||
upgrade_WarframeHealthMax: `+|VAL| Health`,
|
upgrade_WarframeHealthMax: `+|VAL| Health`,
|
||||||
upgrade_WarframeHPBoostFromImpact: `+|VAL1| Health per enemy killed with Blast Damage (Max |VAL2| Health)`,
|
upgrade_WarframeHPBoostFromImpact: `+|VAL1| Health on kill with Blast Damage (Max |VAL2| Health)`,
|
||||||
upgrade_WarframeParkourVelocity: `+|VAL|% Parkour Velocity`,
|
upgrade_WarframeParkourVelocity: `+|VAL|% Parkour Velocity`,
|
||||||
upgrade_WarframeRadiationDamageBoost: `+|VAL|% Ability Damage on enemies affected by Radiation Status`,
|
upgrade_WarframeRadiationDamageBoost: `+|VAL|% Ability Damage on enemies affected by Radiation Status`,
|
||||||
upgrade_WarframeRegen: `+|VAL| Health Regen/s`,
|
upgrade_WarframeRegen: `+|VAL| Health Regen/s`,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Spanish translation by hxedcl
|
// Spanish translation by hxedcl
|
||||||
dict = {
|
dict = {
|
||||||
general_inventoryUpdateNote: `Nota: Los cambios realizados aquí se reflejarán en el juego cuando este sincronice el inventario. Usar la navegación debería ser la forma más sencilla de activar esto.`,
|
general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command, visiting a dojo/relay, or relogging.`,
|
||||||
general_addButton: `Agregar`,
|
general_addButton: `Agregar`,
|
||||||
general_setButton: `[UNTRANSLATED] Set`,
|
general_setButton: `[UNTRANSLATED] Set`,
|
||||||
general_removeButton: `[UNTRANSLATED] Remove`,
|
general_removeButton: `[UNTRANSLATED] Remove`,
|
||||||
@ -182,6 +182,7 @@ dict = {
|
|||||||
cheats_fastClanAscension: `Ascenso rápido del clan`,
|
cheats_fastClanAscension: `Ascenso rápido del clan`,
|
||||||
cheats_missionsCanGiveAllRelics: `Las misiones pueden otorgar todas las reliquias`,
|
cheats_missionsCanGiveAllRelics: `Las misiones pueden otorgar todas las reliquias`,
|
||||||
cheats_unlockAllSimarisResearchEntries: `Desbloquear todas las entradas de investigación de Simaris`,
|
cheats_unlockAllSimarisResearchEntries: `Desbloquear todas las entradas de investigación de Simaris`,
|
||||||
|
cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
|
||||||
cheats_spoofMasteryRank: `Rango de maestría simulado (-1 para desactivar)`,
|
cheats_spoofMasteryRank: `Rango de maestría simulado (-1 para desactivar)`,
|
||||||
cheats_nightwaveStandingMultiplier: `Multiplicador de Reputación de Onda Nocturna`,
|
cheats_nightwaveStandingMultiplier: `Multiplicador de Reputación de Onda Nocturna`,
|
||||||
cheats_save: `Guardar`,
|
cheats_save: `Guardar`,
|
||||||
@ -238,6 +239,7 @@ dict = {
|
|||||||
worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`,
|
worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`,
|
||||||
worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`,
|
worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`,
|
||||||
worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`,
|
worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`,
|
||||||
|
worldState_darvoStockMultiplier: `[UNTRANSLATED] Darvo Stock Multiplier`,
|
||||||
|
|
||||||
import_importNote: `Puedes proporcionar una respuesta de inventario completa o parcial (representación del cliente) aquí. Todos los campos compatibles con el importador <b>serán sobrescritos</b> en tu cuenta.`,
|
import_importNote: `Puedes proporcionar una respuesta de inventario completa o parcial (representación del cliente) aquí. Todos los campos compatibles con el importador <b>serán sobrescritos</b> en tu cuenta.`,
|
||||||
import_submit: `Enviar`,
|
import_submit: `Enviar`,
|
||||||
@ -262,7 +264,7 @@ dict = {
|
|||||||
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% de efectividad de orbes de energía`,
|
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% de efectividad de orbes de energía`,
|
||||||
upgrade_WarframeGlobeEffectHealth: `+|VAL|% de efectividad de orbes de salud`,
|
upgrade_WarframeGlobeEffectHealth: `+|VAL|% de efectividad de orbes de salud`,
|
||||||
upgrade_WarframeHealthMax: `+|VAL| de salud máxima`,
|
upgrade_WarframeHealthMax: `+|VAL| de salud máxima`,
|
||||||
upgrade_WarframeHPBoostFromImpact: `+|VAL1| de salud por enemigo eliminado con daño explosivo (máximo |VAL2| de salud)`,
|
upgrade_WarframeHPBoostFromImpact: `[UNTRANSLATED] +|VAL1| Health on kill with Blast Damage (Max |VAL2| Health)`,
|
||||||
upgrade_WarframeParkourVelocity: `+|VAL|% de velocidad de parkour`,
|
upgrade_WarframeParkourVelocity: `+|VAL|% de velocidad de parkour`,
|
||||||
upgrade_WarframeRadiationDamageBoost: `+|VAL|% de daño de habilidades a enemigos con estado radiactivo`,
|
upgrade_WarframeRadiationDamageBoost: `+|VAL|% de daño de habilidades a enemigos con estado radiactivo`,
|
||||||
upgrade_WarframeRegen: `+|VAL| de regeneración de salud por segundo`,
|
upgrade_WarframeRegen: `+|VAL| de regeneración de salud por segundo`,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// French translation by Vitruvio
|
// French translation by Vitruvio
|
||||||
dict = {
|
dict = {
|
||||||
general_inventoryUpdateNote: `Note : Les changements effectués ici seront appliqués lors de la syncrhonisation. Visiter la navigation appliquera les changements apportés à l'inventaire.`,
|
general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command, visiting a dojo/relay, or relogging.`,
|
||||||
general_addButton: `Ajouter`,
|
general_addButton: `Ajouter`,
|
||||||
general_setButton: `[UNTRANSLATED] Set`,
|
general_setButton: `[UNTRANSLATED] Set`,
|
||||||
general_removeButton: `[UNTRANSLATED] Remove`,
|
general_removeButton: `[UNTRANSLATED] Remove`,
|
||||||
@ -182,6 +182,7 @@ dict = {
|
|||||||
cheats_fastClanAscension: `Ascension de clan rapide`,
|
cheats_fastClanAscension: `Ascension de clan rapide`,
|
||||||
cheats_missionsCanGiveAllRelics: `Les missions donnent toutes les reliques`,
|
cheats_missionsCanGiveAllRelics: `Les missions donnent toutes les reliques`,
|
||||||
cheats_unlockAllSimarisResearchEntries: `Débloquer toute les recherches chez Simaris`,
|
cheats_unlockAllSimarisResearchEntries: `Débloquer toute les recherches chez Simaris`,
|
||||||
|
cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
|
||||||
cheats_spoofMasteryRank: `Rang de maîtrise personnalisé (-1 pour désactiver)`,
|
cheats_spoofMasteryRank: `Rang de maîtrise personnalisé (-1 pour désactiver)`,
|
||||||
cheats_nightwaveStandingMultiplier: `Multiplicateur de réputation d'Ondes Nocturnes`,
|
cheats_nightwaveStandingMultiplier: `Multiplicateur de réputation d'Ondes Nocturnes`,
|
||||||
cheats_save: `Sauvegarder`,
|
cheats_save: `Sauvegarder`,
|
||||||
@ -238,6 +239,7 @@ dict = {
|
|||||||
worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`,
|
worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`,
|
||||||
worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`,
|
worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`,
|
||||||
worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`,
|
worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`,
|
||||||
|
worldState_darvoStockMultiplier: `[UNTRANSLATED] Darvo Stock Multiplier`,
|
||||||
|
|
||||||
import_importNote: `Import manuel. Toutes les modifcations supportées par l'inventaire <b>écraseront celles présentes dans la base de données</b>.`,
|
import_importNote: `Import manuel. Toutes les modifcations supportées par l'inventaire <b>écraseront celles présentes dans la base de données</b>.`,
|
||||||
import_submit: `Soumettre`,
|
import_submit: `Soumettre`,
|
||||||
@ -262,7 +264,7 @@ dict = {
|
|||||||
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% d'efficacité d'orbe d'énergie`,
|
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% d'efficacité d'orbe d'énergie`,
|
||||||
upgrade_WarframeGlobeEffectHealth: `+|VAL|% d'efficacité d'orbe de santé`,
|
upgrade_WarframeGlobeEffectHealth: `+|VAL|% d'efficacité d'orbe de santé`,
|
||||||
upgrade_WarframeHealthMax: `+|VAL| de santé`,
|
upgrade_WarframeHealthMax: `+|VAL| de santé`,
|
||||||
upgrade_WarframeHPBoostFromImpact: `+|VAL1| de santé par ennemi tué avec des dégâts explosifs (Max |VAL2| de santé)`,
|
upgrade_WarframeHPBoostFromImpact: `[UNTRANSLATED] +|VAL1| Health on kill with Blast Damage (Max |VAL2| Health)`,
|
||||||
upgrade_WarframeParkourVelocity: `+|VAL|% de vélocité de parkour`,
|
upgrade_WarframeParkourVelocity: `+|VAL|% de vélocité de parkour`,
|
||||||
upgrade_WarframeRadiationDamageBoost: `+|VAL|% de dégâts de pouvoir sur les ennemis affectés par du statut radiation`,
|
upgrade_WarframeRadiationDamageBoost: `+|VAL|% de dégâts de pouvoir sur les ennemis affectés par du statut radiation`,
|
||||||
upgrade_WarframeRegen: `+|VAL| régénération de santé/s`,
|
upgrade_WarframeRegen: `+|VAL| régénération de santé/s`,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Russian translation by AMelonInsideLemon
|
// Russian translation by AMelonInsideLemon
|
||||||
dict = {
|
dict = {
|
||||||
general_inventoryUpdateNote: `Примечание: изменения, внесенные здесь, отобразятся в игре только после повторной загрузки вашего инвентаря. Посещение навигации — самый простой способ этого добиться.`,
|
general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command, visiting a dojo/relay, or relogging.`,
|
||||||
general_addButton: `Добавить`,
|
general_addButton: `Добавить`,
|
||||||
general_setButton: `Установить`,
|
general_setButton: `Установить`,
|
||||||
general_removeButton: `Удалить`,
|
general_removeButton: `Удалить`,
|
||||||
@ -182,6 +182,7 @@ dict = {
|
|||||||
cheats_fastClanAscension: `Мгновенное Вознесение Клана`,
|
cheats_fastClanAscension: `Мгновенное Вознесение Клана`,
|
||||||
cheats_missionsCanGiveAllRelics: `[UNTRANSLATED] Missions Can Give All Relics`,
|
cheats_missionsCanGiveAllRelics: `[UNTRANSLATED] Missions Can Give All Relics`,
|
||||||
cheats_unlockAllSimarisResearchEntries: `[UNTRANSLATED] Unlock All Simaris Research Entries`,
|
cheats_unlockAllSimarisResearchEntries: `[UNTRANSLATED] Unlock All Simaris Research Entries`,
|
||||||
|
cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
|
||||||
cheats_spoofMasteryRank: `Подделанный ранг мастерства (-1 для отключения)`,
|
cheats_spoofMasteryRank: `Подделанный ранг мастерства (-1 для отключения)`,
|
||||||
cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
|
cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
|
||||||
cheats_save: `[UNTRANSLATED] Save`,
|
cheats_save: `[UNTRANSLATED] Save`,
|
||||||
@ -238,6 +239,7 @@ dict = {
|
|||||||
worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`,
|
worldState_allAtOnceNormal: `[UNTRANSLATED] All At Once, Normal`,
|
||||||
worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`,
|
worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`,
|
||||||
worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`,
|
worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`,
|
||||||
|
worldState_darvoStockMultiplier: `[UNTRANSLATED] Darvo Stock Multiplier`,
|
||||||
|
|
||||||
import_importNote: `Вы можете загрузить полный или частичный ответ инвентаря (клиентское представление) здесь. Все поддерживаемые поля <b>будут перезаписаны</b> в вашем аккаунте.`,
|
import_importNote: `Вы можете загрузить полный или частичный ответ инвентаря (клиентское представление) здесь. Все поддерживаемые поля <b>будут перезаписаны</b> в вашем аккаунте.`,
|
||||||
import_submit: `Отправить`,
|
import_submit: `Отправить`,
|
||||||
@ -262,7 +264,7 @@ dict = {
|
|||||||
upgrade_WarframeGlobeEffectEnergy: `[UNTRANSLATED] +|VAL|% Energy Orb Effectiveness`,
|
upgrade_WarframeGlobeEffectEnergy: `[UNTRANSLATED] +|VAL|% Energy Orb Effectiveness`,
|
||||||
upgrade_WarframeGlobeEffectHealth: `[UNTRANSLATED] +|VAL|% Health Orb Effectiveness`,
|
upgrade_WarframeGlobeEffectHealth: `[UNTRANSLATED] +|VAL|% Health Orb Effectiveness`,
|
||||||
upgrade_WarframeHealthMax: `[UNTRANSLATED] +|VAL| Health`,
|
upgrade_WarframeHealthMax: `[UNTRANSLATED] +|VAL| Health`,
|
||||||
upgrade_WarframeHPBoostFromImpact: `[UNTRANSLATED] +|VAL1| Health per enemy killed with Blast Damage (Max |VAL2| Health)`,
|
upgrade_WarframeHPBoostFromImpact: `[UNTRANSLATED] +|VAL1| Health on kill with Blast Damage (Max |VAL2| Health)`,
|
||||||
upgrade_WarframeParkourVelocity: `[UNTRANSLATED] +|VAL|% Parkour Velocity`,
|
upgrade_WarframeParkourVelocity: `[UNTRANSLATED] +|VAL|% Parkour Velocity`,
|
||||||
upgrade_WarframeRadiationDamageBoost: `[UNTRANSLATED] +|VAL|% Ability Damage on enemies affected by Radiation Status`,
|
upgrade_WarframeRadiationDamageBoost: `[UNTRANSLATED] +|VAL|% Ability Damage on enemies affected by Radiation Status`,
|
||||||
upgrade_WarframeRegen: `[UNTRANSLATED] +|VAL| Health Regen/s`,
|
upgrade_WarframeRegen: `[UNTRANSLATED] +|VAL| Health Regen/s`,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Chinese translation by meb154, bishan178 & Corvus
|
// Chinese translation by meb154, bishan178 & Corvus
|
||||||
dict = {
|
dict = {
|
||||||
general_inventoryUpdateNote: `注意:此处所做的更改只有在游戏同步仓库后才会生效。您可以通过访问星图来触发仓库更新。`,
|
general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command, visiting a dojo/relay, or relogging.`,
|
||||||
general_addButton: `添加`,
|
general_addButton: `添加`,
|
||||||
general_setButton: `[UNTRANSLATED] Set`,
|
general_setButton: `[UNTRANSLATED] Set`,
|
||||||
general_removeButton: `[UNTRANSLATED] Remove`,
|
general_removeButton: `[UNTRANSLATED] Remove`,
|
||||||
@ -182,6 +182,7 @@ dict = {
|
|||||||
cheats_fastClanAscension: `快速升级氏族`,
|
cheats_fastClanAscension: `快速升级氏族`,
|
||||||
cheats_missionsCanGiveAllRelics: `任务可获取所有遗物`,
|
cheats_missionsCanGiveAllRelics: `任务可获取所有遗物`,
|
||||||
cheats_unlockAllSimarisResearchEntries: `解锁所有Simaris研究条目`,
|
cheats_unlockAllSimarisResearchEntries: `解锁所有Simaris研究条目`,
|
||||||
|
cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
|
||||||
cheats_spoofMasteryRank: `伪造精通段位(-1为禁用)`,
|
cheats_spoofMasteryRank: `伪造精通段位(-1为禁用)`,
|
||||||
cheats_nightwaveStandingMultiplier: `午夜电波声望倍率`,
|
cheats_nightwaveStandingMultiplier: `午夜电波声望倍率`,
|
||||||
cheats_save: `保存`,
|
cheats_save: `保存`,
|
||||||
@ -237,7 +238,8 @@ dict = {
|
|||||||
normal: `正常`,
|
normal: `正常`,
|
||||||
worldState_allAtOnceNormal: `全部开启(普通)`,
|
worldState_allAtOnceNormal: `全部开启(普通)`,
|
||||||
worldState_allAtOnceSteelPath: `全部开启(钢铁之路)`,
|
worldState_allAtOnceSteelPath: `全部开启(钢铁之路)`,
|
||||||
worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`,
|
worldState_theCircuitOverride: `无尽回廊任务循环配置:`,
|
||||||
|
worldState_darvoStockMultiplier: `[UNTRANSLATED] Darvo Stock Multiplier`,
|
||||||
|
|
||||||
import_importNote: `您可以在此处提供完整或部分库存响应(客户端表示)。支持的所有字段<b>将被覆盖</b>到您的账户中。`,
|
import_importNote: `您可以在此处提供完整或部分库存响应(客户端表示)。支持的所有字段<b>将被覆盖</b>到您的账户中。`,
|
||||||
import_submit: `提交`,
|
import_submit: `提交`,
|
||||||
@ -262,7 +264,7 @@ dict = {
|
|||||||
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% 能量球效果`,
|
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% 能量球效果`,
|
||||||
upgrade_WarframeGlobeEffectHealth: `+|VAL|% 生命球效果`,
|
upgrade_WarframeGlobeEffectHealth: `+|VAL|% 生命球效果`,
|
||||||
upgrade_WarframeHealthMax: `+|VAL| 生命`,
|
upgrade_WarframeHealthMax: `+|VAL| 生命`,
|
||||||
upgrade_WarframeHPBoostFromImpact: `每个被爆炸伤害击杀的敌人,补充 |VAL1|生命 (最大 |VAL2| 生命)`,
|
upgrade_WarframeHPBoostFromImpact: `[UNTRANSLATED] +|VAL1| Health on kill with Blast Damage (Max |VAL2| Health)`,
|
||||||
upgrade_WarframeParkourVelocity: `+|VAL|% 跑酷速度`,
|
upgrade_WarframeParkourVelocity: `+|VAL|% 跑酷速度`,
|
||||||
upgrade_WarframeRadiationDamageBoost: `对受辐射状态影响的敌人 +|VAL|% 技能伤害`,
|
upgrade_WarframeRadiationDamageBoost: `对受辐射状态影响的敌人 +|VAL|% 技能伤害`,
|
||||||
upgrade_WarframeRegen: `+|VAL| 生命再生/s`,
|
upgrade_WarframeRegen: `+|VAL| 生命再生/s`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user