forked from OpenWF/SpaceNinjaServer
merge upstream
This commit is contained in:
commit
74b7f62a54
8
package-lock.json
generated
8
package-lock.json
generated
@ -18,7 +18,7 @@
|
|||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"ncp": "^2.0.0",
|
"ncp": "^2.0.0",
|
||||||
"typescript": "^5.5",
|
"typescript": "^5.5",
|
||||||
"warframe-public-export-plus": "^0.5.58",
|
"warframe-public-export-plus": "^0.5.59",
|
||||||
"warframe-riven-info": "^0.1.2",
|
"warframe-riven-info": "^0.1.2",
|
||||||
"winston": "^3.17.0",
|
"winston": "^3.17.0",
|
||||||
"winston-daily-rotate-file": "^5.0.0"
|
"winston-daily-rotate-file": "^5.0.0"
|
||||||
@ -3789,9 +3789,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/warframe-public-export-plus": {
|
"node_modules/warframe-public-export-plus": {
|
||||||
"version": "0.5.58",
|
"version": "0.5.59",
|
||||||
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.58.tgz",
|
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.59.tgz",
|
||||||
"integrity": "sha512-2G3tKcoblUl7S3Rkk5k/qH+VGZBUmU2QjtIrEO/Bt6UlgO83s648elkNdDKOLBKXnxIsa194nVwz+ci1K86sXg=="
|
"integrity": "sha512-/SUCVjngVDBz6gahz7CdVLywtHLODL6O5nmNtQcxFDUwrUGnF1lETcG8/UO+WLeGxBVAy4BDPbq+9ZWlYZM4uQ=="
|
||||||
},
|
},
|
||||||
"node_modules/warframe-riven-info": {
|
"node_modules/warframe-riven-info": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"ncp": "^2.0.0",
|
"ncp": "^2.0.0",
|
||||||
"typescript": "^5.5",
|
"typescript": "^5.5",
|
||||||
"warframe-public-export-plus": "^0.5.58",
|
"warframe-public-export-plus": "^0.5.59",
|
||||||
"warframe-riven-info": "^0.1.2",
|
"warframe-riven-info": "^0.1.2",
|
||||||
"winston": "^3.17.0",
|
"winston": "^3.17.0",
|
||||||
"winston-daily-rotate-file": "^5.0.0"
|
"winston-daily-rotate-file": "^5.0.0"
|
||||||
|
@ -13,6 +13,7 @@ import { addItems, combineInventoryChanges, getInventory } from "@/src/services/
|
|||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { ExportFlavour, ExportGear } from "warframe-public-export-plus";
|
import { ExportFlavour, ExportGear } from "warframe-public-export-plus";
|
||||||
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
||||||
|
import { fromStoreItem, isStoreItem } from "@/src/services/itemDataService";
|
||||||
|
|
||||||
export const inboxController: RequestHandler = async (req, res) => {
|
export const inboxController: RequestHandler = async (req, res) => {
|
||||||
const { deleteId, lastMessage: latestClientMessageId, messageId } = req.query;
|
const { deleteId, lastMessage: latestClientMessageId, messageId } = req.query;
|
||||||
@ -48,7 +49,7 @@ export const inboxController: RequestHandler = async (req, res) => {
|
|||||||
await addItems(
|
await addItems(
|
||||||
inventory,
|
inventory,
|
||||||
attachmentItems.map(attItem => ({
|
attachmentItems.map(attItem => ({
|
||||||
ItemType: attItem,
|
ItemType: isStoreItem(attItem) ? fromStoreItem(attItem) : attItem,
|
||||||
ItemCount: attItem in ExportGear ? (ExportGear[attItem].purchaseQuantity ?? 1) : 1
|
ItemCount: attItem in ExportGear ? (ExportGear[attItem].purchaseQuantity ?? 1) : 1
|
||||||
})),
|
})),
|
||||||
inventoryChanges
|
inventoryChanges
|
||||||
|
@ -18,10 +18,12 @@ import {
|
|||||||
addMiscItems,
|
addMiscItems,
|
||||||
allDailyAffiliationKeys,
|
allDailyAffiliationKeys,
|
||||||
cleanupInventory,
|
cleanupInventory,
|
||||||
createLibraryDailyTask
|
createLibraryDailyTask,
|
||||||
|
generateRewardSeed
|
||||||
} from "@/src/services/inventoryService";
|
} from "@/src/services/inventoryService";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { catBreadHash } from "@/src/helpers/stringHelpers";
|
import { catBreadHash } from "@/src/helpers/stringHelpers";
|
||||||
|
import { Types } from "mongoose";
|
||||||
|
|
||||||
export const inventoryController: RequestHandler = async (request, response) => {
|
export const inventoryController: RequestHandler = async (request, response) => {
|
||||||
const accountId = await getAccountIdForRequest(request);
|
const accountId = await getAccountIdForRequest(request);
|
||||||
@ -87,7 +89,7 @@ export const inventoryController: RequestHandler = async (request, response) =>
|
|||||||
cleanupInventory(inventory);
|
cleanupInventory(inventory);
|
||||||
|
|
||||||
inventory.NextRefill = new Date((Math.trunc(Date.now() / 86400000) + 1) * 86400000);
|
inventory.NextRefill = new Date((Math.trunc(Date.now() / 86400000) + 1) * 86400000);
|
||||||
await inventory.save();
|
//await inventory.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -96,9 +98,20 @@ export const inventoryController: RequestHandler = async (request, response) =>
|
|||||||
new Date() >= inventory.InfestedFoundry.AbilityOverrideUnlockCooldown
|
new Date() >= inventory.InfestedFoundry.AbilityOverrideUnlockCooldown
|
||||||
) {
|
) {
|
||||||
handleSubsumeCompletion(inventory);
|
handleSubsumeCompletion(inventory);
|
||||||
await inventory.save();
|
//await inventory.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inventory.LastInventorySync) {
|
||||||
|
const lastSyncDuviriMood = Math.trunc(inventory.LastInventorySync.getTimestamp().getTime() / 7200000);
|
||||||
|
const currentDuviriMood = Math.trunc(Date.now() / 7200000);
|
||||||
|
if (lastSyncDuviriMood != currentDuviriMood) {
|
||||||
|
logger.debug(`refreshing duviri seed`);
|
||||||
|
inventory.DuviriInfo.Seed = generateRewardSeed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inventory.LastInventorySync = new Types.ObjectId();
|
||||||
|
await inventory.save();
|
||||||
|
|
||||||
response.json(await getInventoryResponse(inventory, "xpBasedLevelCapDisabled" in request.query));
|
response.json(await getInventoryResponse(inventory, "xpBasedLevelCapDisabled" in request.query));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -274,7 +287,7 @@ export const getInventoryResponse = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Omitting this field so opening the navigation resyncs the inventory which is more desirable for typical usage.
|
// Omitting this field so opening the navigation resyncs the inventory which is more desirable for typical usage.
|
||||||
//inventoryResponse.LastInventorySync = toOid(new Types.ObjectId());
|
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;
|
||||||
|
@ -2,9 +2,12 @@ import {
|
|||||||
consumeModCharge,
|
consumeModCharge,
|
||||||
encodeNemesisGuess,
|
encodeNemesisGuess,
|
||||||
getInfNodes,
|
getInfNodes,
|
||||||
|
getKnifeUpgrade,
|
||||||
getNemesisPasscode,
|
getNemesisPasscode,
|
||||||
|
getNemesisPasscodeModTypes,
|
||||||
getWeaponsForManifest,
|
getWeaponsForManifest,
|
||||||
IKnifeResponse
|
IKnifeResponse,
|
||||||
|
showdownNodes
|
||||||
} from "@/src/helpers/nemesisHelpers";
|
} from "@/src/helpers/nemesisHelpers";
|
||||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||||
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
|
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
|
||||||
@ -15,6 +18,8 @@ import { IMongoDate, IOid } from "@/src/types/commonTypes";
|
|||||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||||
import {
|
import {
|
||||||
IInnateDamageFingerprint,
|
IInnateDamageFingerprint,
|
||||||
|
IInventoryClient,
|
||||||
|
INemesisClient,
|
||||||
InventorySlot,
|
InventorySlot,
|
||||||
IUpgradeClient,
|
IUpgradeClient,
|
||||||
IWeaponSkinClient,
|
IWeaponSkinClient,
|
||||||
@ -100,13 +105,14 @@ export const nemesisController: RequestHandler = async (req, res) => {
|
|||||||
encodeNemesisGuess(guess[0], result1, guess[1], result2, guess[2], result3)
|
encodeNemesisGuess(guess[0], result1, guess[1], result2, guess[2], result3)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Increase antivirus
|
// Increase antivirus if correct antivirus mod is installed
|
||||||
|
const response: IKnifeResponse = {};
|
||||||
|
if (result1 == 0 || result2 == 0 || result3 == 0) {
|
||||||
let antivirusGain = 5;
|
let antivirusGain = 5;
|
||||||
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
|
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
|
||||||
const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid);
|
const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid);
|
||||||
const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
|
const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
|
||||||
const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
|
const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
|
||||||
const response: IKnifeResponse = {};
|
|
||||||
for (const upgrade of body.knife!.AttachedUpgrades) {
|
for (const upgrade of body.knife!.AttachedUpgrades) {
|
||||||
switch (upgrade.ItemType) {
|
switch (upgrade.ItemType) {
|
||||||
case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusAndSpeedOnUseMod":
|
case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusAndSpeedOnUseMod":
|
||||||
@ -132,18 +138,12 @@ export const nemesisController: RequestHandler = async (req, res) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
inventory.Nemesis!.HenchmenKilled += antivirusGain;
|
inventory.Nemesis!.HenchmenKilled += antivirusGain;
|
||||||
|
}
|
||||||
|
|
||||||
if (inventory.Nemesis!.HenchmenKilled >= 100) {
|
if (inventory.Nemesis!.HenchmenKilled >= 100) {
|
||||||
inventory.Nemesis!.HenchmenKilled = 100;
|
inventory.Nemesis!.HenchmenKilled = 100;
|
||||||
inventory.Nemesis!.InfNodes = [
|
|
||||||
{
|
|
||||||
Node: "CrewBattleNode559",
|
|
||||||
Influence: 1
|
|
||||||
}
|
}
|
||||||
];
|
|
||||||
inventory.Nemesis!.Weakened = true;
|
|
||||||
} else {
|
|
||||||
inventory.Nemesis!.InfNodes = getInfNodes("FC_INFESTATION", 0);
|
inventory.Nemesis!.InfNodes = getInfNodes("FC_INFESTATION", 0);
|
||||||
}
|
|
||||||
|
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
res.json(response);
|
res.json(response);
|
||||||
@ -213,6 +213,38 @@ export const nemesisController: RequestHandler = async (req, res) => {
|
|||||||
res.json({
|
res.json({
|
||||||
target: inventory.toJSON().Nemesis
|
target: inventory.toJSON().Nemesis
|
||||||
});
|
});
|
||||||
|
} else if ((req.query.mode as string) == "w") {
|
||||||
|
const inventory = await getInventory(
|
||||||
|
accountId,
|
||||||
|
"Nemesis LoadOutPresets CurrentLoadOutIds DataKnives Upgrades RawUpgrades"
|
||||||
|
);
|
||||||
|
//const body = getJSONfromString<INemesisWeakenRequest>(String(req.body));
|
||||||
|
|
||||||
|
inventory.Nemesis!.InfNodes = [
|
||||||
|
{
|
||||||
|
Node: showdownNodes[inventory.Nemesis!.Faction],
|
||||||
|
Influence: 1
|
||||||
|
}
|
||||||
|
];
|
||||||
|
inventory.Nemesis!.Weakened = true;
|
||||||
|
|
||||||
|
const response: IKnifeResponse & { target: INemesisClient } = {
|
||||||
|
target: inventory.toJSON<IInventoryClient>().Nemesis!
|
||||||
|
};
|
||||||
|
|
||||||
|
// Consume charge of the correct requiem mod(s)
|
||||||
|
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
|
||||||
|
const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid);
|
||||||
|
const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
|
||||||
|
const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
|
||||||
|
const modTypes = getNemesisPasscodeModTypes(inventory.Nemesis!);
|
||||||
|
for (const modType of modTypes) {
|
||||||
|
const upgrade = getKnifeUpgrade(inventory, dataknifeUpgrades, modType);
|
||||||
|
consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
|
||||||
|
}
|
||||||
|
|
||||||
|
await inventory.save();
|
||||||
|
res.json(response);
|
||||||
} else {
|
} else {
|
||||||
logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
|
logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
|
||||||
throw new Error(`unknown nemesis mode: ${String(req.query.mode)}`);
|
throw new Error(`unknown nemesis mode: ${String(req.query.mode)}`);
|
||||||
@ -264,12 +296,19 @@ interface INemesisRequiemRequest {
|
|||||||
guess: number; // grn/crp: 4 bits | coda: 3x 4 bits
|
guess: number; // grn/crp: 4 bits | coda: 3x 4 bits
|
||||||
position: number; // grn/crp: 0-2 | coda: 0
|
position: number; // grn/crp: 0-2 | coda: 0
|
||||||
// knife field provided for coda only
|
// knife field provided for coda only
|
||||||
knife?: {
|
knife?: IKnife;
|
||||||
|
}
|
||||||
|
|
||||||
|
// interface INemesisWeakenRequest {
|
||||||
|
// target: INemesisClient;
|
||||||
|
// knife: IKnife;
|
||||||
|
// }
|
||||||
|
|
||||||
|
interface IKnife {
|
||||||
Item: IEquipmentClient;
|
Item: IEquipmentClient;
|
||||||
Skins: IWeaponSkinClient[];
|
Skins: IWeaponSkinClient[];
|
||||||
ModSlot: number;
|
ModSlot: number;
|
||||||
CustSlot: number;
|
CustSlot: number;
|
||||||
AttachedUpgrades: IUpgradeClient[];
|
AttachedUpgrades: IUpgradeClient[];
|
||||||
HiddenWhenHolstered: boolean;
|
HiddenWhenHolstered: boolean;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import { ExportRegions, ExportWarframes } from "warframe-public-export-plus";
|
import { ExportRegions, ExportWarframes } from "warframe-public-export-plus";
|
||||||
import { IInfNode } from "@/src/types/inventoryTypes/inventoryTypes";
|
import { IInfNode, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import { SRng } from "@/src/services/rngService";
|
import { getRewardAtPercentage, SRng } from "@/src/services/rngService";
|
||||||
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { IOid } from "../types/commonTypes";
|
import { IOid } from "../types/commonTypes";
|
||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import { addMods } from "../services/inventoryService";
|
import { addMods, generateRewardSeed } from "../services/inventoryService";
|
||||||
import { isArchwingMission } from "../services/worldStateService";
|
import { isArchwingMission } from "../services/worldStateService";
|
||||||
|
import { fromStoreItem, toStoreItem } from "../services/itemDataService";
|
||||||
|
import { createMessage } from "../services/inboxService";
|
||||||
|
|
||||||
export const getInfNodes = (faction: string, rank: number): IInfNode[] => {
|
export const getInfNodes = (faction: string, rank: number): IInfNode[] => {
|
||||||
const infNodes = [];
|
const infNodes = [];
|
||||||
@ -38,17 +40,59 @@ const systemIndexes: Record<string, number[]> = {
|
|||||||
FC_INFESTATION: [23]
|
FC_INFESTATION: [23]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const showdownNodes: Record<string, string> = {
|
||||||
|
FC_GRINEER: "CrewBattleNode557",
|
||||||
|
FC_CORPUS: "CrewBattleNode558",
|
||||||
|
FC_INFESTATION: "CrewBattleNode559"
|
||||||
|
};
|
||||||
|
|
||||||
// Get a parazon 'passcode' based on the nemesis fingerprint so it's always the same for the same nemesis.
|
// Get a parazon 'passcode' based on the nemesis fingerprint so it's always the same for the same nemesis.
|
||||||
export const getNemesisPasscode = (nemesis: { fp: bigint; Faction: string }): number[] => {
|
export const getNemesisPasscode = (nemesis: { fp: bigint; Faction: string }): number[] => {
|
||||||
const rng = new SRng(nemesis.fp);
|
const rng = new SRng(nemesis.fp);
|
||||||
const passcode = [rng.randomInt(0, 7)];
|
const choices = [0, 1, 2, 3, 5, 6, 7];
|
||||||
|
let choiceIndex = rng.randomInt(0, choices.length - 1);
|
||||||
|
const passcode = [choices[choiceIndex]];
|
||||||
if (nemesis.Faction != "FC_INFESTATION") {
|
if (nemesis.Faction != "FC_INFESTATION") {
|
||||||
passcode.push(rng.randomInt(0, 7));
|
choices.splice(choiceIndex, 1);
|
||||||
passcode.push(rng.randomInt(0, 7));
|
choiceIndex = rng.randomInt(0, choices.length - 1);
|
||||||
|
passcode.push(choices[choiceIndex]);
|
||||||
|
|
||||||
|
choices.splice(choiceIndex, 1);
|
||||||
|
choiceIndex = rng.randomInt(0, choices.length - 1);
|
||||||
|
passcode.push(choices[choiceIndex]);
|
||||||
}
|
}
|
||||||
return passcode;
|
return passcode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const reqiuemMods: readonly string[] = [
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalOneMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalTwoMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalThreeMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalFourMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalFiveMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalSixMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalSevenMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalEightMod"
|
||||||
|
];
|
||||||
|
|
||||||
|
const antivirusMods: readonly string[] = [
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/AntivirusOneMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/AntivirusTwoMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/AntivirusThreeMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/AntivirusFourMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/AntivirusFiveMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/AntivirusSixMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/AntivirusSevenMod",
|
||||||
|
"/Lotus/Upgrades/Mods/Immortal/AntivirusEightMod"
|
||||||
|
];
|
||||||
|
|
||||||
|
export const getNemesisPasscodeModTypes = (nemesis: { fp: bigint; Faction: string }): string[] => {
|
||||||
|
const passcode = getNemesisPasscode(nemesis);
|
||||||
|
return nemesis.Faction == "FC_INFESTATION"
|
||||||
|
? passcode.map(i => antivirusMods[i])
|
||||||
|
: passcode.map(i => reqiuemMods[i]);
|
||||||
|
};
|
||||||
|
|
||||||
export const encodeNemesisGuess = (
|
export const encodeNemesisGuess = (
|
||||||
symbol1: number,
|
symbol1: number,
|
||||||
result1: number,
|
result1: number,
|
||||||
@ -79,6 +123,31 @@ export interface IKnifeResponse {
|
|||||||
HasKnife?: boolean;
|
HasKnife?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getKnifeUpgrade = (
|
||||||
|
inventory: TInventoryDatabaseDocument,
|
||||||
|
dataknifeUpgrades: string[],
|
||||||
|
type: string
|
||||||
|
): { ItemId: IOid; ItemType: string } => {
|
||||||
|
if (dataknifeUpgrades.indexOf(type) != -1) {
|
||||||
|
return {
|
||||||
|
ItemId: { $oid: "000000000000000000000000" },
|
||||||
|
ItemType: type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (const upgradeId of dataknifeUpgrades) {
|
||||||
|
if (upgradeId.length == 24) {
|
||||||
|
const upgrade = inventory.Upgrades.id(upgradeId);
|
||||||
|
if (upgrade && upgrade.ItemType == type) {
|
||||||
|
return {
|
||||||
|
ItemId: { $oid: upgradeId },
|
||||||
|
ItemType: type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error(`${type} does not seem to be installed on parazon?!`);
|
||||||
|
};
|
||||||
|
|
||||||
export const consumeModCharge = (
|
export const consumeModCharge = (
|
||||||
response: IKnifeResponse,
|
response: IKnifeResponse,
|
||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
@ -177,7 +246,6 @@ export const getWeaponsForManifest = (manifest: string): readonly string[] => {
|
|||||||
throw new Error(`unknown nemesis manifest: ${manifest}`);
|
throw new Error(`unknown nemesis manifest: ${manifest}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: This sucks.
|
|
||||||
export const getInnateDamageTag = (
|
export const getInnateDamageTag = (
|
||||||
KillingSuit: string
|
KillingSuit: string
|
||||||
):
|
):
|
||||||
@ -188,78 +256,7 @@ export const getInnateDamageTag = (
|
|||||||
| "InnateMagDamage"
|
| "InnateMagDamage"
|
||||||
| "InnateRadDamage"
|
| "InnateRadDamage"
|
||||||
| "InnateToxinDamage" => {
|
| "InnateToxinDamage" => {
|
||||||
const baseSuitType = ExportWarframes[KillingSuit].parentName;
|
return ExportWarframes[KillingSuit].nemesisUpgradeTag!;
|
||||||
switch (baseSuitType) {
|
|
||||||
case "/Lotus/Powersuits/Volt/VoltBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Excalibur/ExcaliburBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/AntiMatter/NovaBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Banshee/BansheeBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Berserker/BerserkerBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Magician/MagicianBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Sentient/SentientBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Gyre/GyreBaseSuit":
|
|
||||||
return "InnateElectricityDamage";
|
|
||||||
case "/Lotus/Powersuits/Ember/EmberBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Dragon/DragonBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Nezha/NezhaBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Sandman/SandmanBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Trapper/TrapperBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Wisp/WispBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Odalisk/OdaliskBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/PaxDuviricus/PaxDuviricusBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Choir/ChoirBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Temple/TempleBaseSuit":
|
|
||||||
return "InnateHeatDamage";
|
|
||||||
case "/Lotus/Powersuits/Frost/FrostBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Glass/GlassBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Fairy/FairyBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/IronFrame/IronFrameBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Revenant/RevenantBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Trinity/TrinityBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Hoplite/HopliteBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Koumei/KoumeiBaseSuit":
|
|
||||||
return "InnateFreezeDamage";
|
|
||||||
case "/Lotus/Powersuits/Saryn/SarynBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Paladin/PaladinBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Brawler/BrawlerBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Infestation/InfestationBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Necro/NecroBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Khora/KhoraBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Ranger/RangerBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Dagath/DagathBaseSuit":
|
|
||||||
return "InnateToxinDamage";
|
|
||||||
case "/Lotus/Powersuits/Mag/MagBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Pirate/PirateBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Cowgirl/CowgirlBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Priest/PriestBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/BrokenFrame/BrokenFrameBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Alchemist/AlchemistBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Yareli/YareliBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Geode/GeodeBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Frumentarius/FrumentariusBaseSuit":
|
|
||||||
return "InnateMagDamage";
|
|
||||||
case "/Lotus/Powersuits/Loki/LokiBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Ninja/NinjaBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Jade/JadeBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Bard/BardBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Harlequin/HarlequinBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Garuda/GarudaBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/YinYang/YinYangBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Werewolf/WerewolfBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/ConcreteFrame/ConcreteFrameBaseSuit":
|
|
||||||
return "InnateRadDamage";
|
|
||||||
case "/Lotus/Powersuits/Rhino/RhinoBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Tengu/TenguBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/MonkeyKing/MonkeyKingBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Runner/RunnerBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Pacifist/PacifistBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Devourer/DevourerBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Wraith/WraithBaseSuit":
|
|
||||||
case "/Lotus/Powersuits/Pagemaster/PagemasterBaseSuit":
|
|
||||||
return "InnateImpactDamage";
|
|
||||||
}
|
|
||||||
logger.warn(`unknown innate damage type for ${KillingSuit}, using heat as a fallback`);
|
|
||||||
return "InnateHeatDamage";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: For -1399275245665749231n, the value should be 75306944, but we're off by 59 with 75307003.
|
// TODO: For -1399275245665749231n, the value should be 75306944, but we're off by 59 with 75307003.
|
||||||
@ -273,3 +270,109 @@ export const getInnateDamageValue = (fp: bigint): number => {
|
|||||||
}
|
}
|
||||||
return Math.trunc(value * 0x40000000);
|
return Math.trunc(value * 0x40000000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getKillTokenRewardCount = (fp: bigint): number => {
|
||||||
|
const rng = new SRng(fp);
|
||||||
|
return rng.randomInt(10, 15);
|
||||||
|
};
|
||||||
|
|
||||||
|
// /Lotus/Types/Enemies/InfestedLich/InfestedLichRewardManifest
|
||||||
|
const infestedLichRotA = [
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyDJRomHuman", probability: 0.046 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyDJRomInfested", probability: 0.045 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyDrillbitHuman", probability: 0.046 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyDrillbitInfested", probability: 0.045 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyHarddriveHuman", probability: 0.046 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyHarddriveInfested", probability: 0.045 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyPacketHuman", probability: 0.046 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyPacketInfested", probability: 0.045 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyZekeHuman", probability: 0.046 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyZekeInfested", probability: 0.045 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandBillboardPosterA", probability: 0.045 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandBillboardPosterB", probability: 0.046 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandDespairPoster", probability: 0.045 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandGridPoster", probability: 0.046 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandHuddlePoster", probability: 0.045 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandJumpPoster", probability: 0.046 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandLimoPoster", probability: 0.045 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandLookingDownPosterDay", probability: 0.046 },
|
||||||
|
{
|
||||||
|
type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandLookingDownPosterNight",
|
||||||
|
probability: 0.045
|
||||||
|
},
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandSillyPoster", probability: 0.046 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandWhiteBluePoster", probability: 0.045 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/ShipDecos/BoybandPosters/BoybandWhitePinkPoster", probability: 0.045 }
|
||||||
|
];
|
||||||
|
const infestedLichRotB = [
|
||||||
|
{ type: "/Lotus/StoreItems/Upgrades/Skins/Effects/InfestedLichEphemeraA", probability: 0.072 },
|
||||||
|
{ type: "/Lotus/StoreItems/Upgrades/Skins/Effects/InfestedLichEphemeraB", probability: 0.071 },
|
||||||
|
{ type: "/Lotus/StoreItems/Upgrades/Skins/Effects/InfestedLichEphemeraC", probability: 0.072 },
|
||||||
|
{ type: "/Lotus/StoreItems/Upgrades/Skins/Effects/InfestedLichEphemeraD", probability: 0.071 },
|
||||||
|
{ type: "/Lotus/StoreItems/Upgrades/Skins/Effects/InfestedLichEphemeraE", probability: 0.072 },
|
||||||
|
{ type: "/Lotus/StoreItems/Upgrades/Skins/Effects/InfestedLichEphemeraF", probability: 0.071 },
|
||||||
|
{ type: "/Lotus/StoreItems/Upgrades/Skins/Effects/InfestedLichEphemeraG", probability: 0.071 },
|
||||||
|
{ type: "/Lotus/StoreItems/Upgrades/Skins/Effects/InfestedLichEphemeraH", probability: 0.072 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/Emotes/DanceDJRomHype", probability: 0.071 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/Emotes/DancePacketWindmillShuffle", probability: 0.072 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/Emotes/DanceHarddrivePony", probability: 0.071 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/Emotes/DanceDrillbitCrisscross", probability: 0.072 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/Emotes/DanceZekeCanthavethis", probability: 0.071 },
|
||||||
|
{ type: "/Lotus/StoreItems/Types/Items/PhotoBooth/PhotoboothTileRJLasXStadiumBossArena", probability: 0.071 }
|
||||||
|
];
|
||||||
|
export const getInfestedLichItemRewards = (fp: bigint): string[] => {
|
||||||
|
const rng = new SRng(fp);
|
||||||
|
const rotAReward = getRewardAtPercentage(infestedLichRotA, rng.randomFloat())!.type;
|
||||||
|
rng.randomFloat(); // unused afaict
|
||||||
|
const rotBReward = getRewardAtPercentage(infestedLichRotB, rng.randomFloat())!.type;
|
||||||
|
return [rotAReward, rotBReward];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendCodaFinishedMessage = async (
|
||||||
|
inventory: TInventoryDatabaseDocument,
|
||||||
|
fp: bigint = generateRewardSeed(),
|
||||||
|
name: string = "ZEKE_BEATWOMAN_TM.1999",
|
||||||
|
killed: boolean = true
|
||||||
|
): Promise<void> => {
|
||||||
|
const att: string[] = [];
|
||||||
|
|
||||||
|
// First vanquish/convert gives a sigil
|
||||||
|
const sigil = killed
|
||||||
|
? "/Lotus/Upgrades/Skins/Sigils/InfLichVanquishedSigil"
|
||||||
|
: "/Lotus/Upgrades/Skins/Sigils/InfLichConvertedSigil";
|
||||||
|
if (!inventory.WeaponSkins.find(x => x.ItemType == sigil)) {
|
||||||
|
att.push(toStoreItem(sigil));
|
||||||
|
}
|
||||||
|
|
||||||
|
const [rotAReward, rotBReward] = getInfestedLichItemRewards(fp);
|
||||||
|
att.push(fromStoreItem(rotAReward));
|
||||||
|
att.push(fromStoreItem(rotBReward));
|
||||||
|
|
||||||
|
let countedAtt: ITypeCount[] | undefined;
|
||||||
|
if (killed) {
|
||||||
|
countedAtt = [
|
||||||
|
{
|
||||||
|
ItemType: "/Lotus/Types/Items/MiscItems/CodaWeaponBucks",
|
||||||
|
ItemCount: getKillTokenRewardCount(fp)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
await createMessage(inventory.accountOwnerId, [
|
||||||
|
{
|
||||||
|
sndr: "/Lotus/Language/Bosses/Ordis",
|
||||||
|
msg: "/Lotus/Language/Inbox/VanquishBandMsgBody",
|
||||||
|
arg: [
|
||||||
|
{
|
||||||
|
Key: "LICH_NAME",
|
||||||
|
Tag: name
|
||||||
|
}
|
||||||
|
],
|
||||||
|
att: att,
|
||||||
|
countedAtt: countedAtt,
|
||||||
|
sub: "/Lotus/Language/Inbox/VanquishBandMsgTitle",
|
||||||
|
icon: "/Lotus/Interface/Icons/Npcs/Ordis.png",
|
||||||
|
highPriority: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
@ -1399,7 +1399,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
//How many Gift do you have left*(gift spends the trade)
|
//How many Gift do you have left*(gift spends the trade)
|
||||||
GiftsRemaining: { type: Number, default: 8 },
|
GiftsRemaining: { type: Number, default: 8 },
|
||||||
//Curent trade info Giving or Getting items
|
//Curent trade info Giving or Getting items
|
||||||
PendingTrades: [Schema.Types.Mixed],
|
//PendingTrades: [Schema.Types.Mixed],
|
||||||
|
|
||||||
//Syndicate currently being pledged to.
|
//Syndicate currently being pledged to.
|
||||||
SupportedSyndicate: String,
|
SupportedSyndicate: String,
|
||||||
@ -1449,7 +1449,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: [Schema.Types.Mixed],
|
||||||
|
|
||||||
//Item for EquippedGear example:Scaner,LoadoutTechSummon etc
|
//Item for EquippedGear example:Scaner,LoadoutTechSummon etc
|
||||||
Consumables: [typeCountSchema],
|
Consumables: [typeCountSchema],
|
||||||
@ -1495,7 +1495,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
//item like DojoKey or Boss missions key
|
//item like DojoKey or Boss missions key
|
||||||
LevelKeys: [typeCountSchema],
|
LevelKeys: [typeCountSchema],
|
||||||
//Active quests
|
//Active quests
|
||||||
Quests: [Schema.Types.Mixed],
|
//Quests: [Schema.Types.Mixed],
|
||||||
|
|
||||||
//Cosmetics like profile glyphs\Kavasa Prime Kubrow Collar\Game Theme etc
|
//Cosmetics like profile glyphs\Kavasa Prime Kubrow Collar\Game Theme etc
|
||||||
FlavourItems: [FlavourItemSchema],
|
FlavourItems: [FlavourItemSchema],
|
||||||
@ -1534,7 +1534,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
TauntHistory: { type: [tauntSchema], default: undefined },
|
TauntHistory: { type: [tauntSchema], default: undefined },
|
||||||
|
|
||||||
//noShow2FA,VisitPrimeVault etc
|
//noShow2FA,VisitPrimeVault etc
|
||||||
WebFlags: Schema.Types.Mixed,
|
//WebFlags: Schema.Types.Mixed,
|
||||||
//Id CompletedAlerts
|
//Id CompletedAlerts
|
||||||
CompletedAlerts: [String],
|
CompletedAlerts: [String],
|
||||||
|
|
||||||
@ -1554,7 +1554,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
//the color your clan requests like Items/Research/DojoColors/DojoColorPlainsB
|
//the color your clan requests like Items/Research/DojoColors/DojoColorPlainsB
|
||||||
ActiveDojoColorResearch: String,
|
ActiveDojoColorResearch: String,
|
||||||
|
|
||||||
SentientSpawnChanceBoosters: Schema.Types.Mixed,
|
//SentientSpawnChanceBoosters: Schema.Types.Mixed,
|
||||||
|
|
||||||
QualifyingInvasions: [invasionProgressSchema],
|
QualifyingInvasions: [invasionProgressSchema],
|
||||||
FactionScores: [Number],
|
FactionScores: [Number],
|
||||||
@ -1589,10 +1589,10 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
// open location store like EidolonPlainsDiscoverable or OrbVallisCaveDiscoverable
|
// open location store like EidolonPlainsDiscoverable or OrbVallisCaveDiscoverable
|
||||||
DiscoveredMarkers: [discoveredMarkerSchema],
|
DiscoveredMarkers: [discoveredMarkerSchema],
|
||||||
//Open location mission like "JobId" + "StageCompletions"
|
//Open location mission like "JobId" + "StageCompletions"
|
||||||
CompletedJobs: [Schema.Types.Mixed],
|
//CompletedJobs: [Schema.Types.Mixed],
|
||||||
|
|
||||||
//Game mission\ivent score example "Tag": "WaterFight", "Best": 170, "Count": 1258,
|
//Game mission\ivent score example "Tag": "WaterFight", "Best": 170, "Count": 1258,
|
||||||
PersonalGoalProgress: [Schema.Types.Mixed],
|
//PersonalGoalProgress: [Schema.Types.Mixed],
|
||||||
|
|
||||||
//Setting interface Style
|
//Setting interface Style
|
||||||
ThemeStyle: String,
|
ThemeStyle: String,
|
||||||
@ -1622,13 +1622,13 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
LibraryActiveDailyTaskInfo: libraryDailyTaskInfoSchema,
|
LibraryActiveDailyTaskInfo: libraryDailyTaskInfoSchema,
|
||||||
|
|
||||||
//https://warframe.fandom.com/wiki/Invasion
|
//https://warframe.fandom.com/wiki/Invasion
|
||||||
InvasionChainProgress: [Schema.Types.Mixed],
|
//InvasionChainProgress: [Schema.Types.Mixed],
|
||||||
|
|
||||||
//CorpusLich or GrineerLich
|
//CorpusLich or GrineerLich
|
||||||
NemesisAbandonedRewards: { type: [String], default: [] },
|
NemesisAbandonedRewards: { type: [String], default: [] },
|
||||||
Nemesis: nemesisSchema,
|
Nemesis: nemesisSchema,
|
||||||
NemesisHistory: { type: [nemesisSchema], default: undefined },
|
NemesisHistory: { type: [nemesisSchema], default: undefined },
|
||||||
LastNemesisAllySpawnTime: Schema.Types.Mixed,
|
//LastNemesisAllySpawnTime: Schema.Types.Mixed,
|
||||||
|
|
||||||
//TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social)
|
//TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social)
|
||||||
Settings: settingsSchema,
|
Settings: settingsSchema,
|
||||||
@ -1642,7 +1642,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
PlayerSkills: { type: playerSkillsSchema, default: {} },
|
PlayerSkills: { type: playerSkillsSchema, default: {} },
|
||||||
|
|
||||||
//TradeBannedUntil data
|
//TradeBannedUntil data
|
||||||
TradeBannedUntil: Schema.Types.Mixed,
|
//TradeBannedUntil: Schema.Types.Mixed,
|
||||||
|
|
||||||
//https://warframe.fandom.com/wiki/Helminth
|
//https://warframe.fandom.com/wiki/Helminth
|
||||||
InfestedFoundry: infestedFoundrySchema,
|
InfestedFoundry: infestedFoundrySchema,
|
||||||
@ -1662,23 +1662,24 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
|
|
||||||
//Unknown and system
|
//Unknown and system
|
||||||
DuviriInfo: DuviriInfoSchema,
|
DuviriInfo: DuviriInfoSchema,
|
||||||
|
LastInventorySync: Schema.Types.ObjectId,
|
||||||
Mailbox: MailboxSchema,
|
Mailbox: MailboxSchema,
|
||||||
HandlerPoints: Number,
|
HandlerPoints: Number,
|
||||||
ChallengesFixVersion: { type: Number, default: 6 },
|
ChallengesFixVersion: { type: Number, default: 6 },
|
||||||
PlayedParkourTutorial: Boolean,
|
PlayedParkourTutorial: Boolean,
|
||||||
ActiveLandscapeTraps: [Schema.Types.Mixed],
|
//ActiveLandscapeTraps: [Schema.Types.Mixed],
|
||||||
RepVotes: [Schema.Types.Mixed],
|
//RepVotes: [Schema.Types.Mixed],
|
||||||
LeagueTickets: [Schema.Types.Mixed],
|
//LeagueTickets: [Schema.Types.Mixed],
|
||||||
HasContributedToDojo: Boolean,
|
HasContributedToDojo: Boolean,
|
||||||
HWIDProtectEnabled: Boolean,
|
HWIDProtectEnabled: Boolean,
|
||||||
LoadOutPresets: { type: Schema.Types.ObjectId, ref: "Loadout" },
|
LoadOutPresets: { type: Schema.Types.ObjectId, ref: "Loadout" },
|
||||||
CurrentLoadOutIds: [oidSchema],
|
CurrentLoadOutIds: [oidSchema],
|
||||||
RandomUpgradesIdentified: Number,
|
RandomUpgradesIdentified: Number,
|
||||||
BountyScore: Number,
|
BountyScore: Number,
|
||||||
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],
|
//UsedDailyDeals: [Schema.Types.Mixed],
|
||||||
CollectibleSeries: { type: [collectibleEntrySchema], default: undefined },
|
CollectibleSeries: { type: [collectibleEntrySchema], default: undefined },
|
||||||
HasResetAccount: { type: Boolean, default: false },
|
HasResetAccount: { type: Boolean, default: false },
|
||||||
|
|
||||||
@ -1759,6 +1760,9 @@ inventorySchema.set("toJSON", {
|
|||||||
sn: inventoryDatabase.LockedWeaponGroup.sn ? toOid(inventoryDatabase.LockedWeaponGroup.sn) : undefined
|
sn: inventoryDatabase.LockedWeaponGroup.sn ? toOid(inventoryDatabase.LockedWeaponGroup.sn) : undefined
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (inventoryDatabase.LastInventorySync) {
|
||||||
|
inventoryResponse.LastInventorySync = toOid(inventoryDatabase.LastInventorySync);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
dict_uk,
|
dict_uk,
|
||||||
dict_zh,
|
dict_zh,
|
||||||
ExportArcanes,
|
ExportArcanes,
|
||||||
|
ExportBoosters,
|
||||||
ExportCustoms,
|
ExportCustoms,
|
||||||
ExportDrones,
|
ExportDrones,
|
||||||
ExportGear,
|
ExportGear,
|
||||||
@ -217,15 +218,30 @@ export const convertInboxMessage = (message: IInboxMessage): IMessage => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const isStoreItem = (type: string): boolean => {
|
export const isStoreItem = (type: string): boolean => {
|
||||||
return type.startsWith("/Lotus/StoreItems/");
|
return type.startsWith("/Lotus/StoreItems/") || type in ExportBoosters;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toStoreItem = (type: string): string => {
|
export const toStoreItem = (type: string): string => {
|
||||||
|
if (type.startsWith("/Lotus/Types/StoreItems/Boosters/")) {
|
||||||
|
const boosterEntry = Object.entries(ExportBoosters).find(arr => arr[1].typeName == type);
|
||||||
|
if (boosterEntry) {
|
||||||
|
return boosterEntry[0];
|
||||||
|
}
|
||||||
|
throw new Error(`could not convert ${type} to a store item`);
|
||||||
|
}
|
||||||
return "/Lotus/StoreItems/" + type.substring("/Lotus/".length);
|
return "/Lotus/StoreItems/" + type.substring("/Lotus/".length);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fromStoreItem = (type: string): string => {
|
export const fromStoreItem = (type: string): string => {
|
||||||
|
if (type.startsWith("/Lotus/StoreItems/")) {
|
||||||
return "/Lotus/" + type.substring("/Lotus/StoreItems/".length);
|
return "/Lotus/" + type.substring("/Lotus/StoreItems/".length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type in ExportBoosters) {
|
||||||
|
return ExportBoosters[type].typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`${type} is not a store item`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDefaultUpgrades = (parts: string[]): IDefaultUpgrade[] | undefined => {
|
export const getDefaultUpgrades = (parts: string[]): IDefaultUpgrade[] | undefined => {
|
||||||
|
@ -77,7 +77,6 @@ const getRandomLoginReward = (rng: CRng, day: number, inventory: TInventoryDatab
|
|||||||
const reward = rng.randomReward(randomRewards)!;
|
const reward = rng.randomReward(randomRewards)!;
|
||||||
//const reward = randomRewards.find(x => x.RewardType == "RT_BOOSTER")!;
|
//const reward = randomRewards.find(x => x.RewardType == "RT_BOOSTER")!;
|
||||||
if (reward.RewardType == "RT_RANDOM_RECIPE") {
|
if (reward.RewardType == "RT_RANDOM_RECIPE") {
|
||||||
// Not very faithful implementation but roughly the same idea
|
|
||||||
const masteredItems = new Set();
|
const masteredItems = new Set();
|
||||||
for (const entry of inventory.XPInfo) {
|
for (const entry of inventory.XPInfo) {
|
||||||
masteredItems.add(entry.ItemType);
|
masteredItems.add(entry.ItemType);
|
||||||
@ -95,12 +94,12 @@ const getRandomLoginReward = (rng: CRng, day: number, inventory: TInventoryDatab
|
|||||||
}
|
}
|
||||||
const eligibleRecipes: string[] = [];
|
const eligibleRecipes: string[] = [];
|
||||||
for (const [uniqueName, recipe] of Object.entries(ExportRecipes)) {
|
for (const [uniqueName, recipe] of Object.entries(ExportRecipes)) {
|
||||||
if (unmasteredItems.has(recipe.resultType)) {
|
if (!recipe.excludeFromMarket && unmasteredItems.has(recipe.resultType)) {
|
||||||
eligibleRecipes.push(uniqueName);
|
eligibleRecipes.push(uniqueName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (eligibleRecipes.length == 0) {
|
if (eligibleRecipes.length == 0) {
|
||||||
// This account has all warframes and weapons already mastered (filthy cheater), need a different reward.
|
// This account has all applicable warframes and weapons already mastered (filthy cheater), need a different reward.
|
||||||
return getRandomLoginReward(rng, day, inventory);
|
return getRandomLoginReward(rng, day, inventory);
|
||||||
}
|
}
|
||||||
reward.StoreItemType = toStoreItem(rng.randomElement(eligibleRecipes));
|
reward.StoreItemType = toStoreItem(rng.randomElement(eligibleRecipes));
|
||||||
|
@ -55,7 +55,7 @@ import kuriaMessage50 from "@/static/fixed_responses/kuriaMessages/fiftyPercent.
|
|||||||
import kuriaMessage75 from "@/static/fixed_responses/kuriaMessages/seventyFivePercent.json";
|
import kuriaMessage75 from "@/static/fixed_responses/kuriaMessages/seventyFivePercent.json";
|
||||||
import kuriaMessage100 from "@/static/fixed_responses/kuriaMessages/oneHundredPercent.json";
|
import kuriaMessage100 from "@/static/fixed_responses/kuriaMessages/oneHundredPercent.json";
|
||||||
import conservationAnimals from "@/static/fixed_responses/conservationAnimals.json";
|
import conservationAnimals from "@/static/fixed_responses/conservationAnimals.json";
|
||||||
import { getInfNodes, getWeaponsForManifest } from "@/src/helpers/nemesisHelpers";
|
import { getInfNodes, getWeaponsForManifest, sendCodaFinishedMessage } from "@/src/helpers/nemesisHelpers";
|
||||||
import { Loadout } from "../models/inventoryModels/loadoutModel";
|
import { Loadout } from "../models/inventoryModels/loadoutModel";
|
||||||
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
|
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
|
||||||
import { getLiteSortie, getWorldState, idToWeek } from "./worldStateService";
|
import { getLiteSortie, getWorldState, idToWeek } from "./worldStateService";
|
||||||
@ -639,7 +639,10 @@ export const addMissionInventoryUpdates = async (
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (value.killed) {
|
if (value.killed) {
|
||||||
if (value.weaponLoc) {
|
if (
|
||||||
|
value.weaponLoc &&
|
||||||
|
inventory.Nemesis.Faction != "FC_INFESTATION" // weaponLoc is "/Lotus/Language/Weapons/DerelictCernosName" for these for some reason
|
||||||
|
) {
|
||||||
const weaponType = getWeaponsForManifest(inventory.Nemesis.manifest)[
|
const weaponType = getWeaponsForManifest(inventory.Nemesis.manifest)[
|
||||||
inventory.Nemesis.WeaponIdx
|
inventory.Nemesis.WeaponIdx
|
||||||
];
|
];
|
||||||
@ -657,6 +660,11 @@ export const addMissionInventoryUpdates = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TOVERIFY: Is the inbox message also sent when converting a lich? If not, how are the rewards given?
|
||||||
|
if (inventory.Nemesis.Faction == "FC_INFESTATION") {
|
||||||
|
await sendCodaFinishedMessage(inventory, inventory.Nemesis.fp, value.nemesisName, value.killed);
|
||||||
|
}
|
||||||
|
|
||||||
inventory.Nemesis = undefined;
|
inventory.Nemesis = undefined;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -18,7 +18,10 @@ export const getRandomInt = (min: number, max: number): number => {
|
|||||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRewardAtPercentage = <T extends { probability: number }>(pool: T[], percentage: number): T | undefined => {
|
export const getRewardAtPercentage = <T extends { probability: number }>(
|
||||||
|
pool: T[],
|
||||||
|
percentage: number
|
||||||
|
): T | undefined => {
|
||||||
if (pool.length == 0) return;
|
if (pool.length == 0) return;
|
||||||
|
|
||||||
const totalChance = pool.reduce((accum, item) => accum + item.probability, 0);
|
const totalChance = pool.reduce((accum, item) => accum + item.probability, 0);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
import { unixTimesInMs } from "@/src/constants/timeConstants";
|
||||||
|
import { catBreadHash } from "@/src/helpers/stringHelpers";
|
||||||
import { CRng, mixSeeds } from "@/src/services/rngService";
|
import { CRng, mixSeeds } from "@/src/services/rngService";
|
||||||
import { IMongoDate } from "@/src/types/commonTypes";
|
import { IMongoDate } from "@/src/types/commonTypes";
|
||||||
import { IItemManifest, IVendorInfo, IVendorManifest } from "@/src/types/vendorTypes";
|
import { IItemManifest, IVendorInfo, IVendorManifest } from "@/src/types/vendorTypes";
|
||||||
@ -6,7 +7,6 @@ import { ExportVendors, IRange } from "warframe-public-export-plus";
|
|||||||
|
|
||||||
import ArchimedeanVendorManifest from "@/static/fixed_responses/getVendorInfo/ArchimedeanVendorManifest.json";
|
import ArchimedeanVendorManifest from "@/static/fixed_responses/getVendorInfo/ArchimedeanVendorManifest.json";
|
||||||
import DeimosEntratiFragmentVendorProductsManifest from "@/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json";
|
import DeimosEntratiFragmentVendorProductsManifest from "@/static/fixed_responses/getVendorInfo/DeimosEntratiFragmentVendorProductsManifest.json";
|
||||||
import DeimosFishmongerVendorManifest from "@/static/fixed_responses/getVendorInfo/DeimosFishmongerVendorManifest.json";
|
|
||||||
import DeimosHivemindCommisionsManifestFishmonger from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestFishmonger.json";
|
import DeimosHivemindCommisionsManifestFishmonger from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestFishmonger.json";
|
||||||
import DeimosHivemindCommisionsManifestPetVendor from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestPetVendor.json";
|
import DeimosHivemindCommisionsManifestPetVendor from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestPetVendor.json";
|
||||||
import DeimosHivemindCommisionsManifestProspector from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestProspector.json";
|
import DeimosHivemindCommisionsManifestProspector from "@/static/fixed_responses/getVendorInfo/DeimosHivemindCommisionsManifestProspector.json";
|
||||||
@ -22,12 +22,10 @@ import HubsIronwakeDondaVendorManifest from "@/static/fixed_responses/getVendorI
|
|||||||
import HubsRailjackCrewMemberVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsRailjackCrewMemberVendorManifest.json";
|
import HubsRailjackCrewMemberVendorManifest from "@/static/fixed_responses/getVendorInfo/HubsRailjackCrewMemberVendorManifest.json";
|
||||||
import MaskSalesmanManifest from "@/static/fixed_responses/getVendorInfo/MaskSalesmanManifest.json";
|
import MaskSalesmanManifest from "@/static/fixed_responses/getVendorInfo/MaskSalesmanManifest.json";
|
||||||
import Nova1999ConquestShopManifest from "@/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json";
|
import Nova1999ConquestShopManifest from "@/static/fixed_responses/getVendorInfo/Nova1999ConquestShopManifest.json";
|
||||||
import OstronFishmongerVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronFishmongerVendorManifest.json";
|
|
||||||
import OstronPetVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json";
|
import OstronPetVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json";
|
||||||
import OstronProspectorVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronProspectorVendorManifest.json";
|
import OstronProspectorVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronProspectorVendorManifest.json";
|
||||||
import RadioLegionIntermission12VendorManifest from "@/static/fixed_responses/getVendorInfo/RadioLegionIntermission12VendorManifest.json";
|
import RadioLegionIntermission12VendorManifest from "@/static/fixed_responses/getVendorInfo/RadioLegionIntermission12VendorManifest.json";
|
||||||
import SolarisDebtTokenVendorRepossessionsManifest from "@/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorRepossessionsManifest.json";
|
import SolarisDebtTokenVendorRepossessionsManifest from "@/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorRepossessionsManifest.json";
|
||||||
import SolarisFishmongerVendorManifest from "@/static/fixed_responses/getVendorInfo/SolarisFishmongerVendorManifest.json";
|
|
||||||
import SolarisProspectorVendorManifest from "@/static/fixed_responses/getVendorInfo/SolarisProspectorVendorManifest.json";
|
import SolarisProspectorVendorManifest from "@/static/fixed_responses/getVendorInfo/SolarisProspectorVendorManifest.json";
|
||||||
import Temple1999VendorManifest from "@/static/fixed_responses/getVendorInfo/Temple1999VendorManifest.json";
|
import Temple1999VendorManifest from "@/static/fixed_responses/getVendorInfo/Temple1999VendorManifest.json";
|
||||||
import TeshinHardModeVendorManifest from "@/static/fixed_responses/getVendorInfo/TeshinHardModeVendorManifest.json";
|
import TeshinHardModeVendorManifest from "@/static/fixed_responses/getVendorInfo/TeshinHardModeVendorManifest.json";
|
||||||
@ -36,7 +34,6 @@ import ZarimanCommisionsManifestArchimedean from "@/static/fixed_responses/getVe
|
|||||||
const rawVendorManifests: IVendorManifest[] = [
|
const rawVendorManifests: IVendorManifest[] = [
|
||||||
ArchimedeanVendorManifest,
|
ArchimedeanVendorManifest,
|
||||||
DeimosEntratiFragmentVendorProductsManifest,
|
DeimosEntratiFragmentVendorProductsManifest,
|
||||||
DeimosFishmongerVendorManifest,
|
|
||||||
DeimosHivemindCommisionsManifestFishmonger,
|
DeimosHivemindCommisionsManifestFishmonger,
|
||||||
DeimosHivemindCommisionsManifestPetVendor,
|
DeimosHivemindCommisionsManifestPetVendor,
|
||||||
DeimosHivemindCommisionsManifestProspector,
|
DeimosHivemindCommisionsManifestProspector,
|
||||||
@ -52,12 +49,10 @@ const rawVendorManifests: IVendorManifest[] = [
|
|||||||
HubsRailjackCrewMemberVendorManifest,
|
HubsRailjackCrewMemberVendorManifest,
|
||||||
MaskSalesmanManifest,
|
MaskSalesmanManifest,
|
||||||
Nova1999ConquestShopManifest,
|
Nova1999ConquestShopManifest,
|
||||||
OstronFishmongerVendorManifest,
|
|
||||||
OstronPetVendorManifest,
|
OstronPetVendorManifest,
|
||||||
OstronProspectorVendorManifest,
|
OstronProspectorVendorManifest,
|
||||||
RadioLegionIntermission12VendorManifest,
|
RadioLegionIntermission12VendorManifest,
|
||||||
SolarisDebtTokenVendorRepossessionsManifest,
|
SolarisDebtTokenVendorRepossessionsManifest,
|
||||||
SolarisFishmongerVendorManifest,
|
|
||||||
SolarisProspectorVendorManifest,
|
SolarisProspectorVendorManifest,
|
||||||
Temple1999VendorManifest,
|
Temple1999VendorManifest,
|
||||||
TeshinHardModeVendorManifest, // uses preprocessing
|
TeshinHardModeVendorManifest, // uses preprocessing
|
||||||
@ -87,17 +82,11 @@ const generatableVendors: IGeneratableVendorInfo[] = [
|
|||||||
cycleOffset: 1744934400_000,
|
cycleOffset: 1744934400_000,
|
||||||
cycleDuration: 4 * unixTimesInMs.day
|
cycleDuration: 4 * unixTimesInMs.day
|
||||||
},
|
},
|
||||||
{
|
|
||||||
_id: { $oid: "5be4a159b144f3cdf1c22efa" },
|
|
||||||
TypeName: "/Lotus/Types/Game/VendorManifests/Solaris/DebtTokenVendorManifest",
|
|
||||||
RandomSeedType: "VRST_FLAVOUR_TEXT",
|
|
||||||
cycleDuration: unixTimesInMs.hour
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
_id: { $oid: "61ba123467e5d37975aeeb03" },
|
_id: { $oid: "61ba123467e5d37975aeeb03" },
|
||||||
TypeName: "/Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest",
|
TypeName: "/Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest",
|
||||||
RandomSeedType: "VRST_FLAVOUR_TEXT",
|
RandomSeedType: "VRST_FLAVOUR_TEXT",
|
||||||
cycleDuration: unixTimesInMs.week
|
cycleDuration: unixTimesInMs.week // TODO: Auto-detect this based on the items, so we don't need to specify it explicitly.
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
// _id: { $oid: "5dbb4c41e966f7886c3ce939" },
|
// _id: { $oid: "5dbb4c41e966f7886c3ce939" },
|
||||||
@ -105,6 +94,10 @@ const generatableVendors: IGeneratableVendorInfo[] = [
|
|||||||
// }
|
// }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const getVendorOid = (typeName: string): string => {
|
||||||
|
return "5be4a159b144f3cd" + catBreadHash(typeName).toString(16).padStart(8, "0");
|
||||||
|
};
|
||||||
|
|
||||||
export const getVendorManifestByTypeName = (typeName: string): IVendorManifest | undefined => {
|
export const getVendorManifestByTypeName = (typeName: string): IVendorManifest | undefined => {
|
||||||
for (const vendorManifest of rawVendorManifests) {
|
for (const vendorManifest of rawVendorManifests) {
|
||||||
if (vendorManifest.VendorInfo.TypeName == typeName) {
|
if (vendorManifest.VendorInfo.TypeName == typeName) {
|
||||||
@ -116,6 +109,14 @@ export const getVendorManifestByTypeName = (typeName: string): IVendorManifest |
|
|||||||
return generateVendorManifest(vendorInfo);
|
return generateVendorManifest(vendorInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (typeName in ExportVendors) {
|
||||||
|
return generateVendorManifest({
|
||||||
|
_id: { $oid: getVendorOid(typeName) },
|
||||||
|
TypeName: typeName,
|
||||||
|
RandomSeedType: ExportVendors[typeName].randomSeedType,
|
||||||
|
cycleDuration: unixTimesInMs.hour
|
||||||
|
});
|
||||||
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -130,6 +131,17 @@ export const getVendorManifestByOid = (oid: string): IVendorManifest | undefined
|
|||||||
return generateVendorManifest(vendorInfo);
|
return generateVendorManifest(vendorInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const [typeName, manifest] of Object.entries(ExportVendors)) {
|
||||||
|
const typeNameOid = getVendorOid(typeName);
|
||||||
|
if (typeNameOid == oid) {
|
||||||
|
return generateVendorManifest({
|
||||||
|
_id: { $oid: typeNameOid },
|
||||||
|
TypeName: typeName,
|
||||||
|
RandomSeedType: manifest.randomSeedType,
|
||||||
|
cycleDuration: unixTimesInMs.hour
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,7 +207,7 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
|
|||||||
const rng = new CRng(mixSeeds(vendorSeed, cycleIndex));
|
const rng = new CRng(mixSeeds(vendorSeed, cycleIndex));
|
||||||
const manifest = ExportVendors[vendorInfo.TypeName];
|
const manifest = ExportVendors[vendorInfo.TypeName];
|
||||||
const offersToAdd = [];
|
const offersToAdd = [];
|
||||||
if (manifest.numItems && manifest.numItems.minValue != manifest.numItems.maxValue) {
|
if (manifest.numItems && !manifest.isOneBinPerCycle) {
|
||||||
const numItemsTarget = rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue);
|
const numItemsTarget = rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue);
|
||||||
while (processed.ItemManifest.length + offersToAdd.length < numItemsTarget) {
|
while (processed.ItemManifest.length + offersToAdd.length < numItemsTarget) {
|
||||||
// TODO: Consider per-bin item limits
|
// TODO: Consider per-bin item limits
|
||||||
@ -263,6 +275,13 @@ const generateVendorManifest = (vendorInfo: IGeneratableVendorInfo): IVendorMani
|
|||||||
) * rawItem.credits.step;
|
) * rawItem.credits.step;
|
||||||
item.RegularPrice = [value, value];
|
item.RegularPrice = [value, value];
|
||||||
}
|
}
|
||||||
|
if (rawItem.platinum) {
|
||||||
|
const value =
|
||||||
|
typeof rawItem.platinum == "number"
|
||||||
|
? rawItem.platinum
|
||||||
|
: rng.randomInt(rawItem.platinum.minValue, rawItem.platinum.maxValue);
|
||||||
|
item.PremiumPrice = [value, value];
|
||||||
|
}
|
||||||
if (vendorInfo.RandomSeedType) {
|
if (vendorInfo.RandomSeedType) {
|
||||||
item.LocTagRandSeed = (rng.randomInt(0, 0xffff) << 16) | rng.randomInt(0, 0xffff);
|
item.LocTagRandSeed = (rng.randomInt(0, 0xffff) << 16) | rng.randomInt(0, 0xffff);
|
||||||
if (vendorInfo.RandomSeedType == "VRST_WEAPON") {
|
if (vendorInfo.RandomSeedType == "VRST_WEAPON") {
|
||||||
|
@ -52,6 +52,7 @@ export interface IInventoryDatabase
|
|||||||
| "LastLiteSortieReward"
|
| "LastLiteSortieReward"
|
||||||
| "CrewMembers"
|
| "CrewMembers"
|
||||||
| "QualifyingInvasions"
|
| "QualifyingInvasions"
|
||||||
|
| "LastInventorySync"
|
||||||
| TEquipmentKey
|
| TEquipmentKey
|
||||||
>,
|
>,
|
||||||
InventoryDatabaseEquipment {
|
InventoryDatabaseEquipment {
|
||||||
@ -89,6 +90,7 @@ export interface IInventoryDatabase
|
|||||||
LastLiteSortieReward?: ILastSortieRewardDatabase[];
|
LastLiteSortieReward?: ILastSortieRewardDatabase[];
|
||||||
CrewMembers: ICrewMemberDatabase[];
|
CrewMembers: ICrewMemberDatabase[];
|
||||||
QualifyingInvasions: IInvasionProgressDatabase[];
|
QualifyingInvasions: IInvasionProgressDatabase[];
|
||||||
|
LastInventorySync?: Types.ObjectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IQuestKeyDatabase {
|
export interface IQuestKeyDatabase {
|
||||||
@ -258,7 +260,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
EquippedGear: string[];
|
EquippedGear: string[];
|
||||||
DeathMarks: string[];
|
DeathMarks: string[];
|
||||||
FusionTreasures: IFusionTreasure[];
|
FusionTreasures: IFusionTreasure[];
|
||||||
WebFlags: IWebFlags;
|
//WebFlags: IWebFlags;
|
||||||
CompletedAlerts: string[];
|
CompletedAlerts: string[];
|
||||||
Consumables: ITypeCount[];
|
Consumables: ITypeCount[];
|
||||||
LevelKeys: ITypeCount[];
|
LevelKeys: ITypeCount[];
|
||||||
@ -268,10 +270,10 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
KubrowPetEggs?: IKubrowPetEggClient[];
|
KubrowPetEggs?: IKubrowPetEggClient[];
|
||||||
LoreFragmentScans: ILoreFragmentScan[];
|
LoreFragmentScans: ILoreFragmentScan[];
|
||||||
EquippedEmotes: string[];
|
EquippedEmotes: string[];
|
||||||
PendingTrades: IPendingTrade[];
|
//PendingTrades: IPendingTrade[];
|
||||||
Boosters: IBooster[];
|
Boosters: IBooster[];
|
||||||
ActiveDojoColorResearch: string;
|
ActiveDojoColorResearch: string;
|
||||||
SentientSpawnChanceBoosters: ISentientSpawnChanceBoosters;
|
//SentientSpawnChanceBoosters: ISentientSpawnChanceBoosters;
|
||||||
SupportedSyndicate?: string;
|
SupportedSyndicate?: string;
|
||||||
Affiliations: IAffiliation[];
|
Affiliations: IAffiliation[];
|
||||||
QualifyingInvasions: IInvasionProgressClient[];
|
QualifyingInvasions: IInvasionProgressClient[];
|
||||||
@ -293,19 +295,19 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
ActiveAvatarImageType: string;
|
ActiveAvatarImageType: string;
|
||||||
ShipDecorations: ITypeCount[];
|
ShipDecorations: ITypeCount[];
|
||||||
DiscoveredMarkers: IDiscoveredMarker[];
|
DiscoveredMarkers: IDiscoveredMarker[];
|
||||||
CompletedJobs: ICompletedJob[];
|
//CompletedJobs: ICompletedJob[];
|
||||||
FocusAbility?: string;
|
FocusAbility?: string;
|
||||||
FocusUpgrades: IFocusUpgrade[];
|
FocusUpgrades: IFocusUpgrade[];
|
||||||
HasContributedToDojo?: boolean;
|
HasContributedToDojo?: boolean;
|
||||||
HWIDProtectEnabled?: boolean;
|
HWIDProtectEnabled?: boolean;
|
||||||
KubrowPetPrints: IKubrowPetPrint[];
|
//KubrowPetPrints: IKubrowPetPrint[];
|
||||||
AlignmentReplay?: IAlignment;
|
AlignmentReplay?: IAlignment;
|
||||||
PersonalGoalProgress: IPersonalGoalProgress[];
|
//PersonalGoalProgress: IPersonalGoalProgress[];
|
||||||
ThemeStyle: string;
|
ThemeStyle: string;
|
||||||
ThemeBackground: string;
|
ThemeBackground: string;
|
||||||
ThemeSounds: string;
|
ThemeSounds: string;
|
||||||
BountyScore: number;
|
BountyScore: number;
|
||||||
ChallengeInstanceStates: IChallengeInstanceState[];
|
//ChallengeInstanceStates: IChallengeInstanceState[];
|
||||||
LoginMilestoneRewards: string[];
|
LoginMilestoneRewards: string[];
|
||||||
RecentVendorPurchases?: IRecentVendorPurchaseClient[];
|
RecentVendorPurchases?: IRecentVendorPurchaseClient[];
|
||||||
NodeIntrosCompleted: string[];
|
NodeIntrosCompleted: string[];
|
||||||
@ -313,17 +315,17 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
CompletedJobChains?: ICompletedJobChain[];
|
CompletedJobChains?: ICompletedJobChain[];
|
||||||
SeasonChallengeHistory: ISeasonChallenge[];
|
SeasonChallengeHistory: ISeasonChallenge[];
|
||||||
EquippedInstrument?: string;
|
EquippedInstrument?: string;
|
||||||
InvasionChainProgress: IInvasionChainProgress[];
|
//InvasionChainProgress: IInvasionChainProgress[];
|
||||||
Nemesis?: INemesisClient;
|
Nemesis?: INemesisClient;
|
||||||
NemesisHistory?: INemesisBaseClient[];
|
NemesisHistory?: INemesisBaseClient[];
|
||||||
LastNemesisAllySpawnTime?: IMongoDate;
|
//LastNemesisAllySpawnTime?: IMongoDate;
|
||||||
Settings?: ISettings;
|
Settings?: ISettings;
|
||||||
PersonalTechProjects: IPersonalTechProjectClient[];
|
PersonalTechProjects: IPersonalTechProjectClient[];
|
||||||
PlayerSkills: IPlayerSkills;
|
PlayerSkills: IPlayerSkills;
|
||||||
CrewShipAmmo: ITypeCount[];
|
CrewShipAmmo: ITypeCount[];
|
||||||
CrewShipWeaponSkins: IUpgradeClient[];
|
CrewShipWeaponSkins: IUpgradeClient[];
|
||||||
CrewShipSalvagedWeaponSkins: IUpgradeClient[];
|
CrewShipSalvagedWeaponSkins: IUpgradeClient[];
|
||||||
TradeBannedUntil?: IMongoDate;
|
//TradeBannedUntil?: IMongoDate;
|
||||||
PlayedParkourTutorial: boolean;
|
PlayedParkourTutorial: boolean;
|
||||||
SubscribedToEmailsPersonalized: number;
|
SubscribedToEmailsPersonalized: number;
|
||||||
InfestedFoundry?: IInfestedFoundryClient;
|
InfestedFoundry?: IInfestedFoundryClient;
|
||||||
@ -333,17 +335,17 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
LotusCustomization?: ILotusCustomization;
|
LotusCustomization?: ILotusCustomization;
|
||||||
UseAdultOperatorLoadout?: boolean;
|
UseAdultOperatorLoadout?: boolean;
|
||||||
NemesisAbandonedRewards: string[];
|
NemesisAbandonedRewards: string[];
|
||||||
LastInventorySync: IOid;
|
LastInventorySync?: IOid;
|
||||||
NextRefill?: IMongoDate;
|
NextRefill?: IMongoDate;
|
||||||
FoundToday?: IMiscItem[]; // for Argon Crystals
|
FoundToday?: IMiscItem[]; // for Argon Crystals
|
||||||
CustomMarkers?: ICustomMarkers[];
|
CustomMarkers?: ICustomMarkers[];
|
||||||
ActiveLandscapeTraps: any[];
|
//ActiveLandscapeTraps: any[];
|
||||||
EvolutionProgress?: IEvolutionProgress[];
|
EvolutionProgress?: IEvolutionProgress[];
|
||||||
RepVotes: any[];
|
//RepVotes: any[];
|
||||||
LeagueTickets: any[];
|
//LeagueTickets: any[];
|
||||||
Quests: any[];
|
//Quests: any[];
|
||||||
Robotics: any[];
|
//Robotics: any[];
|
||||||
UsedDailyDeals: any[];
|
//UsedDailyDeals: any[];
|
||||||
LibraryPersonalTarget?: string;
|
LibraryPersonalTarget?: string;
|
||||||
LibraryPersonalProgress: ILibraryPersonalProgress[];
|
LibraryPersonalProgress: ILibraryPersonalProgress[];
|
||||||
CollectibleSeries?: ICollectibleEntry[];
|
CollectibleSeries?: ICollectibleEntry[];
|
||||||
|
@ -1,106 +0,0 @@
|
|||||||
{
|
|
||||||
"VendorInfo": {
|
|
||||||
"_id": {
|
|
||||||
"$oid": "5f456e01c96976e97d6b8016"
|
|
||||||
},
|
|
||||||
"TypeName": "/Lotus/Types/Game/VendorManifests/Deimos/FishmongerVendorManifest",
|
|
||||||
"ItemManifest": [
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Deimos/FishParts/DeimosOrokinFishAPartItem",
|
|
||||||
"PremiumPrice": [9, 9],
|
|
||||||
"Bin": "BIN_1",
|
|
||||||
"QuantityMultiplier": 10,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e91b9"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishDPartItem",
|
|
||||||
"PremiumPrice": [17, 17],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e91ba"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishCPartItem",
|
|
||||||
"PremiumPrice": [10, 10],
|
|
||||||
"Bin": "BIN_1",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e91bb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishBPartItem",
|
|
||||||
"PremiumPrice": [6, 6],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e91bc"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Deimos/FishParts/DeimosInfestedFishAPartItem",
|
|
||||||
"PremiumPrice": [5, 5],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e91bd"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Deimos/FishParts/DeimosGenericSharedFishPartItem",
|
|
||||||
"PremiumPrice": [7, 7],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e91be"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"PropertyTextHash": "6DF13A7FB573C25B4B4F989CBEFFC615",
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
{
|
|
||||||
"VendorInfo": {
|
|
||||||
"_id": {
|
|
||||||
"$oid": "59d6e27ebcc718474eb17115"
|
|
||||||
},
|
|
||||||
"TypeName": "/Lotus/Types/Game/VendorManifests/Ostron/FishmongerVendorManifest",
|
|
||||||
"ItemManifest": [
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Eidolon/FishParts/DayUncommonFishAPartItem",
|
|
||||||
"PremiumPrice": [14, 14],
|
|
||||||
"Bin": "BIN_1",
|
|
||||||
"QuantityMultiplier": 10,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e9808"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Eidolon/FishParts/BothUncommonFishBPartItem",
|
|
||||||
"PremiumPrice": [12, 12],
|
|
||||||
"Bin": "BIN_1",
|
|
||||||
"QuantityMultiplier": 10,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e9809"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Eidolon/FishParts/DayCommonFishCPartItem",
|
|
||||||
"PremiumPrice": [8, 8],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e980a"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Eidolon/FishParts/DayCommonFishBPartItem",
|
|
||||||
"PremiumPrice": [7, 7],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e980b"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Eidolon/FishParts/DayCommonFishAPartItem",
|
|
||||||
"PremiumPrice": [10, 10],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e980c"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Eidolon/FishParts/BothCommonFishBPartItem",
|
|
||||||
"PremiumPrice": [8, 8],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e980d"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"PropertyTextHash": "CC3B9DAFB38F412998E90A41421A8986",
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
{
|
|
||||||
"VendorInfo": {
|
|
||||||
"_id": {
|
|
||||||
"$oid": "5b0de8556df82a56ea9bae82"
|
|
||||||
},
|
|
||||||
"TypeName": "/Lotus/Types/Game/VendorManifests/Solaris/FishmongerVendorManifest",
|
|
||||||
"ItemManifest": [
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Solaris/FishParts/CorpusFishThermalLaserItem",
|
|
||||||
"PremiumPrice": [15, 15],
|
|
||||||
"Bin": "BIN_1",
|
|
||||||
"QuantityMultiplier": 10,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e9515"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Solaris/FishParts/CorpusFishVenedoCaseItem",
|
|
||||||
"PremiumPrice": [8, 8],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e9516"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Solaris/FishParts/SolarisFishDissipatorCoilItem",
|
|
||||||
"PremiumPrice": [18, 18],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e9517"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Solaris/FishParts/CorpusFishExaBrainItem",
|
|
||||||
"PremiumPrice": [5, 5],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e9518"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Solaris/FishParts/CorpusFishAnoscopicSensorItem",
|
|
||||||
"PremiumPrice": [5, 5],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e9519"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"StoreItem": "/Lotus/StoreItems/Types/Items/Fish/Solaris/FishParts/GenericFishScrapItem",
|
|
||||||
"PremiumPrice": [5, 5],
|
|
||||||
"Bin": "BIN_0",
|
|
||||||
"QuantityMultiplier": 20,
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowMultipurchase": true,
|
|
||||||
"Id": {
|
|
||||||
"$oid": "66fd60b20ba592c4c95e951a"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"PropertyTextHash": "946131D0CF5CDF7C2C03BB967DE0DF49",
|
|
||||||
"Expiry": {
|
|
||||||
"$date": {
|
|
||||||
"$numberLong": "9999999000000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -34,8 +34,8 @@ dict = {
|
|||||||
code_rerollsNumber: `Anzahl der Umrollversuche`,
|
code_rerollsNumber: `Anzahl der Umrollversuche`,
|
||||||
code_viewStats: `Statistiken anzeigen`,
|
code_viewStats: `Statistiken anzeigen`,
|
||||||
code_rank: `Rang`,
|
code_rank: `Rang`,
|
||||||
code_rankUp: `[UNTRANSLATED] Rank up`,
|
code_rankUp: `Rang erhöhen`,
|
||||||
code_rankDown: `[UNTRANSLATED] Rank down`,
|
code_rankDown: `Rang verringern`,
|
||||||
code_count: `Anzahl`,
|
code_count: `Anzahl`,
|
||||||
code_focusAllUnlocked: `Alle Fokus-Schulen sind bereits freigeschaltet.`,
|
code_focusAllUnlocked: `Alle Fokus-Schulen sind bereits freigeschaltet.`,
|
||||||
code_focusUnlocked: `|COUNT| neue Fokus-Schulen freigeschaltet! Ein Inventar-Update wird benötigt, damit die Änderungen im Spiel sichtbar werden. Die Sternenkarte zu besuchen, sollte der einfachste Weg sein, dies auszulösen.`,
|
code_focusUnlocked: `|COUNT| neue Fokus-Schulen freigeschaltet! Ein Inventar-Update wird benötigt, damit die Änderungen im Spiel sichtbar werden. Die Sternenkarte zu besuchen, sollte der einfachste Weg sein, dies auszulösen.`,
|
||||||
@ -86,21 +86,21 @@ dict = {
|
|||||||
inventory_hoverboards: `K-Drives`,
|
inventory_hoverboards: `K-Drives`,
|
||||||
inventory_moaPets: `Moas`,
|
inventory_moaPets: `Moas`,
|
||||||
inventory_kubrowPets: `Bestien`,
|
inventory_kubrowPets: `Bestien`,
|
||||||
inventory_evolutionProgress: `[UNTRANSLATED] Incarnon Evolution Progress`,
|
inventory_evolutionProgress: `Incarnon-Entwicklungsfortschritte`,
|
||||||
inventory_bulkAddSuits: `Fehlende Warframes hinzufügen`,
|
inventory_bulkAddSuits: `Fehlende Warframes hinzufügen`,
|
||||||
inventory_bulkAddWeapons: `Fehlende Waffen hinzufügen`,
|
inventory_bulkAddWeapons: `Fehlende Waffen hinzufügen`,
|
||||||
inventory_bulkAddSpaceSuits: `Fehlende Archwings hinzufügen`,
|
inventory_bulkAddSpaceSuits: `Fehlende Archwings hinzufügen`,
|
||||||
inventory_bulkAddSpaceWeapons: `Fehlende Archwing-Waffen hinzufügen`,
|
inventory_bulkAddSpaceWeapons: `Fehlende Archwing-Waffen hinzufügen`,
|
||||||
inventory_bulkAddSentinels: `Fehlende Wächter hinzufügen`,
|
inventory_bulkAddSentinels: `Fehlende Wächter hinzufügen`,
|
||||||
inventory_bulkAddSentinelWeapons: `Fehlende Wächter-Waffen hinzufügen`,
|
inventory_bulkAddSentinelWeapons: `Fehlende Wächter-Waffen hinzufügen`,
|
||||||
inventory_bulkAddEvolutionProgress: `[UNTRANSLATED] Add Missing Incarnon Evolution Progress`,
|
inventory_bulkAddEvolutionProgress: `Fehlende Incarnon-Entwicklungsfortschritte hinzufügen`,
|
||||||
inventory_bulkRankUpSuits: `Alle Warframes auf Max. Rang`,
|
inventory_bulkRankUpSuits: `Alle Warframes auf Max. Rang`,
|
||||||
inventory_bulkRankUpWeapons: `Alle Waffen auf Max. Rang`,
|
inventory_bulkRankUpWeapons: `Alle Waffen auf Max. Rang`,
|
||||||
inventory_bulkRankUpSpaceSuits: `Alle Archwings auf Max. Rang`,
|
inventory_bulkRankUpSpaceSuits: `Alle Archwings auf Max. Rang`,
|
||||||
inventory_bulkRankUpSpaceWeapons: `Alle Archwing-Waffen auf Max. Rang`,
|
inventory_bulkRankUpSpaceWeapons: `Alle Archwing-Waffen auf Max. Rang`,
|
||||||
inventory_bulkRankUpSentinels: `Alle Wächter auf Max. Rang`,
|
inventory_bulkRankUpSentinels: `Alle Wächter auf Max. Rang`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `Alle Wächter-Waffen auf Max. Rang`,
|
inventory_bulkRankUpSentinelWeapons: `Alle Wächter-Waffen auf Max. Rang`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `[UNTRANSLATED] Max Rank All Incarnon Evolution Progress`,
|
inventory_bulkRankUpEvolutionProgress: `Alle Incarnon-Entwicklungsfortschritte auf Max. Rang`,
|
||||||
|
|
||||||
quests_list: `Quests`,
|
quests_list: `Quests`,
|
||||||
quests_completeAll: `Alle Quests abschließen`,
|
quests_completeAll: `Alle Quests abschließen`,
|
||||||
@ -120,9 +120,9 @@ dict = {
|
|||||||
mods_fingerprintHelp: `Benötigst du Hilfe mit dem Fingerabdruck?`,
|
mods_fingerprintHelp: `Benötigst du Hilfe mit dem Fingerabdruck?`,
|
||||||
mods_rivens: `Rivens`,
|
mods_rivens: `Rivens`,
|
||||||
mods_mods: `Mods`,
|
mods_mods: `Mods`,
|
||||||
mods_addMissingUnrankedMods: `[UNTRANSLATED] Add Missing Unranked Mods`,
|
mods_addMissingUnrankedMods: `Fehlende Mods ohne Rang hinzufügen`,
|
||||||
mods_removeUnranked: `Mods ohne Rang entfernen`,
|
mods_removeUnranked: `Mods ohne Rang entfernen`,
|
||||||
mods_addMissingMaxRankMods: `[UNTRANSLATED] Add Missing Max Rank Mods`,
|
mods_addMissingMaxRankMods: `Fehlende Mods mit Max. Rang hinzufügen`,
|
||||||
cheats_administratorRequirement: `Du musst Administrator sein, um diese Funktion nutzen zu können. Um Administrator zu werden, füge <code>|DISPLAYNAME|</code> zu <code>administratorNames</code> in der config.json hinzu.`,
|
cheats_administratorRequirement: `Du musst Administrator sein, um diese Funktion nutzen zu können. Um Administrator zu werden, füge <code>|DISPLAYNAME|</code> zu <code>administratorNames</code> in der config.json hinzu.`,
|
||||||
cheats_server: `Server`,
|
cheats_server: `Server`,
|
||||||
cheats_skipTutorial: `Tutorial überspringen`,
|
cheats_skipTutorial: `Tutorial überspringen`,
|
||||||
@ -134,7 +134,7 @@ dict = {
|
|||||||
cheats_infiniteEndo: `Unendlich Endo`,
|
cheats_infiniteEndo: `Unendlich Endo`,
|
||||||
cheats_infiniteRegalAya: `Unendlich Reines Aya`,
|
cheats_infiniteRegalAya: `Unendlich Reines Aya`,
|
||||||
cheats_infiniteHelminthMaterials: `Unendlich Helminth-Materialien`,
|
cheats_infiniteHelminthMaterials: `Unendlich Helminth-Materialien`,
|
||||||
cheats_dontSubtractConsumables: `[UNTRANSLATED] Don't Subtract Consumables`,
|
cheats_dontSubtractConsumables: `Verbrauchsgegenstände (Ausrüstung) nicht verbrauchen`,
|
||||||
cheats_unlockAllShipFeatures: `Alle Schiffs-Funktionen freischalten`,
|
cheats_unlockAllShipFeatures: `Alle Schiffs-Funktionen freischalten`,
|
||||||
cheats_unlockAllShipDecorations: `Alle Schiffsdekorationen freischalten`,
|
cheats_unlockAllShipDecorations: `Alle Schiffsdekorationen freischalten`,
|
||||||
cheats_unlockAllFlavourItems: `Alle <abbr title=\"Animationssets, Glyphen, Farbpaletten usw.\">Sammlerstücke</abbr> freischalten`,
|
cheats_unlockAllFlavourItems: `Alle <abbr title=\"Animationssets, Glyphen, Farbpaletten usw.\">Sammlerstücke</abbr> freischalten`,
|
||||||
@ -154,7 +154,7 @@ dict = {
|
|||||||
cheats_noKimCooldowns: `Keine Wartezeit bei KIM`,
|
cheats_noKimCooldowns: `Keine Wartezeit bei KIM`,
|
||||||
cheats_instantResourceExtractorDrones: `Sofortige Ressourcen-Extraktor-Drohnen`,
|
cheats_instantResourceExtractorDrones: `Sofortige Ressourcen-Extraktor-Drohnen`,
|
||||||
cheats_noResourceExtractorDronesDamage: `Kein Schaden für Ressourcen-Extraktor-Drohnen`,
|
cheats_noResourceExtractorDronesDamage: `Kein Schaden für Ressourcen-Extraktor-Drohnen`,
|
||||||
cheats_skipClanKeyCrafting: `[UNTRANSLATED] Skip Clan Key Crafting`,
|
cheats_skipClanKeyCrafting: `Clan-Schlüsselherstellung überspringen`,
|
||||||
cheats_noDojoRoomBuildStage: `Kein Dojo-Raum-Bauvorgang`,
|
cheats_noDojoRoomBuildStage: `Kein Dojo-Raum-Bauvorgang`,
|
||||||
cheats_noDojoDecoBuildStage: `Kein Dojo-Deko-Bauvorgang`,
|
cheats_noDojoDecoBuildStage: `Kein Dojo-Deko-Bauvorgang`,
|
||||||
cheats_fastDojoRoomDestruction: `Schnelle Dojo-Raum-Zerstörung`,
|
cheats_fastDojoRoomDestruction: `Schnelle Dojo-Raum-Zerstörung`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user