forked from OpenWF/SpaceNinjaServer
Compare commits
17 Commits
f3e56480e5
...
267357871b
Author | SHA1 | Date | |
---|---|---|---|
267357871b | |||
cf5ed0442d | |||
de36e2ee8d | |||
ca1b6c31b6 | |||
d66c474bfc | |||
781f01520f | |||
ac37702468 | |||
75c011e3cb | |||
4d4f885c8e | |||
66d1a65e63 | |||
48eefd8db1 | |||
4a6a5ea9cc | |||
95c0ad7892 | |||
a90d3a5156 | |||
d0c9409a2d | |||
bbde7b2141 | |||
5271123090 |
@ -1,7 +1,6 @@
|
|||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
echo Updating SpaceNinjaServer...
|
echo Updating SpaceNinjaServer...
|
||||||
git config remote.origin.url https://openwf.io/SpaceNinjaServer.git
|
|
||||||
git fetch --prune
|
git fetch --prune
|
||||||
git stash
|
git stash
|
||||||
git reset --hard origin/main
|
git reset --hard origin/main
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"infiniteEndo": false,
|
"infiniteEndo": false,
|
||||||
"infiniteRegalAya": false,
|
"infiniteRegalAya": false,
|
||||||
"infiniteHelminthMaterials": false,
|
"infiniteHelminthMaterials": false,
|
||||||
|
"dontSubtractConsumables": false,
|
||||||
"unlockAllShipFeatures": false,
|
"unlockAllShipFeatures": false,
|
||||||
"unlockAllShipDecorations": false,
|
"unlockAllShipDecorations": false,
|
||||||
"unlockAllFlavourItems": false,
|
"unlockAllFlavourItems": false,
|
||||||
|
@ -62,14 +62,7 @@ export const crewShipIdentifySalvageController: RequestHandler = async (req, res
|
|||||||
} satisfies IInnateDamageFingerprint)
|
} satisfies IInnateDamageFingerprint)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
addEquipment(
|
addEquipment(inventory, "CrewShipSalvagedWeapons", payload.ItemType, defaultOverwrites, inventoryChanges);
|
||||||
inventory,
|
|
||||||
"CrewShipSalvagedWeapons",
|
|
||||||
payload.ItemType,
|
|
||||||
undefined,
|
|
||||||
inventoryChanges,
|
|
||||||
defaultOverwrites
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inventoryChanges.CrewShipRawSalvage = [
|
inventoryChanges.CrewShipRawSalvage = [
|
||||||
|
@ -104,13 +104,14 @@ export const focusController: RequestHandler = async (req, res) => {
|
|||||||
}
|
}
|
||||||
case FocusOperation.SentTrainingAmplifier: {
|
case FocusOperation.SentTrainingAmplifier: {
|
||||||
const request = JSON.parse(String(req.body)) as ISentTrainingAmplifierRequest;
|
const request = JSON.parse(String(req.body)) as ISentTrainingAmplifierRequest;
|
||||||
const parts: string[] = [
|
const inventory = await getInventory(accountId);
|
||||||
|
const inventoryChanges = addEquipment(inventory, "OperatorAmps", request.StartingWeaponType, {
|
||||||
|
ModularParts: [
|
||||||
"/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/SentAmpTrainingGrip",
|
"/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/SentAmpTrainingGrip",
|
||||||
"/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/SentAmpTrainingChassis",
|
"/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/SentAmpTrainingChassis",
|
||||||
"/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/SentAmpTrainingBarrel"
|
"/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/SentAmpTrainingBarrel"
|
||||||
];
|
]
|
||||||
const inventory = await getInventory(accountId);
|
});
|
||||||
const inventoryChanges = addEquipment(inventory, "OperatorAmps", request.StartingWeaponType, parts);
|
|
||||||
occupySlot(inventory, InventorySlot.AMPS, false);
|
occupySlot(inventory, InventorySlot.AMPS, false);
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
res.json((inventoryChanges.OperatorAmps as IEquipmentClient[])[0]);
|
res.json((inventoryChanges.OperatorAmps as IEquipmentClient[])[0]);
|
||||||
|
84
src/controllers/api/gardeningController.ts
Normal file
84
src/controllers/api/gardeningController.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { toMongoDate } from "@/src/helpers/inventoryHelpers";
|
||||||
|
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||||
|
import { addMiscItem, getInventory } from "@/src/services/inventoryService";
|
||||||
|
import { toStoreItem } from "@/src/services/itemDataService";
|
||||||
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
|
import { createGarden, getPersonalRooms } from "@/src/services/personalRoomsService";
|
||||||
|
import { IMongoDate } from "@/src/types/commonTypes";
|
||||||
|
import { IMissionReward } from "@/src/types/missionTypes";
|
||||||
|
import { IPersonalRoomsClient } from "@/src/types/personalRoomsTypes";
|
||||||
|
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||||
|
import { IGardeningClient } from "@/src/types/shipTypes";
|
||||||
|
import { RequestHandler } from "express";
|
||||||
|
import { dict_en, ExportResources } from "warframe-public-export-plus";
|
||||||
|
|
||||||
|
export const gardeningController: RequestHandler = async (req, res) => {
|
||||||
|
const data = getJSONfromString<IGardeningRequest>(String(req.body));
|
||||||
|
if (data.Mode != "HarvestAll") {
|
||||||
|
throw new Error(`unexpected gardening mode: ${data.Mode}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const accountId = await getAccountIdForRequest(req);
|
||||||
|
const [inventory, personalRooms] = await Promise.all([
|
||||||
|
getInventory(accountId, "MiscItems"),
|
||||||
|
getPersonalRooms(accountId, "Apartment")
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Harvest plants
|
||||||
|
const inventoryChanges: IInventoryChanges = {};
|
||||||
|
const rewards: Record<string, IMissionReward[][]> = {};
|
||||||
|
for (const planter of personalRooms.Apartment.Gardening.Planters) {
|
||||||
|
rewards[planter.Name] = [];
|
||||||
|
for (const plant of planter.Plants) {
|
||||||
|
const itemType =
|
||||||
|
"/Lotus/Types/Gameplay/Duviri/Resource/DuviriPlantItem" +
|
||||||
|
plant.PlantType.substring(plant.PlantType.length - 1);
|
||||||
|
const itemCount = Math.random() < 0.775 ? 2 : 4;
|
||||||
|
|
||||||
|
addMiscItem(inventory, itemType, itemCount, inventoryChanges);
|
||||||
|
|
||||||
|
rewards[planter.Name].push([
|
||||||
|
{
|
||||||
|
StoreItem: toStoreItem(itemType),
|
||||||
|
TypeName: itemType,
|
||||||
|
ItemCount: itemCount,
|
||||||
|
DailyCooldown: false,
|
||||||
|
Rarity: itemCount == 2 ? 0.7743589743589744 : 0.22564102564102564,
|
||||||
|
TweetText: `${itemCount}x ${dict_en[ExportResources[itemType].name]} (Resource)`,
|
||||||
|
ProductCategory: "MiscItems"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh garden
|
||||||
|
personalRooms.Apartment.Gardening = createGarden();
|
||||||
|
|
||||||
|
await Promise.all([inventory.save(), personalRooms.save()]);
|
||||||
|
|
||||||
|
const planter = personalRooms.Apartment.Gardening.Planters[personalRooms.Apartment.Gardening.Planters.length - 1];
|
||||||
|
const plant = planter.Plants[planter.Plants.length - 1];
|
||||||
|
res.json({
|
||||||
|
GardenTagName: planter.Name,
|
||||||
|
PlantType: plant.PlantType,
|
||||||
|
PlotIndex: plant.PlotIndex,
|
||||||
|
EndTime: toMongoDate(plant.EndTime),
|
||||||
|
InventoryChanges: inventoryChanges,
|
||||||
|
Gardening: personalRooms.toJSON<IPersonalRoomsClient>().Apartment.Gardening,
|
||||||
|
Rewards: rewards
|
||||||
|
} satisfies IGardeningResponse);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IGardeningRequest {
|
||||||
|
Mode: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IGardeningResponse {
|
||||||
|
GardenTagName: string;
|
||||||
|
PlantType: string;
|
||||||
|
PlotIndex: number;
|
||||||
|
EndTime: IMongoDate;
|
||||||
|
InventoryChanges: IInventoryChanges;
|
||||||
|
Gardening: IGardeningClient;
|
||||||
|
Rewards: Record<string, IMissionReward[][]>;
|
||||||
|
}
|
@ -2,17 +2,24 @@ import { RequestHandler } from "express";
|
|||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
import allShipFeatures from "@/static/fixed_responses/allShipFeatures.json";
|
import allShipFeatures from "@/static/fixed_responses/allShipFeatures.json";
|
||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
import { getPersonalRooms } from "@/src/services/personalRoomsService";
|
import { createGarden, getPersonalRooms } from "@/src/services/personalRoomsService";
|
||||||
import { getShip } from "@/src/services/shipService";
|
import { getShip } from "@/src/services/shipService";
|
||||||
import { toOid } from "@/src/helpers/inventoryHelpers";
|
import { toOid } from "@/src/helpers/inventoryHelpers";
|
||||||
import { IGetShipResponse } from "@/src/types/shipTypes";
|
import { IGetShipResponse } from "@/src/types/shipTypes";
|
||||||
import { IPersonalRooms } from "@/src/types/personalRoomsTypes";
|
import { IPersonalRoomsClient } from "@/src/types/personalRoomsTypes";
|
||||||
import { getLoadout } from "@/src/services/loadoutService";
|
import { getLoadout } from "@/src/services/loadoutService";
|
||||||
|
|
||||||
export const getShipController: RequestHandler = async (req, res) => {
|
export const getShipController: RequestHandler = async (req, res) => {
|
||||||
const accountId = await getAccountIdForRequest(req);
|
const accountId = await getAccountIdForRequest(req);
|
||||||
const personalRoomsDb = await getPersonalRooms(accountId);
|
const personalRoomsDb = await getPersonalRooms(accountId);
|
||||||
const personalRooms = personalRoomsDb.toJSON<IPersonalRooms>();
|
|
||||||
|
// Setup gardening if it's missing. Maybe should be done as part of some quest completion in the future.
|
||||||
|
if (personalRoomsDb.Apartment.Gardening.Planters.length == 0) {
|
||||||
|
personalRoomsDb.Apartment.Gardening = createGarden();
|
||||||
|
await personalRoomsDb.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
const personalRooms = personalRoomsDb.toJSON<IPersonalRoomsClient>();
|
||||||
const loadout = await getLoadout(accountId);
|
const loadout = await getLoadout(accountId);
|
||||||
const ship = await getShip(personalRoomsDb.activeShipId, "ShipAttachments SkinFlavourItem");
|
const ship = await getShip(personalRoomsDb.activeShipId, "ShipAttachments SkinFlavourItem");
|
||||||
|
|
||||||
|
@ -441,16 +441,9 @@ const finishComponentRepair = (
|
|||||||
const inventoryChanges = {
|
const inventoryChanges = {
|
||||||
...(category == "CrewShipWeaponSkins"
|
...(category == "CrewShipWeaponSkins"
|
||||||
? addCrewShipWeaponSkin(inventory, salvageItem.ItemType, salvageItem.UpgradeFingerprint)
|
? addCrewShipWeaponSkin(inventory, salvageItem.ItemType, salvageItem.UpgradeFingerprint)
|
||||||
: addEquipment(
|
: addEquipment(inventory, category, salvageItem.ItemType, {
|
||||||
inventory,
|
|
||||||
category,
|
|
||||||
salvageItem.ItemType,
|
|
||||||
undefined,
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
UpgradeFingerprint: salvageItem.UpgradeFingerprint
|
UpgradeFingerprint: salvageItem.UpgradeFingerprint
|
||||||
}
|
})),
|
||||||
)),
|
|
||||||
...occupySlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS, false)
|
...occupySlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,7 +36,9 @@ export const modularWeaponCraftingController: RequestHandler = async (req, res)
|
|||||||
const inventory = await getInventory(accountId);
|
const inventory = await getInventory(accountId);
|
||||||
|
|
||||||
let defaultUpgrades: IDefaultUpgrade[] | undefined;
|
let defaultUpgrades: IDefaultUpgrade[] | undefined;
|
||||||
const defaultOverwrites: Partial<IEquipmentDatabase> = {};
|
const defaultOverwrites: Partial<IEquipmentDatabase> = {
|
||||||
|
ModularParts: data.Parts
|
||||||
|
};
|
||||||
const inventoryChanges: IInventoryChanges = {};
|
const inventoryChanges: IInventoryChanges = {};
|
||||||
if (category == "KubrowPets") {
|
if (category == "KubrowPets") {
|
||||||
const traits = {
|
const traits = {
|
||||||
@ -151,7 +153,7 @@ export const modularWeaponCraftingController: RequestHandler = async (req, res)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
defaultOverwrites.Configs = applyDefaultUpgrades(inventory, defaultUpgrades);
|
defaultOverwrites.Configs = applyDefaultUpgrades(inventory, defaultUpgrades);
|
||||||
addEquipment(inventory, category, data.WeaponType, data.Parts, inventoryChanges, defaultOverwrites);
|
addEquipment(inventory, category, data.WeaponType, defaultOverwrites, inventoryChanges);
|
||||||
combineInventoryChanges(
|
combineInventoryChanges(
|
||||||
inventoryChanges,
|
inventoryChanges,
|
||||||
occupySlot(inventory, productCategoryToInventoryBin(category)!, !!data.isWebUi)
|
occupySlot(inventory, productCategoryToInventoryBin(category)!, !!data.isWebUi)
|
||||||
|
@ -21,7 +21,11 @@ import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
|||||||
export const modularWeaponSaleController: RequestHandler = async (req, res) => {
|
export const modularWeaponSaleController: RequestHandler = async (req, res) => {
|
||||||
const partTypeToParts: Record<string, string[]> = {};
|
const partTypeToParts: Record<string, string[]> = {};
|
||||||
for (const [uniqueName, data] of Object.entries(ExportWeapons)) {
|
for (const [uniqueName, data] of Object.entries(ExportWeapons)) {
|
||||||
if (data.partType && data.premiumPrice) {
|
if (
|
||||||
|
data.partType &&
|
||||||
|
data.premiumPrice &&
|
||||||
|
!data.excludeFromCodex // exclude pvp variants
|
||||||
|
) {
|
||||||
partTypeToParts[data.partType] ??= [];
|
partTypeToParts[data.partType] ??= [];
|
||||||
partTypeToParts[data.partType].push(uniqueName);
|
partTypeToParts[data.partType].push(uniqueName);
|
||||||
}
|
}
|
||||||
@ -41,24 +45,18 @@ export const modularWeaponSaleController: RequestHandler = async (req, res) => {
|
|||||||
const defaultUpgrades = getDefaultUpgrades(weaponInfo.ModularParts);
|
const defaultUpgrades = getDefaultUpgrades(weaponInfo.ModularParts);
|
||||||
const configs = applyDefaultUpgrades(inventory, defaultUpgrades);
|
const configs = applyDefaultUpgrades(inventory, defaultUpgrades);
|
||||||
const inventoryChanges: IInventoryChanges = {
|
const inventoryChanges: IInventoryChanges = {
|
||||||
...addEquipment(
|
...addEquipment(inventory, category, weaponInfo.ItemType, {
|
||||||
inventory,
|
|
||||||
category,
|
|
||||||
weaponInfo.ItemType,
|
|
||||||
weaponInfo.ModularParts,
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
Features: EquipmentFeatures.DOUBLE_CAPACITY | EquipmentFeatures.GILDED,
|
Features: EquipmentFeatures.DOUBLE_CAPACITY | EquipmentFeatures.GILDED,
|
||||||
ItemName: payload.ItemName,
|
ItemName: payload.ItemName,
|
||||||
Configs: configs,
|
Configs: configs,
|
||||||
|
ModularParts: weaponInfo.ModularParts,
|
||||||
Polarity: [
|
Polarity: [
|
||||||
{
|
{
|
||||||
Slot: payload.PolarizeSlot,
|
Slot: payload.PolarizeSlot,
|
||||||
Value: payload.PolarizeValue
|
Value: payload.PolarizeValue
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}),
|
||||||
),
|
|
||||||
...occupySlot(inventory, productCategoryToInventoryBin(category)!, true),
|
...occupySlot(inventory, productCategoryToInventoryBin(category)!, true),
|
||||||
...updateCurrency(inventory, weaponInfo.PremiumPrice, true)
|
...updateCurrency(inventory, weaponInfo.PremiumPrice, true)
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,6 @@ import { addEmailItem, getInventory, updateCurrency } from "@/src/services/inven
|
|||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
import { ICompletedDialogue, IDialogueDatabase } from "@/src/types/inventoryTypes/inventoryTypes";
|
import { ICompletedDialogue, IDialogueDatabase } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||||
import { logger } from "@/src/utils/logger";
|
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
|
|
||||||
export const saveDialogueController: RequestHandler = async (req, res) => {
|
export const saveDialogueController: RequestHandler = async (req, res) => {
|
||||||
@ -27,7 +26,6 @@ export const saveDialogueController: RequestHandler = async (req, res) => {
|
|||||||
const dialogue = getDialogue(inventory, request.DialogueName);
|
const dialogue = getDialogue(inventory, request.DialogueName);
|
||||||
dialogue.Rank = request.Rank;
|
dialogue.Rank = request.Rank;
|
||||||
dialogue.Chemistry = request.Chemistry;
|
dialogue.Chemistry = request.Chemistry;
|
||||||
if (request.Data) {
|
|
||||||
dialogue.QueuedDialogues = request.QueuedDialogues;
|
dialogue.QueuedDialogues = request.QueuedDialogues;
|
||||||
for (const bool of request.Booleans) {
|
for (const bool of request.Booleans) {
|
||||||
dialogue.Booleans.push(bool);
|
dialogue.Booleans.push(bool);
|
||||||
@ -45,8 +43,6 @@ export const saveDialogueController: RequestHandler = async (req, res) => {
|
|||||||
dialogue.Booleans.splice(index, 1);
|
dialogue.Booleans.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dialogue.Completed.push(request.Data);
|
|
||||||
dialogue.AvailableDate = new Date(tomorrowAt0Utc);
|
|
||||||
for (const info of request.OtherDialogueInfos) {
|
for (const info of request.OtherDialogueInfos) {
|
||||||
const otherDialogue = getDialogue(inventory, info.Dialogue);
|
const otherDialogue = getDialogue(inventory, info.Dialogue);
|
||||||
if (info.Tag != "") {
|
if (info.Tag != "") {
|
||||||
@ -54,6 +50,9 @@ export const saveDialogueController: RequestHandler = async (req, res) => {
|
|||||||
}
|
}
|
||||||
otherDialogue.Chemistry += info.Value; // unsure
|
otherDialogue.Chemistry += info.Value; // unsure
|
||||||
}
|
}
|
||||||
|
if (request.Data) {
|
||||||
|
dialogue.Completed.push(request.Data);
|
||||||
|
dialogue.AvailableDate = new Date(tomorrowAt0Utc);
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
res.json({
|
res.json({
|
||||||
InventoryChanges: inventoryChanges,
|
InventoryChanges: inventoryChanges,
|
||||||
@ -74,7 +73,7 @@ export const saveDialogueController: RequestHandler = async (req, res) => {
|
|||||||
AvailableGiftDate: { $date: { $numberLong: tomorrowAt0Utc.toString() } }
|
AvailableGiftDate: { $date: { $numberLong: tomorrowAt0Utc.toString() } }
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
logger.error(`saveDialogue request not fully handled: ${String(req.body)}`);
|
res.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
44
src/controllers/custom/addMissingMaxRankModsController.ts
Normal file
44
src/controllers/custom/addMissingMaxRankModsController.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { getInventory } from "@/src/services/inventoryService";
|
||||||
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
|
import { RequestHandler } from "express";
|
||||||
|
import { ExportArcanes, ExportUpgrades } from "warframe-public-export-plus";
|
||||||
|
|
||||||
|
export const addMissingMaxRankModsController: RequestHandler = async (req, res) => {
|
||||||
|
const accountId = await getAccountIdForRequest(req);
|
||||||
|
const inventory = await getInventory(accountId, "Upgrades");
|
||||||
|
|
||||||
|
const maxOwnedRanks: Record<string, number> = {};
|
||||||
|
for (const upgrade of inventory.Upgrades) {
|
||||||
|
const fingerprint = JSON.parse(upgrade.UpgradeFingerprint ?? "{}") as { lvl?: number };
|
||||||
|
if (fingerprint.lvl) {
|
||||||
|
maxOwnedRanks[upgrade.ItemType] ??= 0;
|
||||||
|
if (fingerprint.lvl > maxOwnedRanks[upgrade.ItemType]) {
|
||||||
|
maxOwnedRanks[upgrade.ItemType] = fingerprint.lvl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [uniqueName, data] of Object.entries(ExportUpgrades)) {
|
||||||
|
if (data.fusionLimit != 0 && data.type != "PARAZON" && maxOwnedRanks[uniqueName] != data.fusionLimit) {
|
||||||
|
inventory.Upgrades.push({
|
||||||
|
ItemType: uniqueName,
|
||||||
|
UpgradeFingerprint: JSON.stringify({ lvl: data.fusionLimit })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [uniqueName, data] of Object.entries(ExportArcanes)) {
|
||||||
|
if (
|
||||||
|
data.name != "/Lotus/Language/Items/GenericCosmeticEnhancerName" &&
|
||||||
|
maxOwnedRanks[uniqueName] != data.fusionLimit
|
||||||
|
) {
|
||||||
|
inventory.Upgrades.push({
|
||||||
|
ItemType: uniqueName,
|
||||||
|
UpgradeFingerprint: JSON.stringify({ lvl: data.fusionLimit })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await inventory.save();
|
||||||
|
res.end();
|
||||||
|
};
|
@ -96,7 +96,8 @@ import {
|
|||||||
IInvasionProgressDatabase,
|
IInvasionProgressDatabase,
|
||||||
IInvasionProgressClient,
|
IInvasionProgressClient,
|
||||||
IAccolades,
|
IAccolades,
|
||||||
IHubNpcCustomization
|
IHubNpcCustomization,
|
||||||
|
ILotusCustomization
|
||||||
} from "../../types/inventoryTypes/inventoryTypes";
|
} from "../../types/inventoryTypes/inventoryTypes";
|
||||||
import { IOid } from "../../types/commonTypes";
|
import { IOid } from "../../types/commonTypes";
|
||||||
import {
|
import {
|
||||||
@ -780,6 +781,10 @@ const loreFragmentScansSchema = new Schema<ILoreFragmentScan>(
|
|||||||
{ _id: false }
|
{ _id: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const lotusCustomizationSchema = new Schema<ILotusCustomization>().add(ItemConfigSchema).add({
|
||||||
|
Persona: String
|
||||||
|
});
|
||||||
|
|
||||||
const evolutionProgressSchema = new Schema<IEvolutionProgress>(
|
const evolutionProgressSchema = new Schema<IEvolutionProgress>(
|
||||||
{
|
{
|
||||||
Progress: Number,
|
Progress: Number,
|
||||||
@ -1628,7 +1633,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
|
|
||||||
//Purchase this new permanent skin from the Lotus customization options in Personal Quarters located in your Orbiter.
|
//Purchase this new permanent skin from the Lotus customization options in Personal Quarters located in your Orbiter.
|
||||||
//https://warframe.fandom.com/wiki/Lotus#The_New_War
|
//https://warframe.fandom.com/wiki/Lotus#The_New_War
|
||||||
LotusCustomization: Schema.Types.Mixed,
|
LotusCustomization: { type: lotusCustomizationSchema, default: undefined },
|
||||||
|
|
||||||
//Progress+Rank+ItemType(ZarimanPumpShotgun)
|
//Progress+Rank+ItemType(ZarimanPumpShotgun)
|
||||||
//https://warframe.fandom.com/wiki/Incarnon
|
//https://warframe.fandom.com/wiki/Incarnon
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
import { toOid } from "@/src/helpers/inventoryHelpers";
|
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
|
||||||
import { colorSchema } from "@/src/models/inventoryModels/inventoryModel";
|
import { colorSchema } from "@/src/models/inventoryModels/inventoryModel";
|
||||||
import { IOrbiter, IPersonalRoomsDatabase, PersonalRoomsModelType } from "@/src/types/personalRoomsTypes";
|
import { IOrbiter, IPersonalRoomsDatabase, PersonalRoomsModelType } from "@/src/types/personalRoomsTypes";
|
||||||
import {
|
import {
|
||||||
IFavouriteLoadoutDatabase,
|
IFavouriteLoadoutDatabase,
|
||||||
IGardening,
|
IGardeningDatabase,
|
||||||
IPlacedDecosDatabase,
|
IPlacedDecosDatabase,
|
||||||
IPictureFrameInfo,
|
IPictureFrameInfo,
|
||||||
IRoom,
|
IRoom,
|
||||||
ITailorShopDatabase,
|
ITailorShopDatabase,
|
||||||
IApartmentDatabase
|
IApartmentDatabase,
|
||||||
|
IPlanterDatabase,
|
||||||
|
IPlantDatabase,
|
||||||
|
IPlantClient
|
||||||
} from "@/src/types/shipTypes";
|
} from "@/src/types/shipTypes";
|
||||||
import { Schema, model } from "mongoose";
|
import { Schema, model } from "mongoose";
|
||||||
|
|
||||||
@ -77,15 +80,45 @@ favouriteLoadoutSchema.set("toJSON", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const gardeningSchema = new Schema<IGardening>({
|
const plantSchema = new Schema<IPlantDatabase>(
|
||||||
Planters: [Schema.Types.Mixed] //TODO: add when implementing gardening
|
{
|
||||||
|
PlantType: String,
|
||||||
|
EndTime: Date,
|
||||||
|
PlotIndex: Number
|
||||||
|
},
|
||||||
|
{ _id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
plantSchema.set("toJSON", {
|
||||||
|
virtuals: true,
|
||||||
|
transform(_doc, obj) {
|
||||||
|
const client = obj as IPlantClient;
|
||||||
|
const db = obj as IPlantDatabase;
|
||||||
|
|
||||||
|
client.EndTime = toMongoDate(db.EndTime);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const planterSchema = new Schema<IPlanterDatabase>(
|
||||||
|
{
|
||||||
|
Name: { type: String, required: true },
|
||||||
|
Plants: { type: [plantSchema], default: [] }
|
||||||
|
},
|
||||||
|
{ _id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
const gardeningSchema = new Schema<IGardeningDatabase>(
|
||||||
|
{
|
||||||
|
Planters: { type: [planterSchema], default: [] }
|
||||||
|
},
|
||||||
|
{ _id: false }
|
||||||
|
);
|
||||||
|
|
||||||
const apartmentSchema = new Schema<IApartmentDatabase>(
|
const apartmentSchema = new Schema<IApartmentDatabase>(
|
||||||
{
|
{
|
||||||
Rooms: [roomSchema],
|
Rooms: [roomSchema],
|
||||||
FavouriteLoadouts: [favouriteLoadoutSchema],
|
FavouriteLoadouts: [favouriteLoadoutSchema],
|
||||||
Gardening: gardeningSchema // TODO: ensure this is correct
|
Gardening: gardeningSchema
|
||||||
},
|
},
|
||||||
{ _id: false }
|
{ _id: false }
|
||||||
);
|
);
|
||||||
@ -98,7 +131,9 @@ const apartmentDefault: IApartmentDatabase = {
|
|||||||
{ Name: "DuviriHallway", MaxCapacity: 1600 }
|
{ Name: "DuviriHallway", MaxCapacity: 1600 }
|
||||||
],
|
],
|
||||||
FavouriteLoadouts: [],
|
FavouriteLoadouts: [],
|
||||||
Gardening: {}
|
Gardening: {
|
||||||
|
Planters: []
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const orbiterSchema = new Schema<IOrbiter>(
|
const orbiterSchema = new Schema<IOrbiter>(
|
||||||
|
@ -48,6 +48,7 @@ import { findSessionsController } from "@/src/controllers/api/findSessionsContro
|
|||||||
import { fishmongerController } from "@/src/controllers/api/fishmongerController";
|
import { fishmongerController } from "@/src/controllers/api/fishmongerController";
|
||||||
import { focusController } from "@/src/controllers/api/focusController";
|
import { focusController } from "@/src/controllers/api/focusController";
|
||||||
import { fusionTreasuresController } from "@/src/controllers/api/fusionTreasuresController";
|
import { fusionTreasuresController } from "@/src/controllers/api/fusionTreasuresController";
|
||||||
|
import { gardeningController } from "@/src/controllers/api/gardeningController";
|
||||||
import { genericUpdateController } from "@/src/controllers/api/genericUpdateController";
|
import { genericUpdateController } from "@/src/controllers/api/genericUpdateController";
|
||||||
import { getAllianceController } from "@/src/controllers/api/getAllianceController";
|
import { getAllianceController } from "@/src/controllers/api/getAllianceController";
|
||||||
import { getDailyDealStockLevelsController } from "@/src/controllers/api/getDailyDealStockLevelsController";
|
import { getDailyDealStockLevelsController } from "@/src/controllers/api/getDailyDealStockLevelsController";
|
||||||
@ -240,6 +241,7 @@ apiRouter.post("/findSessions.php", findSessionsController);
|
|||||||
apiRouter.post("/fishmonger.php", fishmongerController);
|
apiRouter.post("/fishmonger.php", fishmongerController);
|
||||||
apiRouter.post("/focus.php", focusController);
|
apiRouter.post("/focus.php", focusController);
|
||||||
apiRouter.post("/fusionTreasures.php", fusionTreasuresController);
|
apiRouter.post("/fusionTreasures.php", fusionTreasuresController);
|
||||||
|
apiRouter.post("/gardening.php", gardeningController);
|
||||||
apiRouter.post("/genericUpdate.php", genericUpdateController);
|
apiRouter.post("/genericUpdate.php", genericUpdateController);
|
||||||
apiRouter.post("/getAlliance.php", getAllianceController);
|
apiRouter.post("/getAlliance.php", getAllianceController);
|
||||||
apiRouter.post("/getFriends.php", getFriendsController);
|
apiRouter.post("/getFriends.php", getFriendsController);
|
||||||
|
@ -10,6 +10,7 @@ import { getAccountInfoController } from "@/src/controllers/custom/getAccountInf
|
|||||||
import { renameAccountController } from "@/src/controllers/custom/renameAccountController";
|
import { renameAccountController } from "@/src/controllers/custom/renameAccountController";
|
||||||
import { ircDroppedController } from "@/src/controllers/custom/ircDroppedController";
|
import { ircDroppedController } from "@/src/controllers/custom/ircDroppedController";
|
||||||
import { unlockAllIntrinsicsController } from "@/src/controllers/custom/unlockAllIntrinsicsController";
|
import { unlockAllIntrinsicsController } from "@/src/controllers/custom/unlockAllIntrinsicsController";
|
||||||
|
import { addMissingMaxRankModsController } from "@/src/controllers/custom/addMissingMaxRankModsController";
|
||||||
|
|
||||||
import { createAccountController } from "@/src/controllers/custom/createAccountController";
|
import { createAccountController } from "@/src/controllers/custom/createAccountController";
|
||||||
import { createMessageController } from "@/src/controllers/custom/createMessageController";
|
import { createMessageController } from "@/src/controllers/custom/createMessageController";
|
||||||
@ -35,6 +36,7 @@ customRouter.get("/getAccountInfo", getAccountInfoController);
|
|||||||
customRouter.get("/renameAccount", renameAccountController);
|
customRouter.get("/renameAccount", renameAccountController);
|
||||||
customRouter.get("/ircDropped", ircDroppedController);
|
customRouter.get("/ircDropped", ircDroppedController);
|
||||||
customRouter.get("/unlockAllIntrinsics", unlockAllIntrinsicsController);
|
customRouter.get("/unlockAllIntrinsics", unlockAllIntrinsicsController);
|
||||||
|
customRouter.get("/addMissingMaxRankMods", addMissingMaxRankModsController);
|
||||||
|
|
||||||
customRouter.post("/createAccount", createAccountController);
|
customRouter.post("/createAccount", createAccountController);
|
||||||
customRouter.post("/createMessage", createMessageController);
|
customRouter.post("/createMessage", createMessageController);
|
||||||
|
@ -24,6 +24,7 @@ interface IConfig {
|
|||||||
infiniteEndo?: boolean;
|
infiniteEndo?: boolean;
|
||||||
infiniteRegalAya?: boolean;
|
infiniteRegalAya?: boolean;
|
||||||
infiniteHelminthMaterials?: boolean;
|
infiniteHelminthMaterials?: boolean;
|
||||||
|
dontSubtractConsumables?: boolean;
|
||||||
unlockAllShipFeatures?: boolean;
|
unlockAllShipFeatures?: boolean;
|
||||||
unlockAllShipDecorations?: boolean;
|
unlockAllShipDecorations?: boolean;
|
||||||
unlockAllFlavourItems?: boolean;
|
unlockAllFlavourItems?: boolean;
|
||||||
|
@ -154,23 +154,22 @@ export const addStartingGear = async (
|
|||||||
|
|
||||||
//TODO: properly merge weapon bin changes it is currently static here
|
//TODO: properly merge weapon bin changes it is currently static here
|
||||||
const inventoryChanges: IInventoryChanges = {};
|
const inventoryChanges: IInventoryChanges = {};
|
||||||
addEquipment(inventory, "LongGuns", LongGuns[0].ItemType, undefined, inventoryChanges);
|
addEquipment(inventory, "LongGuns", LongGuns[0].ItemType, { IsNew: false }, inventoryChanges);
|
||||||
addEquipment(inventory, "Pistols", Pistols[0].ItemType, undefined, inventoryChanges);
|
addEquipment(inventory, "Pistols", Pistols[0].ItemType, { IsNew: false }, inventoryChanges);
|
||||||
addEquipment(inventory, "Melee", Melee[0].ItemType, undefined, inventoryChanges);
|
addEquipment(inventory, "Melee", Melee[0].ItemType, { IsNew: false }, inventoryChanges);
|
||||||
await addPowerSuit(inventory, Suits[0].ItemType, inventoryChanges);
|
await addPowerSuit(inventory, Suits[0].ItemType, { IsNew: false }, inventoryChanges);
|
||||||
addEquipment(
|
addEquipment(
|
||||||
inventory,
|
inventory,
|
||||||
"DataKnives",
|
"DataKnives",
|
||||||
"/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon",
|
"/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon",
|
||||||
undefined,
|
{ XP: 450_000, IsNew: false },
|
||||||
inventoryChanges,
|
inventoryChanges
|
||||||
{ XP: 450_000 }
|
|
||||||
);
|
);
|
||||||
addEquipment(
|
addEquipment(
|
||||||
inventory,
|
inventory,
|
||||||
"Scoops",
|
"Scoops",
|
||||||
"/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest",
|
"/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest",
|
||||||
undefined,
|
{ IsNew: false },
|
||||||
inventoryChanges
|
inventoryChanges
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -213,6 +212,15 @@ export const combineInventoryChanges = (InventoryChanges: IInventoryChanges, del
|
|||||||
for (const key in delta) {
|
for (const key in delta) {
|
||||||
if (!(key in InventoryChanges)) {
|
if (!(key in InventoryChanges)) {
|
||||||
InventoryChanges[key] = delta[key];
|
InventoryChanges[key] = delta[key];
|
||||||
|
} else if (key == "MiscItems") {
|
||||||
|
for (const deltaItem of delta[key]!) {
|
||||||
|
const existing = InventoryChanges[key]!.find(x => x.ItemType == deltaItem.ItemType);
|
||||||
|
if (existing) {
|
||||||
|
existing.ItemCount += deltaItem.ItemCount;
|
||||||
|
} else {
|
||||||
|
InventoryChanges[key]!.push(deltaItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (Array.isArray(delta[key])) {
|
} else if (Array.isArray(delta[key])) {
|
||||||
const left = InventoryChanges[key] as object[];
|
const left = InventoryChanges[key] as object[];
|
||||||
const right: object[] = delta[key];
|
const right: object[] = delta[key];
|
||||||
@ -522,14 +530,7 @@ export const addItem = async (
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const inventoryChanges = addEquipment(
|
const inventoryChanges = addEquipment(inventory, weapon.productCategory, typeName, defaultOverwrites);
|
||||||
inventory,
|
|
||||||
weapon.productCategory,
|
|
||||||
typeName,
|
|
||||||
[],
|
|
||||||
{},
|
|
||||||
defaultOverwrites
|
|
||||||
);
|
|
||||||
if (weapon.additionalItems) {
|
if (weapon.additionalItems) {
|
||||||
for (const item of weapon.additionalItems) {
|
for (const item of weapon.additionalItems) {
|
||||||
combineInventoryChanges(inventoryChanges, await addItem(inventory, item, 1));
|
combineInventoryChanges(inventoryChanges, await addItem(inventory, item, 1));
|
||||||
@ -630,12 +631,9 @@ export const addItem = async (
|
|||||||
switch (typeName.substr(1).split("/")[2]) {
|
switch (typeName.substr(1).split("/")[2]) {
|
||||||
default: {
|
default: {
|
||||||
return {
|
return {
|
||||||
...(await addPowerSuit(
|
...(await addPowerSuit(inventory, typeName, {
|
||||||
inventory,
|
Features: premiumPurchase ? EquipmentFeatures.DOUBLE_CAPACITY : undefined
|
||||||
typeName,
|
})),
|
||||||
{},
|
|
||||||
premiumPurchase ? EquipmentFeatures.DOUBLE_CAPACITY : undefined
|
|
||||||
)),
|
|
||||||
...occupySlot(inventory, InventorySlot.SUITS, premiumPurchase)
|
...occupySlot(inventory, InventorySlot.SUITS, premiumPurchase)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -855,8 +853,8 @@ const addSentinelWeapon = (
|
|||||||
export const addPowerSuit = async (
|
export const addPowerSuit = async (
|
||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
powersuitName: string,
|
powersuitName: string,
|
||||||
inventoryChanges: IInventoryChanges = {},
|
defaultOverwrites?: Partial<IEquipmentDatabase>,
|
||||||
features?: number
|
inventoryChanges: IInventoryChanges = {}
|
||||||
): Promise<IInventoryChanges> => {
|
): Promise<IInventoryChanges> => {
|
||||||
const powersuit = ExportWarframes[powersuitName] as IPowersuit | undefined;
|
const powersuit = ExportWarframes[powersuitName] as IPowersuit | undefined;
|
||||||
const exalted = powersuit?.exalted ?? [];
|
const exalted = powersuit?.exalted ?? [];
|
||||||
@ -870,15 +868,20 @@ export const addPowerSuit = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const suitIndex =
|
const suit: Omit<IEquipmentDatabase, "_id"> = Object.assign(
|
||||||
inventory.Suits.push({
|
{
|
||||||
ItemType: powersuitName,
|
ItemType: powersuitName,
|
||||||
Configs: [],
|
Configs: [],
|
||||||
UpgradeVer: 101,
|
UpgradeVer: 101,
|
||||||
XP: 0,
|
XP: 0,
|
||||||
Features: features,
|
|
||||||
IsNew: true
|
IsNew: true
|
||||||
}) - 1;
|
},
|
||||||
|
defaultOverwrites
|
||||||
|
);
|
||||||
|
if (!suit.IsNew) {
|
||||||
|
suit.IsNew = undefined;
|
||||||
|
}
|
||||||
|
const suitIndex = inventory.Suits.push(suit) - 1;
|
||||||
inventoryChanges.Suits ??= [];
|
inventoryChanges.Suits ??= [];
|
||||||
inventoryChanges.Suits.push(inventory.Suits[suitIndex].toJSON<IEquipmentClient>());
|
inventoryChanges.Suits.push(inventory.Suits[suitIndex].toJSON<IEquipmentClient>());
|
||||||
return inventoryChanges;
|
return inventoryChanges;
|
||||||
@ -1199,20 +1202,21 @@ export const addEquipment = (
|
|||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
category: TEquipmentKey,
|
category: TEquipmentKey,
|
||||||
type: string,
|
type: string,
|
||||||
modularParts?: string[],
|
defaultOverwrites?: Partial<IEquipmentDatabase>,
|
||||||
inventoryChanges: IInventoryChanges = {},
|
inventoryChanges: IInventoryChanges = {}
|
||||||
defaultOverwrites?: Partial<IEquipmentDatabase>
|
|
||||||
): IInventoryChanges => {
|
): IInventoryChanges => {
|
||||||
const equipment = Object.assign(
|
const equipment: Omit<IEquipmentDatabase, "_id"> = Object.assign(
|
||||||
{
|
{
|
||||||
ItemType: type,
|
ItemType: type,
|
||||||
Configs: [],
|
Configs: [],
|
||||||
XP: 0,
|
XP: 0,
|
||||||
ModularParts: modularParts,
|
IsNew: category != "CrewShipWeapons" && category != "CrewShipSalvagedWeapons"
|
||||||
IsNew: category != "CrewShipWeapons" && category != "CrewShipSalvagedWeapons" ? true : undefined
|
|
||||||
},
|
},
|
||||||
defaultOverwrites
|
defaultOverwrites
|
||||||
);
|
);
|
||||||
|
if (!equipment.IsNew) {
|
||||||
|
equipment.IsNew = undefined;
|
||||||
|
}
|
||||||
const index = inventory[category].push(equipment) - 1;
|
const index = inventory[category].push(equipment) - 1;
|
||||||
|
|
||||||
inventoryChanges[category] ??= [];
|
inventoryChanges[category] ??= [];
|
||||||
@ -1468,6 +1472,22 @@ export const addGearExpByCategory = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const addMiscItem = (
|
||||||
|
inventory: TInventoryDatabaseDocument,
|
||||||
|
type: string,
|
||||||
|
count: number,
|
||||||
|
inventoryChanges: IInventoryChanges
|
||||||
|
): void => {
|
||||||
|
const miscItemChanges: IMiscItem[] = [
|
||||||
|
{
|
||||||
|
ItemType: type,
|
||||||
|
ItemCount: count
|
||||||
|
}
|
||||||
|
];
|
||||||
|
addMiscItems(inventory, miscItemChanges);
|
||||||
|
combineInventoryChanges(inventoryChanges, { MiscItems: miscItemChanges });
|
||||||
|
};
|
||||||
|
|
||||||
export const addMiscItems = (inventory: TInventoryDatabaseDocument, itemsArray: IMiscItem[]): void => {
|
export const addMiscItems = (inventory: TInventoryDatabaseDocument, itemsArray: IMiscItem[]): void => {
|
||||||
const { MiscItems } = inventory;
|
const { MiscItems } = inventory;
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ import {
|
|||||||
addMods,
|
addMods,
|
||||||
addRecipes,
|
addRecipes,
|
||||||
addShipDecorations,
|
addShipDecorations,
|
||||||
|
addSkin,
|
||||||
addStanding,
|
addStanding,
|
||||||
combineInventoryChanges,
|
combineInventoryChanges,
|
||||||
generateRewardSeed,
|
generateRewardSeed,
|
||||||
@ -69,16 +70,22 @@ const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[]
|
|||||||
return rotations;
|
return rotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
const missionIndex: number | undefined = ExportRegions[rewardInfo.node]?.missionIndex;
|
||||||
|
|
||||||
// For Rescue missions
|
// For Rescue missions
|
||||||
if (rewardInfo.node in ExportRegions && ExportRegions[rewardInfo.node].missionIndex == 3 && rewardInfo.rewardTier) {
|
if (missionIndex == 3 && rewardInfo.rewardTier) {
|
||||||
return [rewardInfo.rewardTier];
|
return [rewardInfo.rewardTier];
|
||||||
}
|
}
|
||||||
|
|
||||||
const rotationCount = rewardInfo.rewardQualifications?.length || 0;
|
const rotationCount = rewardInfo.rewardQualifications?.length || 0;
|
||||||
|
|
||||||
// Empty or absent rewardQualifications should not give rewards:
|
// Empty or absent rewardQualifications should not give rewards when:
|
||||||
// - Aborting a railjack mission (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/1741)
|
|
||||||
// - Completing only 1 zone of (E)SO (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/1823)
|
// - Completing only 1 zone of (E)SO (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/1823)
|
||||||
|
// - Aborting a railjack mission (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/1741)
|
||||||
|
if (rotationCount == 0 && missionIndex != 30 && missionIndex != 32) {
|
||||||
|
return [0];
|
||||||
|
}
|
||||||
|
|
||||||
const rotationPattern =
|
const rotationPattern =
|
||||||
tierOverride === undefined
|
tierOverride === undefined
|
||||||
@ -184,6 +191,12 @@ export const addMissionInventoryUpdates = async (
|
|||||||
if (inventoryUpdates.RewardInfo.NemesisAbandonedRewards) {
|
if (inventoryUpdates.RewardInfo.NemesisAbandonedRewards) {
|
||||||
inventory.NemesisAbandonedRewards = inventoryUpdates.RewardInfo.NemesisAbandonedRewards;
|
inventory.NemesisAbandonedRewards = inventoryUpdates.RewardInfo.NemesisAbandonedRewards;
|
||||||
}
|
}
|
||||||
|
if (inventoryUpdates.RewardInfo.NemesisHenchmenKills && inventory.Nemesis) {
|
||||||
|
inventory.Nemesis.HenchmenKilled += inventoryUpdates.RewardInfo.NemesisHenchmenKills;
|
||||||
|
}
|
||||||
|
if (inventoryUpdates.RewardInfo.NemesisHintProgress && inventory.Nemesis) {
|
||||||
|
inventory.Nemesis.HintProgress += inventoryUpdates.RewardInfo.NemesisHintProgress;
|
||||||
|
}
|
||||||
if (inventoryUpdates.MissionStatus == "GS_SUCCESS" && inventoryUpdates.RewardInfo.jobId) {
|
if (inventoryUpdates.MissionStatus == "GS_SUCCESS" && inventoryUpdates.RewardInfo.jobId) {
|
||||||
// e.g. for Profit-Taker Phase 1:
|
// e.g. for Profit-Taker Phase 1:
|
||||||
// JobTier: -6,
|
// JobTier: -6,
|
||||||
@ -265,7 +278,14 @@ export const addMissionInventoryUpdates = async (
|
|||||||
addMiscItems(inventory, value);
|
addMiscItems(inventory, value);
|
||||||
break;
|
break;
|
||||||
case "Consumables":
|
case "Consumables":
|
||||||
|
if (config.dontSubtractConsumables) {
|
||||||
|
addConsumables(
|
||||||
|
inventory,
|
||||||
|
value.filter(x => x.ItemCount > 0)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
addConsumables(inventory, value);
|
addConsumables(inventory, value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "Recipes":
|
case "Recipes":
|
||||||
addRecipes(inventory, value);
|
addRecipes(inventory, value);
|
||||||
@ -411,6 +431,11 @@ export const addMissionInventoryUpdates = async (
|
|||||||
upgrade.UpgradeFingerprint = clientUpgrade.UpgradeFingerprint; // primitive way to copy over the riven challenge progress
|
upgrade.UpgradeFingerprint = clientUpgrade.UpgradeFingerprint; // primitive way to copy over the riven challenge progress
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case "WeaponSkins":
|
||||||
|
for (const item of value) {
|
||||||
|
addSkin(inventory, item.ItemType);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "Boosters":
|
case "Boosters":
|
||||||
value.forEach(booster => {
|
value.forEach(booster => {
|
||||||
addBooster(booster.ItemType, booster.ExpiryDate, inventory);
|
addBooster(booster.ItemType, booster.ExpiryDate, inventory);
|
||||||
@ -1277,6 +1302,9 @@ function getRandomMissionDrops(
|
|||||||
// Invasion assassination has Phorid has the boss who should drop Nyx parts
|
// Invasion assassination has Phorid has the boss who should drop Nyx parts
|
||||||
// TODO: Check that the invasion faction is indeed FC_INFESTATION once the Invasions in worldState are more dynamic
|
// TODO: Check that the invasion faction is indeed FC_INFESTATION once the Invasions in worldState are more dynamic
|
||||||
rewardManifests = ["/Lotus/Types/Game/MissionDecks/BossMissionRewards/NyxRewards"];
|
rewardManifests = ["/Lotus/Types/Game/MissionDecks/BossMissionRewards/NyxRewards"];
|
||||||
|
} else if (RewardInfo.sortieId && region.missionIndex != 0) {
|
||||||
|
// Sortie mission types differ from the underlying node and hence also don't give rewards from the underlying nodes. Assassinations are an exception to this.
|
||||||
|
rewardManifests = [];
|
||||||
} else {
|
} else {
|
||||||
rewardManifests = region.rewardManifests;
|
rewardManifests = region.rewardManifests;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
import { PersonalRooms } from "@/src/models/personalRoomsModel";
|
import { PersonalRooms } from "@/src/models/personalRoomsModel";
|
||||||
import { addItem, getInventory } from "@/src/services/inventoryService";
|
import { addItem, getInventory } from "@/src/services/inventoryService";
|
||||||
import { TPersonalRoomsDatabaseDocument } from "../types/personalRoomsTypes";
|
import { TPersonalRoomsDatabaseDocument } from "../types/personalRoomsTypes";
|
||||||
|
import { IGardeningDatabase } from "../types/shipTypes";
|
||||||
|
import { getRandomElement } from "./rngService";
|
||||||
|
|
||||||
export const getPersonalRooms = async (accountId: string): Promise<TPersonalRoomsDatabaseDocument> => {
|
export const getPersonalRooms = async (
|
||||||
const personalRooms = await PersonalRooms.findOne({ personalRoomsOwnerId: accountId });
|
accountId: string,
|
||||||
|
projection?: string
|
||||||
|
): Promise<TPersonalRoomsDatabaseDocument> => {
|
||||||
|
const personalRooms = await PersonalRooms.findOne({ personalRoomsOwnerId: accountId }, projection);
|
||||||
|
|
||||||
if (!personalRooms) {
|
if (!personalRooms) {
|
||||||
throw new Error(`personal rooms not found for account ${accountId}`);
|
throw new Error(`personal rooms not found for account ${accountId}`);
|
||||||
@ -25,3 +30,64 @@ export const updateShipFeature = async (accountId: string, shipFeature: string):
|
|||||||
await addItem(inventory, shipFeature, -1);
|
await addItem(inventory, shipFeature, -1);
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const createGarden = (): IGardeningDatabase => {
|
||||||
|
const plantTypes = [
|
||||||
|
"/Lotus/Types/Items/Plants/MiscItems/DuvxDuviriGrowingPlantA",
|
||||||
|
"/Lotus/Types/Items/Plants/MiscItems/DuvxDuviriGrowingPlantB",
|
||||||
|
"/Lotus/Types/Items/Plants/MiscItems/DuvxDuviriGrowingPlantC",
|
||||||
|
"/Lotus/Types/Items/Plants/MiscItems/DuvxDuviriGrowingPlantD",
|
||||||
|
"/Lotus/Types/Items/Plants/MiscItems/DuvxDuviriGrowingPlantE",
|
||||||
|
"/Lotus/Types/Items/Plants/MiscItems/DuvxDuviriGrowingPlantF"
|
||||||
|
];
|
||||||
|
const endTime = new Date((Math.trunc(Date.now() / 1000) + 79200) * 1000); // Plants will take 22 hours to grow
|
||||||
|
return {
|
||||||
|
Planters: [
|
||||||
|
{
|
||||||
|
Name: "Garden0",
|
||||||
|
Plants: [
|
||||||
|
{
|
||||||
|
PlantType: getRandomElement(plantTypes),
|
||||||
|
EndTime: endTime,
|
||||||
|
PlotIndex: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlantType: getRandomElement(plantTypes),
|
||||||
|
EndTime: endTime,
|
||||||
|
PlotIndex: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Garden1",
|
||||||
|
Plants: [
|
||||||
|
{
|
||||||
|
PlantType: getRandomElement(plantTypes),
|
||||||
|
EndTime: endTime,
|
||||||
|
PlotIndex: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlantType: getRandomElement(plantTypes),
|
||||||
|
EndTime: endTime,
|
||||||
|
PlotIndex: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Garden2",
|
||||||
|
Plants: [
|
||||||
|
{
|
||||||
|
PlantType: getRandomElement(plantTypes),
|
||||||
|
EndTime: endTime,
|
||||||
|
PlotIndex: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PlantType: getRandomElement(plantTypes),
|
||||||
|
EndTime: endTime,
|
||||||
|
PlotIndex: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -66,6 +66,18 @@ export const handlePurchase = async (
|
|||||||
if (!offer) {
|
if (!offer) {
|
||||||
throw new Error(`unknown vendor offer: ${ItemId ? ItemId : purchaseRequest.PurchaseParams.StoreItem}`);
|
throw new Error(`unknown vendor offer: ${ItemId ? ItemId : purchaseRequest.PurchaseParams.StoreItem}`);
|
||||||
}
|
}
|
||||||
|
if (offer.RegularPrice) {
|
||||||
|
combineInventoryChanges(
|
||||||
|
prePurchaseInventoryChanges,
|
||||||
|
updateCurrency(inventory, offer.RegularPrice[0], false)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (offer.PremiumPrice) {
|
||||||
|
combineInventoryChanges(
|
||||||
|
prePurchaseInventoryChanges,
|
||||||
|
updateCurrency(inventory, offer.PremiumPrice[0], true)
|
||||||
|
);
|
||||||
|
}
|
||||||
if (offer.ItemPrices) {
|
if (offer.ItemPrices) {
|
||||||
handleItemPrices(
|
handleItemPrices(
|
||||||
inventory,
|
inventory,
|
||||||
@ -170,6 +182,9 @@ export const handlePurchase = async (
|
|||||||
purchaseResponse.InventoryChanges,
|
purchaseResponse.InventoryChanges,
|
||||||
updateCurrency(inventory, offer.RegularPrice, false)
|
updateCurrency(inventory, offer.RegularPrice, false)
|
||||||
);
|
);
|
||||||
|
if (purchaseRequest.PurchaseParams.ExpectedPrice) {
|
||||||
|
throw new Error(`vendor purchase should not have an expected price`);
|
||||||
|
}
|
||||||
|
|
||||||
const invItem: IMiscItem = {
|
const invItem: IMiscItem = {
|
||||||
ItemType: "/Lotus/Types/Items/MiscItems/PrimeBucks",
|
ItemType: "/Lotus/Types/Items/MiscItems/PrimeBucks",
|
||||||
@ -229,6 +244,12 @@ export const handlePurchase = async (
|
|||||||
updateCurrency(inventory, offer.credits, false)
|
updateCurrency(inventory, offer.credits, false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (typeof offer.platinum == "number") {
|
||||||
|
combineInventoryChanges(
|
||||||
|
purchaseResponse.InventoryChanges,
|
||||||
|
updateCurrency(inventory, offer.platinum, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
if (offer.itemPrices) {
|
if (offer.itemPrices) {
|
||||||
handleItemPrices(
|
handleItemPrices(
|
||||||
inventory,
|
inventory,
|
||||||
@ -239,6 +260,9 @@ export const handlePurchase = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (purchaseRequest.PurchaseParams.ExpectedPrice) {
|
||||||
|
throw new Error(`vendor purchase should not have an expected price`);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 18: {
|
case 18: {
|
||||||
if (purchaseRequest.PurchaseParams.SourceId! != worldState.PrimeVaultTraders[0]._id.$oid) {
|
if (purchaseRequest.PurchaseParams.SourceId! != worldState.PrimeVaultTraders[0]._id.$oid) {
|
||||||
|
@ -161,6 +161,11 @@ export const handleInventoryItemConfigChange = async (
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "LotusCustomization": {
|
||||||
|
logger.debug(`saved LotusCustomization`, equipmentChanges.LotusCustomization);
|
||||||
|
inventory.LotusCustomization = equipmentChanges.LotusCustomization;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
if (equipmentKeys.includes(equipmentName as TEquipmentKey) && equipmentName != "ValidNewLoadoutId") {
|
if (equipmentKeys.includes(equipmentName as TEquipmentKey) && equipmentName != "ValidNewLoadoutId") {
|
||||||
logger.debug(`general Item config saved of type ${equipmentName}`, {
|
logger.debug(`general Item config saved of type ${equipmentName}`, {
|
||||||
|
@ -50,21 +50,27 @@ const sortieBossToFaction: Record<string, string> = {
|
|||||||
SORTIE_BOSS_PHORID: "FC_INFESTATION",
|
SORTIE_BOSS_PHORID: "FC_INFESTATION",
|
||||||
SORTIE_BOSS_LEPHANTIS: "FC_INFESTATION",
|
SORTIE_BOSS_LEPHANTIS: "FC_INFESTATION",
|
||||||
SORTIE_BOSS_INFALAD: "FC_INFESTATION",
|
SORTIE_BOSS_INFALAD: "FC_INFESTATION",
|
||||||
SORTIE_BOSS_CORRUPTED_VOR: "FC_CORRUPTED"
|
SORTIE_BOSS_CORRUPTED_VOR: "FC_OROKIN"
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortieFactionToSystemIndexes: Record<string, number[]> = {
|
const sortieFactionToSystemIndexes: Record<string, number[]> = {
|
||||||
FC_GRINEER: [0, 2, 3, 5, 6, 9, 11, 18],
|
FC_GRINEER: [0, 2, 3, 5, 6, 9, 11, 18],
|
||||||
FC_CORPUS: [1, 4, 7, 8, 12, 15],
|
FC_CORPUS: [1, 4, 7, 8, 12, 15],
|
||||||
FC_INFESTATION: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15],
|
FC_INFESTATION: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15],
|
||||||
FC_CORRUPTED: [14]
|
FC_OROKIN: [14]
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortieFactionToFactionIndexes: Record<string, number[]> = {
|
const sortieFactionToFactionIndexes: Record<string, number[]> = {
|
||||||
FC_GRINEER: [0],
|
FC_GRINEER: [0],
|
||||||
FC_CORPUS: [1],
|
FC_CORPUS: [1],
|
||||||
FC_INFESTATION: [0, 1, 2],
|
FC_INFESTATION: [0, 1, 2],
|
||||||
FC_CORRUPTED: [3]
|
FC_OROKIN: [3]
|
||||||
|
};
|
||||||
|
|
||||||
|
const sortieFactionToSpecialMissionTileset: Record<string, string> = {
|
||||||
|
FC_GRINEER: "GrineerGalleonTileset",
|
||||||
|
FC_CORPUS: "CorpusShipTileset",
|
||||||
|
FC_INFESTATION: "CorpusShipTileset"
|
||||||
};
|
};
|
||||||
|
|
||||||
const sortieBossNode: Record<string, string> = {
|
const sortieBossNode: Record<string, string> = {
|
||||||
@ -273,14 +279,7 @@ const pushSortieIfRelevant = (worldState: IWorldState, day: number): void => {
|
|||||||
if (
|
if (
|
||||||
sortieFactionToSystemIndexes[sortieBossToFaction[boss]].includes(value.systemIndex) &&
|
sortieFactionToSystemIndexes[sortieBossToFaction[boss]].includes(value.systemIndex) &&
|
||||||
sortieFactionToFactionIndexes[sortieBossToFaction[boss]].includes(value.factionIndex!) &&
|
sortieFactionToFactionIndexes[sortieBossToFaction[boss]].includes(value.factionIndex!) &&
|
||||||
!isArchwingMission(value) &&
|
key in sortieTilesets
|
||||||
value.missionIndex != 0 && // Exclude MT_ASSASSINATION
|
|
||||||
value.missionIndex != 10 && // Exclude MT_PVP (for relays)
|
|
||||||
value.missionIndex != 21 && // Exclude MT_PURIFY
|
|
||||||
value.missionIndex != 22 && // Exclude MT_ARENA
|
|
||||||
value.missionIndex != 23 && // Exclude MT_JUNCTION
|
|
||||||
(value.missionIndex != 28 || value.systemIndex == 2) && // MT_LANDSCAPE only on Earth
|
|
||||||
value.missionIndex < 29
|
|
||||||
) {
|
) {
|
||||||
if (!availableMissionIndexes.includes(value.missionIndex)) {
|
if (!availableMissionIndexes.includes(value.missionIndex)) {
|
||||||
availableMissionIndexes.push(value.missionIndex);
|
availableMissionIndexes.push(value.missionIndex);
|
||||||
@ -289,21 +288,36 @@ const pushSortieIfRelevant = (worldState: IWorldState, day: number): void => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const specialMissionTypes = [1, 3, 5, 9];
|
||||||
|
if (!(sortieBossToFaction[boss] in sortieFactionToSpecialMissionTileset)) {
|
||||||
|
for (const missionType of specialMissionTypes) {
|
||||||
|
const i = availableMissionIndexes.indexOf(missionType);
|
||||||
|
if (i != -1) {
|
||||||
|
availableMissionIndexes.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const selectedNodes: ISortieMission[] = [];
|
const selectedNodes: ISortieMission[] = [];
|
||||||
const missionTypes = new Set();
|
const missionTypes = new Set();
|
||||||
|
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
const randomIndex = rng.randomInt(0, nodes.length - 1);
|
let randomIndex;
|
||||||
const node = nodes[randomIndex];
|
let node;
|
||||||
let missionIndex = ExportRegions[node].missionIndex;
|
let missionIndex;
|
||||||
|
do {
|
||||||
|
randomIndex = rng.randomInt(0, nodes.length - 1);
|
||||||
|
node = nodes[randomIndex];
|
||||||
|
|
||||||
if (
|
missionIndex = ExportRegions[node].missionIndex;
|
||||||
!["SolNode404", "SolNode411"].includes(node) && // for some reason the game doesn't like missionType changes for these missions
|
if (missionIndex != 28) {
|
||||||
missionIndex != 28 &&
|
|
||||||
rng.randomInt(0, 2) == 2
|
|
||||||
) {
|
|
||||||
missionIndex = rng.randomElement(availableMissionIndexes);
|
missionIndex = rng.randomElement(availableMissionIndexes);
|
||||||
}
|
}
|
||||||
|
} while (
|
||||||
|
specialMissionTypes.indexOf(missionIndex) != -1 &&
|
||||||
|
sortieTilesets[node as keyof typeof sortieTilesets] !=
|
||||||
|
sortieFactionToSpecialMissionTileset[sortieBossToFaction[boss]]
|
||||||
|
);
|
||||||
|
|
||||||
if (i == 2 && rng.randomInt(0, 2) == 2) {
|
if (i == 2 && rng.randomInt(0, 2) == 2) {
|
||||||
const filteredModifiers = modifiers.filter(mod => mod !== "SORTIE_MODIFIER_MELEE_ONLY");
|
const filteredModifiers = modifiers.filter(mod => mod !== "SORTIE_MODIFIER_MELEE_ONLY");
|
||||||
|
@ -328,7 +328,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
BlessingCooldown?: IMongoDate;
|
BlessingCooldown?: IMongoDate;
|
||||||
CrewShipRawSalvage: ITypeCount[];
|
CrewShipRawSalvage: ITypeCount[];
|
||||||
CrewMembers: ICrewMemberClient[];
|
CrewMembers: ICrewMemberClient[];
|
||||||
LotusCustomization: ILotusCustomization;
|
LotusCustomization?: ILotusCustomization;
|
||||||
UseAdultOperatorLoadout?: boolean;
|
UseAdultOperatorLoadout?: boolean;
|
||||||
NemesisAbandonedRewards: string[];
|
NemesisAbandonedRewards: string[];
|
||||||
LastInventorySync: IOid;
|
LastInventorySync: IOid;
|
||||||
|
@ -8,6 +8,8 @@ export interface IMissionReward {
|
|||||||
TypeName?: string;
|
TypeName?: string;
|
||||||
UpgradeLevel?: number;
|
UpgradeLevel?: number;
|
||||||
ItemCount: number;
|
ItemCount: number;
|
||||||
|
DailyCooldown?: boolean;
|
||||||
|
Rarity?: number;
|
||||||
TweetText?: string;
|
TweetText?: string;
|
||||||
ProductCategory?: string;
|
ProductCategory?: string;
|
||||||
FromEnemyCache?: boolean;
|
FromEnemyCache?: boolean;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { IColor } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
import { IColor } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||||
import {
|
import {
|
||||||
IApartment,
|
|
||||||
IRoom,
|
IRoom,
|
||||||
IPlacedDecosDatabase,
|
IPlacedDecosDatabase,
|
||||||
ITailorShop,
|
ITailorShop,
|
||||||
ITailorShopDatabase,
|
ITailorShopDatabase,
|
||||||
TBootLocation,
|
TBootLocation,
|
||||||
IApartmentDatabase
|
IApartmentDatabase,
|
||||||
|
IApartmentClient
|
||||||
} from "@/src/types/shipTypes";
|
} from "@/src/types/shipTypes";
|
||||||
import { Document, Model, Types } from "mongoose";
|
import { Document, Model, Types } from "mongoose";
|
||||||
|
|
||||||
@ -21,10 +21,10 @@ export interface IOrbiter {
|
|||||||
BootLocation?: TBootLocation;
|
BootLocation?: TBootLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPersonalRooms {
|
export interface IPersonalRoomsClient {
|
||||||
ShipInteriorColors: IColor;
|
ShipInteriorColors: IColor;
|
||||||
Ship: IOrbiter;
|
Ship: IOrbiter;
|
||||||
Apartment: IApartment;
|
Apartment: IApartmentClient;
|
||||||
TailorShop: ITailorShop;
|
TailorShop: ITailorShop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@ import {
|
|||||||
IDiscoveredMarker,
|
IDiscoveredMarker,
|
||||||
ILockedWeaponGroupClient,
|
ILockedWeaponGroupClient,
|
||||||
ILoadOutPresets,
|
ILoadOutPresets,
|
||||||
IInvasionProgressClient
|
IInvasionProgressClient,
|
||||||
|
IWeaponSkinClient
|
||||||
} from "./inventoryTypes/inventoryTypes";
|
} from "./inventoryTypes/inventoryTypes";
|
||||||
import { IGroup } from "./loginTypes";
|
import { IGroup } from "./loginTypes";
|
||||||
|
|
||||||
@ -101,6 +102,7 @@ export type IMissionInventoryUpdateRequest = {
|
|||||||
}[];
|
}[];
|
||||||
CollectibleScans?: ICollectibleEntry[];
|
CollectibleScans?: ICollectibleEntry[];
|
||||||
Upgrades?: IUpgradeClient[]; // riven challenge progress
|
Upgrades?: IUpgradeClient[]; // riven challenge progress
|
||||||
|
WeaponSkins?: IWeaponSkinClient[];
|
||||||
StrippedItems?: {
|
StrippedItems?: {
|
||||||
DropTable: string;
|
DropTable: string;
|
||||||
DROP_MOD?: number[];
|
DROP_MOD?: number[];
|
||||||
@ -156,6 +158,8 @@ export interface IRewardInfo {
|
|||||||
lostTargetWave?: number;
|
lostTargetWave?: number;
|
||||||
defenseTargetCount?: number;
|
defenseTargetCount?: number;
|
||||||
NemesisAbandonedRewards?: string[];
|
NemesisAbandonedRewards?: string[];
|
||||||
|
NemesisHenchmenKills?: number;
|
||||||
|
NemesisHintProgress?: number;
|
||||||
EOM_AFK?: number;
|
EOM_AFK?: number;
|
||||||
rewardQualifications?: string; // did a Survival for 5 minutes and this was "1"
|
rewardQualifications?: string; // did a Survival for 5 minutes and this was "1"
|
||||||
PurgatoryRewardQualifications?: string;
|
PurgatoryRewardQualifications?: string;
|
||||||
|
@ -6,7 +6,8 @@ import {
|
|||||||
ICrewShipMembersClient,
|
ICrewShipMembersClient,
|
||||||
ICrewShipWeapon,
|
ICrewShipWeapon,
|
||||||
IFlavourItem,
|
IFlavourItem,
|
||||||
ILoadoutConfigClient
|
ILoadoutConfigClient,
|
||||||
|
ILotusCustomization
|
||||||
} from "./inventoryTypes/inventoryTypes";
|
} from "./inventoryTypes/inventoryTypes";
|
||||||
|
|
||||||
export interface ISaveLoadoutRequest {
|
export interface ISaveLoadoutRequest {
|
||||||
@ -43,6 +44,7 @@ export interface ISaveLoadoutRequest {
|
|||||||
EquippedEmotes: string[];
|
EquippedEmotes: string[];
|
||||||
UseAdultOperatorLoadout: boolean;
|
UseAdultOperatorLoadout: boolean;
|
||||||
WeaponSkins: IItemEntry;
|
WeaponSkins: IItemEntry;
|
||||||
|
LotusCustomization: ILotusCustomization;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ISaveLoadoutRequestNoUpgradeVer = Omit<ISaveLoadoutRequest, "UpgradeVer">;
|
export type ISaveLoadoutRequestNoUpgradeVer = Omit<ISaveLoadoutRequest, "UpgradeVer">;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import { IOid } from "@/src/types/commonTypes";
|
import { IMongoDate, IOid } from "@/src/types/commonTypes";
|
||||||
import { IColor } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
import { IColor } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||||
import { ILoadoutClient } from "./saveLoadoutTypes";
|
import { ILoadoutClient } from "./saveLoadoutTypes";
|
||||||
|
|
||||||
export interface IGetShipResponse {
|
export interface IGetShipResponse {
|
||||||
ShipOwnerId: string;
|
ShipOwnerId: string;
|
||||||
Ship: IShip;
|
Ship: IShip;
|
||||||
Apartment: IApartment;
|
Apartment: IApartmentClient;
|
||||||
TailorShop: ITailorShop;
|
TailorShop: ITailorShop;
|
||||||
LoadOutInventory: { LoadOutPresets: ILoadoutClient };
|
LoadOutInventory: { LoadOutPresets: ILoadoutClient };
|
||||||
}
|
}
|
||||||
@ -51,28 +51,42 @@ export interface IRoom {
|
|||||||
PlacedDecos?: IPlacedDecosDatabase[];
|
PlacedDecos?: IPlacedDecosDatabase[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPlants {
|
export interface IPlantClient {
|
||||||
PlantType: string;
|
PlantType: string;
|
||||||
EndTime: IOid;
|
EndTime: IMongoDate;
|
||||||
PlotIndex: number;
|
PlotIndex: number;
|
||||||
}
|
}
|
||||||
export interface IPlanters {
|
|
||||||
|
export interface IPlantDatabase extends Omit<IPlantClient, "EndTime"> {
|
||||||
|
EndTime: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPlanterClient {
|
||||||
Name: string;
|
Name: string;
|
||||||
Plants: IPlants[];
|
Plants: IPlantClient[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IGardening {
|
export interface IPlanterDatabase {
|
||||||
Planters?: IPlanters[];
|
Name: string;
|
||||||
|
Plants: IPlantDatabase[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IApartment {
|
export interface IGardeningClient {
|
||||||
Gardening: IGardening;
|
Planters: IPlanterClient[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IGardeningDatabase {
|
||||||
|
Planters: IPlanterDatabase[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IApartmentClient {
|
||||||
|
Gardening: IGardeningClient;
|
||||||
Rooms: IRoom[];
|
Rooms: IRoom[];
|
||||||
FavouriteLoadouts: IFavouriteLoadout[];
|
FavouriteLoadouts: IFavouriteLoadout[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IApartmentDatabase {
|
export interface IApartmentDatabase {
|
||||||
Gardening: IGardening;
|
Gardening: IGardeningDatabase;
|
||||||
Rooms: IRoom[];
|
Rooms: IRoom[];
|
||||||
FavouriteLoadouts: IFavouriteLoadoutDatabase[];
|
FavouriteLoadouts: IFavouriteLoadoutDatabase[];
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ export interface IItemManifest {
|
|||||||
StoreItem: string;
|
StoreItem: string;
|
||||||
ItemPrices?: IItemPrice[];
|
ItemPrices?: IItemPrice[];
|
||||||
RegularPrice?: number[];
|
RegularPrice?: number[];
|
||||||
|
PremiumPrice?: number[];
|
||||||
Bin: string;
|
Bin: string;
|
||||||
QuantityMultiplier: number;
|
QuantityMultiplier: number;
|
||||||
Expiry: IMongoDate; // Either a date in the distant future or a period in milliseconds for preprocessing.
|
Expiry: IMongoDate; // Either a date in the distant future or a period in milliseconds for preprocessing.
|
||||||
|
@ -510,8 +510,9 @@
|
|||||||
<div class="card mb-3">
|
<div class="card mb-3">
|
||||||
<h5 class="card-header" data-loc="general_bulkActions"></h5>
|
<h5 class="card-header" data-loc="general_bulkActions"></h5>
|
||||||
<div class="card-body d-flex flex-wrap gap-2">
|
<div class="card-body d-flex flex-wrap gap-2">
|
||||||
<button class="btn btn-primary" onclick="doAddAllMods();" data-loc="mods_bulkAddMods"></button>
|
<button class="btn btn-primary" onclick="doAddAllMods();" data-loc="mods_addMissingUnrankedMods"></button>
|
||||||
<button class="btn btn-danger" onclick="doRemoveUnrankedMods();" data-loc="mods_removeUnranked"></button>
|
<button class="btn btn-danger" onclick="doRemoveUnrankedMods();" data-loc="mods_removeUnranked"></button>
|
||||||
|
<button class="btn btn-primary" onclick="doAddMissingMaxRankMods();" data-loc="mods_addMissingMaxRankMods"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -593,6 +594,10 @@
|
|||||||
<input class="form-check-input" type="checkbox" id="infiniteHelminthMaterials" />
|
<input class="form-check-input" type="checkbox" id="infiniteHelminthMaterials" />
|
||||||
<label class="form-check-label" for="infiniteHelminthMaterials" data-loc="cheats_infiniteHelminthMaterials"></label>
|
<label class="form-check-label" for="infiniteHelminthMaterials" data-loc="cheats_infiniteHelminthMaterials"></label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" id="dontSubtractConsumables" />
|
||||||
|
<label class="form-check-label" for="dontSubtractConsumables" data-loc="cheats_dontSubtractConsumables"></label>
|
||||||
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox" id="unlockAllShipFeatures" />
|
<input class="form-check-input" type="checkbox" id="unlockAllShipFeatures" />
|
||||||
<label class="form-check-label" for="unlockAllShipFeatures" data-loc="cheats_unlockAllShipFeatures"></label>
|
<label class="form-check-label" for="unlockAllShipFeatures" data-loc="cheats_unlockAllShipFeatures"></label>
|
||||||
|
@ -1795,6 +1795,14 @@ function doRemoveUnrankedMods() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function doAddMissingMaxRankMods() {
|
||||||
|
revalidateAuthz(() => {
|
||||||
|
fetch("/custom/addMissingMaxRankMods?" + window.authz).then(() => {
|
||||||
|
updateInventory();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Powersuit Route
|
// Powersuit Route
|
||||||
|
|
||||||
single.getRoute("#powersuit-route").on("beforeload", function () {
|
single.getRoute("#powersuit-route").on("beforeload", function () {
|
||||||
|
@ -120,8 +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_bulkAddMods: `Fehlende Mods hinzufügen`,
|
mods_addMissingUnrankedMods: `[UNTRANSLATED] Add Missing Unranked Mods`,
|
||||||
mods_removeUnranked: `Mods ohne Rang entfernen`,
|
mods_removeUnranked: `Mods ohne Rang entfernen`,
|
||||||
|
mods_addMissingMaxRankMods: `[UNTRANSLATED] Add Missing Max Rank Mods`,
|
||||||
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`,
|
||||||
@ -133,6 +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_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`,
|
||||||
|
@ -119,8 +119,9 @@ dict = {
|
|||||||
mods_fingerprintHelp: `Need help with the fingerprint?`,
|
mods_fingerprintHelp: `Need help with the fingerprint?`,
|
||||||
mods_rivens: `Rivens`,
|
mods_rivens: `Rivens`,
|
||||||
mods_mods: `Mods`,
|
mods_mods: `Mods`,
|
||||||
mods_bulkAddMods: `Add Missing Mods`,
|
mods_addMissingUnrankedMods: `Add Missing Unranked Mods`,
|
||||||
mods_removeUnranked: `Remove Unranked Mods`,
|
mods_removeUnranked: `Remove Unranked Mods`,
|
||||||
|
mods_addMissingMaxRankMods: `Add Missing Max Rank Mods`,
|
||||||
cheats_administratorRequirement: `You must be an administrator to use this feature. To become an administrator, add <code>|DISPLAYNAME|</code> to <code>administratorNames</code> in the config.json.`,
|
cheats_administratorRequirement: `You must be an administrator to use this feature. To become an administrator, add <code>|DISPLAYNAME|</code> to <code>administratorNames</code> in the config.json.`,
|
||||||
cheats_server: `Server`,
|
cheats_server: `Server`,
|
||||||
cheats_skipTutorial: `Skip Tutorial`,
|
cheats_skipTutorial: `Skip Tutorial`,
|
||||||
@ -132,6 +133,7 @@ dict = {
|
|||||||
cheats_infiniteEndo: `Infinite Endo`,
|
cheats_infiniteEndo: `Infinite Endo`,
|
||||||
cheats_infiniteRegalAya: `Infinite Regal Aya`,
|
cheats_infiniteRegalAya: `Infinite Regal Aya`,
|
||||||
cheats_infiniteHelminthMaterials: `Infinite Helminth Materials`,
|
cheats_infiniteHelminthMaterials: `Infinite Helminth Materials`,
|
||||||
|
cheats_dontSubtractConsumables: `Don't Subtract Consumables`,
|
||||||
cheats_unlockAllShipFeatures: `Unlock All Ship Features`,
|
cheats_unlockAllShipFeatures: `Unlock All Ship Features`,
|
||||||
cheats_unlockAllShipDecorations: `Unlock All Ship Decorations`,
|
cheats_unlockAllShipDecorations: `Unlock All Ship Decorations`,
|
||||||
cheats_unlockAllFlavourItems: `Unlock All <abbr title=\"Animation Sets, Glyphs, Palettes, etc.\">Flavor Items</abbr>`,
|
cheats_unlockAllFlavourItems: `Unlock All <abbr title=\"Animation Sets, Glyphs, Palettes, etc.\">Flavor Items</abbr>`,
|
||||||
|
@ -34,8 +34,8 @@ dict = {
|
|||||||
code_rerollsNumber: `Cantidad de reintentos`,
|
code_rerollsNumber: `Cantidad de reintentos`,
|
||||||
code_viewStats: `Ver estadísticas`,
|
code_viewStats: `Ver estadísticas`,
|
||||||
code_rank: `Rango`,
|
code_rank: `Rango`,
|
||||||
code_rankUp: `[UNTRANSLATED] Rank up`,
|
code_rankUp: `Subir de rango`,
|
||||||
code_rankDown: `[UNTRANSLATED] Rank down`,
|
code_rankDown: `Bajar de rango`,
|
||||||
code_count: `Cantidad`,
|
code_count: `Cantidad`,
|
||||||
code_focusAllUnlocked: `Todas las escuelas de enfoque ya están desbloqueadas.`,
|
code_focusAllUnlocked: `Todas las escuelas de enfoque ya están desbloqueadas.`,
|
||||||
code_focusUnlocked: `¡Desbloqueadas |COUNT| nuevas escuelas de enfoque! Se necesita una actualización del inventario para reflejar los cambios en el juego. Visitar la navegación debería ser la forma más sencilla de activarlo.`,
|
code_focusUnlocked: `¡Desbloqueadas |COUNT| nuevas escuelas de enfoque! Se necesita una actualización del inventario para reflejar los cambios en el juego. Visitar la navegación debería ser la forma más sencilla de activarlo.`,
|
||||||
@ -86,21 +86,21 @@ dict = {
|
|||||||
inventory_hoverboards: `K-Drives`,
|
inventory_hoverboards: `K-Drives`,
|
||||||
inventory_moaPets: `Moa`,
|
inventory_moaPets: `Moa`,
|
||||||
inventory_kubrowPets: `Bestias`,
|
inventory_kubrowPets: `Bestias`,
|
||||||
inventory_evolutionProgress: `[UNTRANSLATED] Incarnon Evolution Progress`,
|
inventory_evolutionProgress: `Progreso de evolución Incarnon`,
|
||||||
inventory_bulkAddSuits: `Agregar Warframes faltantes`,
|
inventory_bulkAddSuits: `Agregar Warframes faltantes`,
|
||||||
inventory_bulkAddWeapons: `Agregar armas faltantes`,
|
inventory_bulkAddWeapons: `Agregar armas faltantes`,
|
||||||
inventory_bulkAddSpaceSuits: `Agregar Archwings faltantes`,
|
inventory_bulkAddSpaceSuits: `Agregar Archwings faltantes`,
|
||||||
inventory_bulkAddSpaceWeapons: `Agregar armas Archwing faltantes`,
|
inventory_bulkAddSpaceWeapons: `Agregar armas Archwing faltantes`,
|
||||||
inventory_bulkAddSentinels: `Agregar centinelas faltantes`,
|
inventory_bulkAddSentinels: `Agregar centinelas faltantes`,
|
||||||
inventory_bulkAddSentinelWeapons: `Agregar armas de centinela faltantes`,
|
inventory_bulkAddSentinelWeapons: `Agregar armas de centinela faltantes`,
|
||||||
inventory_bulkAddEvolutionProgress: `[UNTRANSLATED] Add Missing Incarnon Evolution Progress`,
|
inventory_bulkAddEvolutionProgress: `Completar el progreso de evolución Incarnon faltante`,
|
||||||
inventory_bulkRankUpSuits: `Maximizar rango de todos los Warframes`,
|
inventory_bulkRankUpSuits: `Maximizar rango de todos los Warframes`,
|
||||||
inventory_bulkRankUpWeapons: `Maximizar rango de todas las armas`,
|
inventory_bulkRankUpWeapons: `Maximizar rango de todas las armas`,
|
||||||
inventory_bulkRankUpSpaceSuits: `Maximizar rango de todos los Archwings`,
|
inventory_bulkRankUpSpaceSuits: `Maximizar rango de todos los Archwings`,
|
||||||
inventory_bulkRankUpSpaceWeapons: `Maximizar rango de todas las armas Archwing`,
|
inventory_bulkRankUpSpaceWeapons: `Maximizar rango de todas las armas Archwing`,
|
||||||
inventory_bulkRankUpSentinels: `Maximizar rango de todos los centinelas`,
|
inventory_bulkRankUpSentinels: `Maximizar rango de todos los centinelas`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `Maximizar rango de todas las armas de centinela`,
|
inventory_bulkRankUpSentinelWeapons: `Maximizar rango de todas las armas de centinela`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `[UNTRANSLATED] Max Rank All Incarnon Evolution Progress`,
|
inventory_bulkRankUpEvolutionProgress: `Maximizar todo el progreso de evolución Incarnon`,
|
||||||
|
|
||||||
quests_list: `Misiones`,
|
quests_list: `Misiones`,
|
||||||
quests_completeAll: `Completar todas las misiones`,
|
quests_completeAll: `Completar todas las misiones`,
|
||||||
@ -120,8 +120,9 @@ dict = {
|
|||||||
mods_fingerprintHelp: `¿Necesitas ayuda con la huella digital?`,
|
mods_fingerprintHelp: `¿Necesitas ayuda con la huella digital?`,
|
||||||
mods_rivens: `Agrietados`,
|
mods_rivens: `Agrietados`,
|
||||||
mods_mods: `Mods`,
|
mods_mods: `Mods`,
|
||||||
mods_bulkAddMods: `Agregar mods faltantes`,
|
mods_addMissingUnrankedMods: `[UNTRANSLATED] Add Missing Unranked Mods`,
|
||||||
mods_removeUnranked: `Quitar mods sin rango`,
|
mods_removeUnranked: `Quitar mods sin rango`,
|
||||||
|
mods_addMissingMaxRankMods: `[UNTRANSLATED] Add Missing Max Rank Mods`,
|
||||||
cheats_administratorRequirement: `Debes ser administrador para usar esta función. Para convertirte en administrador, agrega <code>|DISPLAYNAME|</code> a <code>administratorNames</code> en el archivo config.json.`,
|
cheats_administratorRequirement: `Debes ser administrador para usar esta función. Para convertirte en administrador, agrega <code>|DISPLAYNAME|</code> a <code>administratorNames</code> en el archivo config.json.`,
|
||||||
cheats_server: `Servidor`,
|
cheats_server: `Servidor`,
|
||||||
cheats_skipTutorial: `Omitir tutorial`,
|
cheats_skipTutorial: `Omitir tutorial`,
|
||||||
@ -133,6 +134,7 @@ dict = {
|
|||||||
cheats_infiniteEndo: `Endo infinito`,
|
cheats_infiniteEndo: `Endo infinito`,
|
||||||
cheats_infiniteRegalAya: `Aya Real infinita`,
|
cheats_infiniteRegalAya: `Aya Real infinita`,
|
||||||
cheats_infiniteHelminthMaterials: `Materiales Helminto infinitos`,
|
cheats_infiniteHelminthMaterials: `Materiales Helminto infinitos`,
|
||||||
|
cheats_dontSubtractConsumables: `[UNTRANSLATED] Don't Subtract Consumables`,
|
||||||
cheats_unlockAllShipFeatures: `Desbloquear todas las funciones de nave`,
|
cheats_unlockAllShipFeatures: `Desbloquear todas las funciones de nave`,
|
||||||
cheats_unlockAllShipDecorations: `Desbloquear todas las decoraciones de nave`,
|
cheats_unlockAllShipDecorations: `Desbloquear todas las decoraciones de nave`,
|
||||||
cheats_unlockAllFlavourItems: `Desbloquear todos los <abbr title="Conjuntos de animaciones, glifos, paletas, etc.">ítems estéticos</abbr>`,
|
cheats_unlockAllFlavourItems: `Desbloquear todos los <abbr title="Conjuntos de animaciones, glifos, paletas, etc.">ítems estéticos</abbr>`,
|
||||||
|
@ -120,8 +120,9 @@ dict = {
|
|||||||
mods_fingerprintHelp: `Besoin d'aide pour l'empreinte ?`,
|
mods_fingerprintHelp: `Besoin d'aide pour l'empreinte ?`,
|
||||||
mods_rivens: `Rivens`,
|
mods_rivens: `Rivens`,
|
||||||
mods_mods: `Mods`,
|
mods_mods: `Mods`,
|
||||||
mods_bulkAddMods: `Ajouter les mods manquants`,
|
mods_addMissingUnrankedMods: `[UNTRANSLATED] Add Missing Unranked Mods`,
|
||||||
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
||||||
|
mods_addMissingMaxRankMods: `[UNTRANSLATED] Add Missing Max Rank Mods`,
|
||||||
cheats_administratorRequirement: `Rôle d'administrateur requis pour cette fonctionnalité. Ajoutez <code>|DISPLAYNAME|</code> à la ligne <code>administratorNames</code> dans le fichier config.json.`,
|
cheats_administratorRequirement: `Rôle d'administrateur requis pour cette fonctionnalité. Ajoutez <code>|DISPLAYNAME|</code> à la ligne <code>administratorNames</code> dans le fichier config.json.`,
|
||||||
cheats_server: `Serveur`,
|
cheats_server: `Serveur`,
|
||||||
cheats_skipTutorial: `Passer le tutoriel`,
|
cheats_skipTutorial: `Passer le tutoriel`,
|
||||||
@ -133,6 +134,7 @@ dict = {
|
|||||||
cheats_infiniteEndo: `Endo infini`,
|
cheats_infiniteEndo: `Endo infini`,
|
||||||
cheats_infiniteRegalAya: `Aya Raffiné infini`,
|
cheats_infiniteRegalAya: `Aya Raffiné infini`,
|
||||||
cheats_infiniteHelminthMaterials: `Ressources d'Helminth infinies`,
|
cheats_infiniteHelminthMaterials: `Ressources d'Helminth infinies`,
|
||||||
|
cheats_dontSubtractConsumables: `[UNTRANSLATED] Don't Subtract Consumables`,
|
||||||
cheats_unlockAllShipFeatures: `Débloquer tous les segments du vaisseau`,
|
cheats_unlockAllShipFeatures: `Débloquer tous les segments du vaisseau`,
|
||||||
cheats_unlockAllShipDecorations: `Débloquer toutes les décorations du vaisseau`,
|
cheats_unlockAllShipDecorations: `Débloquer toutes les décorations du vaisseau`,
|
||||||
cheats_unlockAllFlavourItems: `Débloquer tous les <abbr title=\"Animations, Glyphes, Palettes, etc.\">Flavor Items</abbr>`,
|
cheats_unlockAllFlavourItems: `Débloquer tous les <abbr title=\"Animations, Glyphes, Palettes, etc.\">Flavor Items</abbr>`,
|
||||||
|
@ -120,8 +120,9 @@ dict = {
|
|||||||
mods_fingerprintHelp: `Нужна помощь с отпечатком?`,
|
mods_fingerprintHelp: `Нужна помощь с отпечатком?`,
|
||||||
mods_rivens: `Моды Разлома`,
|
mods_rivens: `Моды Разлома`,
|
||||||
mods_mods: `Моды`,
|
mods_mods: `Моды`,
|
||||||
mods_bulkAddMods: `Добавить отсутствующие моды`,
|
mods_addMissingUnrankedMods: `[UNTRANSLATED] Add Missing Unranked Mods`,
|
||||||
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
||||||
|
mods_addMissingMaxRankMods: `[UNTRANSLATED] Add Missing Max Rank Mods`,
|
||||||
cheats_administratorRequirement: `Вы должны быть администратором для использования этой функции. Чтобы стать администратором, добавьте <code>\"|DISPLAYNAME|\"</code> в <code>administratorNames</code> в config.json.`,
|
cheats_administratorRequirement: `Вы должны быть администратором для использования этой функции. Чтобы стать администратором, добавьте <code>\"|DISPLAYNAME|\"</code> в <code>administratorNames</code> в config.json.`,
|
||||||
cheats_server: `Сервер`,
|
cheats_server: `Сервер`,
|
||||||
cheats_skipTutorial: `Пропустить обучение`,
|
cheats_skipTutorial: `Пропустить обучение`,
|
||||||
@ -133,6 +134,7 @@ dict = {
|
|||||||
cheats_infiniteEndo: `Бесконечное эндо`,
|
cheats_infiniteEndo: `Бесконечное эндо`,
|
||||||
cheats_infiniteRegalAya: `Бесконечная Королевская Айя`,
|
cheats_infiniteRegalAya: `Бесконечная Королевская Айя`,
|
||||||
cheats_infiniteHelminthMaterials: `Бесконечные Выделения Гельминта`,
|
cheats_infiniteHelminthMaterials: `Бесконечные Выделения Гельминта`,
|
||||||
|
cheats_dontSubtractConsumables: `[UNTRANSLATED] Don't Subtract Consumables`,
|
||||||
cheats_unlockAllShipFeatures: `Разблокировать все функции корабля`,
|
cheats_unlockAllShipFeatures: `Разблокировать все функции корабля`,
|
||||||
cheats_unlockAllShipDecorations: `Разблокировать все украшения корабля`,
|
cheats_unlockAllShipDecorations: `Разблокировать все украшения корабля`,
|
||||||
cheats_unlockAllFlavourItems: `Разблокировать все <abbr title=\"Наборы анимаций, глифы, палитры и т. д.\">уникальные предметы</abbr>`,
|
cheats_unlockAllFlavourItems: `Разблокировать все <abbr title=\"Наборы анимаций, глифы, палитры и т. д.\">уникальные предметы</abbr>`,
|
||||||
|
@ -120,8 +120,9 @@ dict = {
|
|||||||
mods_fingerprintHelp: `需要印记相关的帮助?`,
|
mods_fingerprintHelp: `需要印记相关的帮助?`,
|
||||||
mods_rivens: `裂罅MOD`,
|
mods_rivens: `裂罅MOD`,
|
||||||
mods_mods: `Mods`,
|
mods_mods: `Mods`,
|
||||||
mods_bulkAddMods: `添加缺失MOD`,
|
mods_addMissingUnrankedMods: `[UNTRANSLATED] Add Missing Unranked Mods`,
|
||||||
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
||||||
|
mods_addMissingMaxRankMods: `[UNTRANSLATED] Add Missing Max Rank Mods`,
|
||||||
cheats_administratorRequirement: `您必须是管理员才能使用此功能。要成为管理员,请将 <code>|DISPLAYNAME|</code> 添加到 config.json 的 <code>administratorNames</code> 中。`,
|
cheats_administratorRequirement: `您必须是管理员才能使用此功能。要成为管理员,请将 <code>|DISPLAYNAME|</code> 添加到 config.json 的 <code>administratorNames</code> 中。`,
|
||||||
cheats_server: `服务器`,
|
cheats_server: `服务器`,
|
||||||
cheats_skipTutorial: `跳过教程`,
|
cheats_skipTutorial: `跳过教程`,
|
||||||
@ -133,6 +134,7 @@ dict = {
|
|||||||
cheats_infiniteEndo: `无限内融核心`,
|
cheats_infiniteEndo: `无限内融核心`,
|
||||||
cheats_infiniteRegalAya: `无限御品阿耶`,
|
cheats_infiniteRegalAya: `无限御品阿耶`,
|
||||||
cheats_infiniteHelminthMaterials: `无限Helminth材料`,
|
cheats_infiniteHelminthMaterials: `无限Helminth材料`,
|
||||||
|
cheats_dontSubtractConsumables: `[UNTRANSLATED] Don't Subtract Consumables`,
|
||||||
cheats_unlockAllShipFeatures: `解锁所有飞船功能`,
|
cheats_unlockAllShipFeatures: `解锁所有飞船功能`,
|
||||||
cheats_unlockAllShipDecorations: `解锁所有飞船装饰`,
|
cheats_unlockAllShipDecorations: `解锁所有飞船装饰`,
|
||||||
cheats_unlockAllFlavourItems: `解锁所有<abbr title=\"动画组合、图标、调色板等\">装饰物品</abbr>`,
|
cheats_unlockAllFlavourItems: `解锁所有<abbr title=\"动画组合、图标、调色板等\">装饰物品</abbr>`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user