chore(webui): update Chinese translation #2380
@ -60,6 +60,7 @@
 | 
				
			|||||||
  "unlockAllSimarisResearchEntries": false,
 | 
					  "unlockAllSimarisResearchEntries": false,
 | 
				
			||||||
  "disableDailyTribute": false,
 | 
					  "disableDailyTribute": false,
 | 
				
			||||||
  "spoofMasteryRank": -1,
 | 
					  "spoofMasteryRank": -1,
 | 
				
			||||||
 | 
					  "relicRewardItemCountMultiplier": 1,
 | 
				
			||||||
  "nightwaveStandingMultiplier": 1,
 | 
					  "nightwaveStandingMultiplier": 1,
 | 
				
			||||||
  "unfaithfulBugFixes": {
 | 
					  "unfaithfulBugFixes": {
 | 
				
			||||||
    "ignore1999LastRegionPlayed": false,
 | 
					    "ignore1999LastRegionPlayed": false,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -23,7 +23,7 @@
 | 
				
			|||||||
        "ncp": "^2.0.0",
 | 
					        "ncp": "^2.0.0",
 | 
				
			||||||
        "typescript": "^5.5",
 | 
					        "typescript": "^5.5",
 | 
				
			||||||
        "undici": "^7.10.0",
 | 
					        "undici": "^7.10.0",
 | 
				
			||||||
        "warframe-public-export-plus": "^0.5.74",
 | 
					        "warframe-public-export-plus": "^0.5.76",
 | 
				
			||||||
        "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",
 | 
				
			||||||
@ -3386,9 +3386,9 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/warframe-public-export-plus": {
 | 
					    "node_modules/warframe-public-export-plus": {
 | 
				
			||||||
      "version": "0.5.74",
 | 
					      "version": "0.5.76",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.74.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.76.tgz",
 | 
				
			||||||
      "integrity": "sha512-pA7dxA0lKn9w/2Sc97oxnn+CEzL1SrT9XriNLTDF4Xp+2SBEpGcfbqbdR9ljPQJopIbrc9Zy02R+uBQVomcwyA=="
 | 
					      "integrity": "sha512-0gX3NTWaxFyzUmqBSUHhPY8pMRX92iXQFqoBuMQlMG1+6uC6JMKtwP5t8cuXR3pvV2vkaCi/cDWjP1JUChkZ9g=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/warframe-riven-info": {
 | 
					    "node_modules/warframe-riven-info": {
 | 
				
			||||||
      "version": "0.1.2",
 | 
					      "version": "0.1.2",
 | 
				
			||||||
 | 
				
			|||||||
@ -37,7 +37,7 @@
 | 
				
			|||||||
    "ncp": "^2.0.0",
 | 
					    "ncp": "^2.0.0",
 | 
				
			||||||
    "typescript": "^5.5",
 | 
					    "typescript": "^5.5",
 | 
				
			||||||
    "undici": "^7.10.0",
 | 
					    "undici": "^7.10.0",
 | 
				
			||||||
    "warframe-public-export-plus": "^0.5.74",
 | 
					    "warframe-public-export-plus": "^0.5.76",
 | 
				
			||||||
    "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",
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@ import {
 | 
				
			|||||||
    getGuildVault,
 | 
					    getGuildVault,
 | 
				
			||||||
    hasAccessToDojo,
 | 
					    hasAccessToDojo,
 | 
				
			||||||
    hasGuildPermission,
 | 
					    hasGuildPermission,
 | 
				
			||||||
 | 
					    processCompletedGuildTechProject,
 | 
				
			||||||
    processFundedGuildTechProject,
 | 
					    processFundedGuildTechProject,
 | 
				
			||||||
    processGuildTechProjectContributionsUpdate,
 | 
					    processGuildTechProjectContributionsUpdate,
 | 
				
			||||||
    removePigmentsFromGuildMembers,
 | 
					    removePigmentsFromGuildMembers,
 | 
				
			||||||
@ -51,8 +52,12 @@ export const guildTechController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
                };
 | 
					                };
 | 
				
			||||||
                if (project.CompletionDate) {
 | 
					                if (project.CompletionDate) {
 | 
				
			||||||
                    techProject.CompletionDate = toMongoDate(project.CompletionDate);
 | 
					                    techProject.CompletionDate = toMongoDate(project.CompletionDate);
 | 
				
			||||||
                    if (Date.now() >= project.CompletionDate.getTime()) {
 | 
					                    if (
 | 
				
			||||||
                        needSave ||= setGuildTechLogState(guild, project.ItemType, 4, project.CompletionDate);
 | 
					                        Date.now() >= project.CompletionDate.getTime() &&
 | 
				
			||||||
 | 
					                        setGuildTechLogState(guild, project.ItemType, 4, project.CompletionDate)
 | 
				
			||||||
 | 
					                    ) {
 | 
				
			||||||
 | 
					                        processCompletedGuildTechProject(guild, project.ItemType);
 | 
				
			||||||
 | 
					                        needSave = true;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                techProjects.push(techProject);
 | 
					                techProjects.push(techProject);
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ import { IPolarity, ArtifactPolarity, EquipmentFeatures } from "@/src/types/inve
 | 
				
			|||||||
import { ExportCustoms, ExportFlavour, ExportResources, ExportVirtuals } from "warframe-public-export-plus";
 | 
					import { ExportCustoms, ExportFlavour, ExportResources, ExportVirtuals } from "warframe-public-export-plus";
 | 
				
			||||||
import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "@/src/services/infestedFoundryService";
 | 
					import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "@/src/services/infestedFoundryService";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					    addEmailItem,
 | 
				
			||||||
    addMiscItems,
 | 
					    addMiscItems,
 | 
				
			||||||
    allDailyAffiliationKeys,
 | 
					    allDailyAffiliationKeys,
 | 
				
			||||||
    cleanupInventory,
 | 
					    cleanupInventory,
 | 
				
			||||||
@ -110,7 +111,58 @@ export const inventoryController: RequestHandler = async (request, response) =>
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (inventory.CalendarProgress) {
 | 
					        if (inventory.CalendarProgress) {
 | 
				
			||||||
 | 
					            const previousYearIteration = inventory.CalendarProgress.Iteration;
 | 
				
			||||||
            getCalendarProgress(inventory); // handle year rollover; the client expects to receive an inventory with an up-to-date CalendarProgress
 | 
					            getCalendarProgress(inventory); // handle year rollover; the client expects to receive an inventory with an up-to-date CalendarProgress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // also handle sending of kiss cinematic at year rollover
 | 
				
			||||||
 | 
					            if (
 | 
				
			||||||
 | 
					                inventory.CalendarProgress.Iteration != previousYearIteration &&
 | 
				
			||||||
 | 
					                inventory.DialogueHistory &&
 | 
				
			||||||
 | 
					                inventory.DialogueHistory.Dialogues
 | 
				
			||||||
 | 
					            ) {
 | 
				
			||||||
 | 
					                let kalymos = false;
 | 
				
			||||||
 | 
					                for (const { dialogueName, kissEmail } of [
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/ArthurDialogue_rom.dialogue",
 | 
				
			||||||
 | 
					                        kissEmail: "/Lotus/Types/Items/EmailItems/ArthurKissEmailItem"
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/EleanorDialogue_rom.dialogue",
 | 
				
			||||||
 | 
					                        kissEmail: "/Lotus/Types/Items/EmailItems/EleanorKissEmailItem"
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/LettieDialogue_rom.dialogue",
 | 
				
			||||||
 | 
					                        kissEmail: "/Lotus/Types/Items/EmailItems/LettieKissEmailItem"
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/JabirDialogue_rom.dialogue",
 | 
				
			||||||
 | 
					                        kissEmail: "/Lotus/Types/Items/EmailItems/AmirKissEmailItem"
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/AoiDialogue_rom.dialogue",
 | 
				
			||||||
 | 
					                        kissEmail: "/Lotus/Types/Items/EmailItems/AoiKissEmailItem"
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        dialogueName: "/Lotus/Types/Gameplay/1999Wf/Dialogue/QuincyDialogue_rom.dialogue",
 | 
				
			||||||
 | 
					                        kissEmail: "/Lotus/Types/Items/EmailItems/QuincyKissEmailItem"
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                ]) {
 | 
				
			||||||
 | 
					                    const dialogue = inventory.DialogueHistory.Dialogues.find(x => x.DialogueName == dialogueName);
 | 
				
			||||||
 | 
					                    if (dialogue) {
 | 
				
			||||||
 | 
					                        if (dialogue.Rank == 7) {
 | 
				
			||||||
 | 
					                            await addEmailItem(inventory, kissEmail);
 | 
				
			||||||
 | 
					                            kalymos = false;
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        if (dialogue.Rank == 6) {
 | 
				
			||||||
 | 
					                            kalymos = true;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (kalymos) {
 | 
				
			||||||
 | 
					                    await addEmailItem(inventory, "/Lotus/Types/Items/EmailItems/KalymosKissEmailItem");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cleanupInventory(inventory);
 | 
					        cleanupInventory(inventory);
 | 
				
			||||||
 | 
				
			|||||||
@ -48,10 +48,8 @@ export const loginRewardsController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
        response.DailyTributeInfo.HasChosenReward = true;
 | 
					        response.DailyTributeInfo.HasChosenReward = true;
 | 
				
			||||||
        response.DailyTributeInfo.ChosenReward = randomRewards[0];
 | 
					        response.DailyTributeInfo.ChosenReward = randomRewards[0];
 | 
				
			||||||
        response.DailyTributeInfo.NewInventory = await claimLoginReward(inventory, randomRewards[0]);
 | 
					        response.DailyTributeInfo.NewInventory = await claimLoginReward(inventory, randomRewards[0]);
 | 
				
			||||||
        await inventory.save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        setAccountGotLoginRewardToday(account);
 | 
					        setAccountGotLoginRewardToday(account);
 | 
				
			||||||
        await account.save();
 | 
					        await Promise.all([inventory.save(), account.save()]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        sendWsBroadcastTo(account._id.toString(), { update_inventory: true });
 | 
					        sendWsBroadcastTo(account._id.toString(), { update_inventory: true });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -35,10 +35,8 @@ export const loginRewardsSelectionController: RequestHandler = async (req, res)
 | 
				
			|||||||
        chosenReward = randomRewards.find(x => x.StoreItemType == body.ChosenReward)!;
 | 
					        chosenReward = randomRewards.find(x => x.StoreItemType == body.ChosenReward)!;
 | 
				
			||||||
        inventoryChanges = await claimLoginReward(inventory, chosenReward);
 | 
					        inventoryChanges = await claimLoginReward(inventory, chosenReward);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    await inventory.save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    setAccountGotLoginRewardToday(account);
 | 
					    setAccountGotLoginRewardToday(account);
 | 
				
			||||||
    await account.save();
 | 
					    await Promise.all([inventory.save(), account.save()]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sendWsBroadcastTo(account._id.toString(), { update_inventory: true });
 | 
					    sendWsBroadcastTo(account._id.toString(), { update_inventory: true });
 | 
				
			||||||
    res.json({
 | 
					    res.json({
 | 
				
			||||||
 | 
				
			|||||||
@ -57,8 +57,12 @@ export const placeDecoInComponentController: RequestHandler = async (req, res) =
 | 
				
			|||||||
                component.DecoCapacity -= meta.capacityCost;
 | 
					                component.DecoCapacity -= meta.capacityCost;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            const [itemType, meta] = Object.entries(ExportResources).find(arr => arr[1].deco == deco.Type)!;
 | 
					            const entry = Object.entries(ExportResources).find(arr => arr[1].deco == deco.Type);
 | 
				
			||||||
            if (!itemType || meta.dojoCapacityCost === undefined) {
 | 
					            if (!entry) {
 | 
				
			||||||
 | 
					                throw new Error(`unknown deco type: ${deco.Type}`);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            const [itemType, meta] = entry;
 | 
				
			||||||
 | 
					            if (meta.dojoCapacityCost === undefined) {
 | 
				
			||||||
                throw new Error(`unknown deco type: ${deco.Type}`);
 | 
					                throw new Error(`unknown deco type: ${deco.Type}`);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            component.DecoCapacity -= meta.dojoCapacityCost;
 | 
					            component.DecoCapacity -= meta.dojoCapacityCost;
 | 
				
			||||||
@ -75,7 +79,13 @@ export const placeDecoInComponentController: RequestHandler = async (req, res) =
 | 
				
			|||||||
                if (meta) {
 | 
					                if (meta) {
 | 
				
			||||||
                    processDojoBuildMaterialsGathered(guild, meta);
 | 
					                    processDojoBuildMaterialsGathered(guild, meta);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else if (guild.AutoContributeFromVault && guild.VaultRegularCredits && guild.VaultMiscItems) {
 | 
					            } else if (
 | 
				
			||||||
 | 
					                deco.Type.startsWith("/Lotus/Objects/Tenno/Dojo/NpcPlaceables/") ||
 | 
				
			||||||
 | 
					                (guild.AutoContributeFromVault && guild.VaultRegularCredits && guild.VaultMiscItems)
 | 
				
			||||||
 | 
					            ) {
 | 
				
			||||||
 | 
					                if (!guild.VaultRegularCredits || !guild.VaultMiscItems) {
 | 
				
			||||||
 | 
					                    throw new Error(`dojo visitor placed without anything in vault?!`);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                if (guild.VaultRegularCredits >= scaleRequiredCount(guild.Tier, meta.price)) {
 | 
					                if (guild.VaultRegularCredits >= scaleRequiredCount(guild.Tier, meta.price)) {
 | 
				
			||||||
                    let enoughMiscItems = true;
 | 
					                    let enoughMiscItems = true;
 | 
				
			||||||
                    for (const ingredient of meta.ingredients) {
 | 
					                    for (const ingredient of meta.ingredients) {
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@ import { sendWsBroadcastTo } from "@/src/services/webService";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const sellController: RequestHandler = async (req, res) => {
 | 
					export const sellController: RequestHandler = async (req, res) => {
 | 
				
			||||||
    const payload = JSON.parse(String(req.body)) as ISellRequest;
 | 
					    const payload = JSON.parse(String(req.body)) as ISellRequest;
 | 
				
			||||||
 | 
					    //console.log(JSON.stringify(payload, null, 2));
 | 
				
			||||||
    const accountId = await getAccountIdForRequest(req);
 | 
					    const accountId = await getAccountIdForRequest(req);
 | 
				
			||||||
    const requiredFields = new Set<keyof TInventoryDatabaseDocument>();
 | 
					    const requiredFields = new Set<keyof TInventoryDatabaseDocument>();
 | 
				
			||||||
    if (payload.SellCurrency == "SC_RegularCredits") {
 | 
					    if (payload.SellCurrency == "SC_RegularCredits") {
 | 
				
			||||||
@ -184,6 +185,11 @@ export const sellController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
            inventory.Drones.pull({ _id: sellItem.String });
 | 
					            inventory.Drones.pull({ _id: sellItem.String });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (payload.Items.KubrowPetPrints) {
 | 
				
			||||||
 | 
					        payload.Items.KubrowPetPrints.forEach(sellItem => {
 | 
				
			||||||
 | 
					            inventory.KubrowPetPrints.pull({ _id: sellItem.String });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (payload.Items.CrewMembers) {
 | 
					    if (payload.Items.CrewMembers) {
 | 
				
			||||||
        payload.Items.CrewMembers.forEach(sellItem => {
 | 
					        payload.Items.CrewMembers.forEach(sellItem => {
 | 
				
			||||||
            inventory.CrewMembers.pull({ _id: sellItem.String });
 | 
					            inventory.CrewMembers.pull({ _id: sellItem.String });
 | 
				
			||||||
@ -312,6 +318,7 @@ interface ISellRequest {
 | 
				
			|||||||
        OperatorAmps?: ISellItem[];
 | 
					        OperatorAmps?: ISellItem[];
 | 
				
			||||||
        Hoverboards?: ISellItem[];
 | 
					        Hoverboards?: ISellItem[];
 | 
				
			||||||
        Drones?: ISellItem[];
 | 
					        Drones?: ISellItem[];
 | 
				
			||||||
 | 
					        KubrowPetPrints?: ISellItem[];
 | 
				
			||||||
        CrewMembers?: ISellItem[];
 | 
					        CrewMembers?: ISellItem[];
 | 
				
			||||||
        CrewShipWeapons?: ISellItem[];
 | 
					        CrewShipWeapons?: ISellItem[];
 | 
				
			||||||
        CrewShipWeaponSkins?: ISellItem[];
 | 
					        CrewShipWeaponSkins?: ISellItem[];
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@ import { logger } from "@/src/utils/logger";
 | 
				
			|||||||
import { addMiscItems, combineInventoryChanges } from "@/src/services/inventoryService";
 | 
					import { addMiscItems, combineInventoryChanges } from "@/src/services/inventoryService";
 | 
				
			||||||
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
 | 
					import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
 | 
				
			||||||
import { IInventoryChanges } from "../types/purchaseTypes";
 | 
					import { IInventoryChanges } from "../types/purchaseTypes";
 | 
				
			||||||
 | 
					import { config } from "../services/configService";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const crackRelic = async (
 | 
					export const crackRelic = async (
 | 
				
			||||||
    inventory: TInventoryDatabaseDocument,
 | 
					    inventory: TInventoryDatabaseDocument,
 | 
				
			||||||
@ -35,7 +36,13 @@ export const crackRelic = async (
 | 
				
			|||||||
    // Give reward
 | 
					    // Give reward
 | 
				
			||||||
    combineInventoryChanges(
 | 
					    combineInventoryChanges(
 | 
				
			||||||
        inventoryChanges,
 | 
					        inventoryChanges,
 | 
				
			||||||
        (await handleStoreItemAcquisition(reward.type, inventory, reward.itemCount)).InventoryChanges
 | 
					        (
 | 
				
			||||||
 | 
					            await handleStoreItemAcquisition(
 | 
				
			||||||
 | 
					                reward.type,
 | 
				
			||||||
 | 
					                inventory,
 | 
				
			||||||
 | 
					                reward.itemCount * (config.relicRewardItemCountMultiplier ?? 1)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        ).InventoryChanges
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return reward;
 | 
					    return reward;
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,9 @@ export interface IMessageDatabase extends IMessage {
 | 
				
			|||||||
export interface IMessage {
 | 
					export interface IMessage {
 | 
				
			||||||
    sndr: string;
 | 
					    sndr: string;
 | 
				
			||||||
    msg: string;
 | 
					    msg: string;
 | 
				
			||||||
 | 
					    cinematic?: string;
 | 
				
			||||||
    sub: string;
 | 
					    sub: string;
 | 
				
			||||||
 | 
					    customData?: string;
 | 
				
			||||||
    icon?: string;
 | 
					    icon?: string;
 | 
				
			||||||
    highPriority?: boolean;
 | 
					    highPriority?: boolean;
 | 
				
			||||||
    lowPrioNewPlayers?: boolean;
 | 
					    lowPrioNewPlayers?: boolean;
 | 
				
			||||||
@ -102,7 +104,9 @@ const messageSchema = new Schema<IMessageDatabase>(
 | 
				
			|||||||
        ownerId: Schema.Types.ObjectId,
 | 
					        ownerId: Schema.Types.ObjectId,
 | 
				
			||||||
        sndr: String,
 | 
					        sndr: String,
 | 
				
			||||||
        msg: String,
 | 
					        msg: String,
 | 
				
			||||||
 | 
					        cinematic: String,
 | 
				
			||||||
        sub: String,
 | 
					        sub: String,
 | 
				
			||||||
 | 
					        customData: String,
 | 
				
			||||||
        icon: String,
 | 
					        icon: String,
 | 
				
			||||||
        highPriority: Boolean,
 | 
					        highPriority: Boolean,
 | 
				
			||||||
        lowPrioNewPlayers: Boolean,
 | 
					        lowPrioNewPlayers: Boolean,
 | 
				
			||||||
 | 
				
			|||||||
@ -67,6 +67,7 @@ export interface IConfig {
 | 
				
			|||||||
    unlockAllSimarisResearchEntries?: boolean;
 | 
					    unlockAllSimarisResearchEntries?: boolean;
 | 
				
			||||||
    disableDailyTribute?: boolean;
 | 
					    disableDailyTribute?: boolean;
 | 
				
			||||||
    spoofMasteryRank?: number;
 | 
					    spoofMasteryRank?: number;
 | 
				
			||||||
 | 
					    relicRewardItemCountMultiplier?: number;
 | 
				
			||||||
    nightwaveStandingMultiplier?: number;
 | 
					    nightwaveStandingMultiplier?: number;
 | 
				
			||||||
    unfaithfulBugFixes?: {
 | 
					    unfaithfulBugFixes?: {
 | 
				
			||||||
        ignore1999LastRegionPlayed?: boolean;
 | 
					        ignore1999LastRegionPlayed?: boolean;
 | 
				
			||||||
 | 
				
			|||||||
@ -550,6 +550,19 @@ export const processFundedGuildTechProject = (
 | 
				
			|||||||
        guild.XP += recipe.guildXpValue;
 | 
					        guild.XP += recipe.guildXpValue;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    setGuildTechLogState(guild, techProject.ItemType, config.noDojoResearchTime ? 4 : 3, techProject.CompletionDate);
 | 
					    setGuildTechLogState(guild, techProject.ItemType, config.noDojoResearchTime ? 4 : 3, techProject.CompletionDate);
 | 
				
			||||||
 | 
					    if (config.noDojoResearchTime) {
 | 
				
			||||||
 | 
					        processCompletedGuildTechProject(guild, techProject.ItemType);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const processCompletedGuildTechProject = (guild: TGuildDatabaseDocument, type: string): void => {
 | 
				
			||||||
 | 
					    if (type.startsWith("/Lotus/Levels/ClanDojo/ComponentPropRecipes/NpcPlaceables/")) {
 | 
				
			||||||
 | 
					        guild.VaultDecoRecipes ??= [];
 | 
				
			||||||
 | 
					        guild.VaultDecoRecipes.push({
 | 
				
			||||||
 | 
					            ItemType: type,
 | 
				
			||||||
 | 
					            ItemCount: 1
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const setGuildTechLogState = (
 | 
					export const setGuildTechLogState = (
 | 
				
			||||||
 | 
				
			|||||||
@ -83,7 +83,7 @@ import { addQuestKey, completeQuest } from "@/src/services/questService";
 | 
				
			|||||||
import { handleBundleAcqusition } from "./purchaseService";
 | 
					import { handleBundleAcqusition } from "./purchaseService";
 | 
				
			||||||
import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
 | 
					import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
 | 
				
			||||||
import { getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from "./rngService";
 | 
					import { getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from "./rngService";
 | 
				
			||||||
import { createMessage } from "./inboxService";
 | 
					import { createMessage, IMessageCreationTemplate } from "./inboxService";
 | 
				
			||||||
import { getMaxStanding, getMinStanding } from "@/src/helpers/syndicateStandingHelper";
 | 
					import { getMaxStanding, getMinStanding } from "@/src/helpers/syndicateStandingHelper";
 | 
				
			||||||
import { getNightwaveSyndicateTag, getWorldState } from "./worldStateService";
 | 
					import { getNightwaveSyndicateTag, getWorldState } from "./worldStateService";
 | 
				
			||||||
import { ICalendarSeason } from "@/src/types/worldStateTypes";
 | 
					import { ICalendarSeason } from "@/src/types/worldStateTypes";
 | 
				
			||||||
@ -1563,7 +1563,22 @@ export const addEmailItem = async (
 | 
				
			|||||||
    const meta = ExportEmailItems[typeName];
 | 
					    const meta = ExportEmailItems[typeName];
 | 
				
			||||||
    const emailItem = inventory.EmailItems.find(x => x.ItemType == typeName);
 | 
					    const emailItem = inventory.EmailItems.find(x => x.ItemType == typeName);
 | 
				
			||||||
    if (!emailItem || !meta.sendOnlyOnce) {
 | 
					    if (!emailItem || !meta.sendOnlyOnce) {
 | 
				
			||||||
        await createMessage(inventory.accountOwnerId, [convertInboxMessage(meta.message)]);
 | 
					        const msg: IMessageCreationTemplate = convertInboxMessage(meta.message);
 | 
				
			||||||
 | 
					        if (msg.cinematic == "/Lotus/Levels/1999/PlayerHomeBalconyCinematics.level") {
 | 
				
			||||||
 | 
					            msg.customData = JSON.stringify({
 | 
				
			||||||
 | 
					                Tag: msg.customData + "KissCin",
 | 
				
			||||||
 | 
					                CinLoadout: {
 | 
				
			||||||
 | 
					                    Skins: inventory.AdultOperatorLoadOuts[0].Skins,
 | 
				
			||||||
 | 
					                    Upgrades: inventory.AdultOperatorLoadOuts[0].Upgrades,
 | 
				
			||||||
 | 
					                    attcol: inventory.AdultOperatorLoadOuts[0].attcol,
 | 
				
			||||||
 | 
					                    cloth: inventory.AdultOperatorLoadOuts[0].cloth,
 | 
				
			||||||
 | 
					                    eyecol: inventory.AdultOperatorLoadOuts[0].eyecol,
 | 
				
			||||||
 | 
					                    pricol: inventory.AdultOperatorLoadOuts[0].pricol,
 | 
				
			||||||
 | 
					                    syancol: inventory.AdultOperatorLoadOuts[0].syancol
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        await createMessage(inventory.accountOwnerId, [msg]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (emailItem) {
 | 
					        if (emailItem) {
 | 
				
			||||||
            emailItem.ItemCount += 1;
 | 
					            emailItem.ItemCount += 1;
 | 
				
			||||||
 | 
				
			|||||||
@ -251,7 +251,9 @@ export const convertInboxMessage = (message: IInboxMessage): IMessage => {
 | 
				
			|||||||
    return {
 | 
					    return {
 | 
				
			||||||
        sndr: message.sender,
 | 
					        sndr: message.sender,
 | 
				
			||||||
        msg: message.body,
 | 
					        msg: message.body,
 | 
				
			||||||
 | 
					        cinematic: message.cinematic,
 | 
				
			||||||
        sub: message.title,
 | 
					        sub: message.title,
 | 
				
			||||||
 | 
					        customData: message.customData,
 | 
				
			||||||
        att: message.attachments.length > 0 ? message.attachments : undefined,
 | 
					        att: message.attachments.length > 0 ? message.attachments : undefined,
 | 
				
			||||||
        countedAtt: message.countedAttachments.length > 0 ? message.countedAttachments : undefined,
 | 
					        countedAtt: message.countedAttachments.length > 0 ? message.countedAttachments : undefined,
 | 
				
			||||||
        icon: message.icon ?? "",
 | 
					        icon: message.icon ?? "",
 | 
				
			||||||
 | 
				
			|||||||
@ -167,8 +167,13 @@ export const handleInventoryItemConfigChange = async (
 | 
				
			|||||||
                inventory.LotusCustomization = equipmentChanges.LotusCustomization;
 | 
					                inventory.LotusCustomization = equipmentChanges.LotusCustomization;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            case "ValidNewLoadoutId": {
 | 
				
			||||||
 | 
					                logger.debug(`ignoring ValidNewLoadoutId (${equipmentChanges.ValidNewLoadoutId})`);
 | 
				
			||||||
 | 
					                // seems always equal to the id of loadout config NORMAL[0], likely has no purpose and we're free to ignore it
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            default: {
 | 
					            default: {
 | 
				
			||||||
                if (equipmentKeys.includes(equipmentName as TEquipmentKey) && equipmentName != "ValidNewLoadoutId") {
 | 
					                if (equipmentKeys.includes(equipmentName as TEquipmentKey)) {
 | 
				
			||||||
                    logger.debug(`general Item config saved of type ${equipmentName}`, {
 | 
					                    logger.debug(`general Item config saved of type ${equipmentName}`, {
 | 
				
			||||||
                        config: equipment
 | 
					                        config: equipment
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
@ -216,7 +221,7 @@ export const handleInventoryItemConfigChange = async (
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    logger.warn(`loadout category not implemented, changes may be lost: ${equipmentName}`, {
 | 
					                    logger.error(`loadout category not implemented, changes will be lost: ${equipmentName}`, {
 | 
				
			||||||
                        config: equipment
 | 
					                        config: equipment
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
				
			|||||||
@ -64,8 +64,12 @@ export const handleSetShipDecorations = async (
 | 
				
			|||||||
        throw new Error(`unknown room: ${placedDecoration.Room}`);
 | 
					        throw new Error(`unknown room: ${placedDecoration.Room}`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const [itemType, meta] = Object.entries(ExportResources).find(arr => arr[1].deco == placedDecoration.Type)!;
 | 
					    const entry = Object.entries(ExportResources).find(arr => arr[1].deco == placedDecoration.Type);
 | 
				
			||||||
    if (!itemType || meta.capacityCost === undefined) {
 | 
					    if (!entry) {
 | 
				
			||||||
 | 
					        throw new Error(`unknown deco type: ${placedDecoration.Type}`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const [itemType, meta] = entry;
 | 
				
			||||||
 | 
					    if (meta.capacityCost === undefined) {
 | 
				
			||||||
        throw new Error(`unknown deco type: ${placedDecoration.Type}`);
 | 
					        throw new Error(`unknown deco type: ${placedDecoration.Type}`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -92,5 +92,13 @@
 | 
				
			|||||||
  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/ThumperTrophySilverRecipe",
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/ThumperTrophySilverRecipe",
 | 
				
			||||||
  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/CorpusPlaceables/GasTurbineConeRecipe",
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/CorpusPlaceables/GasTurbineConeRecipe",
 | 
				
			||||||
  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/NaturalPlaceables/CoralChunkARecipe",
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/NaturalPlaceables/CoralChunkARecipe",
 | 
				
			||||||
  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/TennoPlaceables/TnoBeaconEmitterRecipe"
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/TennoPlaceables/TnoBeaconEmitterRecipe",
 | 
				
			||||||
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/NpcPlaceables/OstronFemaleSitting",
 | 
				
			||||||
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/NpcPlaceables/OstronFemaleStanding",
 | 
				
			||||||
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/NpcPlaceables/OstronMaleStanding",
 | 
				
			||||||
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/NpcPlaceables/OstronMaleStandingTwo",
 | 
				
			||||||
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/NpcPlaceables/SolarisForeman",
 | 
				
			||||||
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/NpcPlaceables/SolarisHazard",
 | 
				
			||||||
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/NpcPlaceables/SolarisStrikerOne",
 | 
				
			||||||
 | 
					  "/Lotus/Levels/ClanDojo/ComponentPropRecipes/NpcPlaceables/SolarisStrikerThree"
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
				
			|||||||
@ -546,6 +546,7 @@
 | 
				
			|||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div data-route="/webui/quests" data-title="Quests | OpenWF WebUI">
 | 
					            <div data-route="/webui/quests" data-title="Quests | OpenWF WebUI">
 | 
				
			||||||
 | 
					                <p class="mb-3" data-loc="general_inventoryUpdateNote"></p>
 | 
				
			||||||
                <div class="row g-3">
 | 
					                <div class="row g-3">
 | 
				
			||||||
                    <div class="col-md-6">
 | 
					                    <div class="col-md-6">
 | 
				
			||||||
                        <div class="card">
 | 
					                        <div class="card">
 | 
				
			||||||
@ -788,14 +789,21 @@
 | 
				
			|||||||
                                    <form class="form-group mt-2" onsubmit="doSaveConfigInt('spoofMasteryRank'); return false;">
 | 
					                                    <form class="form-group mt-2" onsubmit="doSaveConfigInt('spoofMasteryRank'); return false;">
 | 
				
			||||||
                                        <label class="form-label" for="spoofMasteryRank" data-loc="cheats_spoofMasteryRank"></label>
 | 
					                                        <label class="form-label" for="spoofMasteryRank" data-loc="cheats_spoofMasteryRank"></label>
 | 
				
			||||||
                                        <div class="input-group">
 | 
					                                        <div class="input-group">
 | 
				
			||||||
                                            <input class="form-control" id="spoofMasteryRank" type="number" min="-1" max="65535" />
 | 
					                                            <input class="form-control" id="spoofMasteryRank" type="number" min="-1" max="65535" data-default="-1" />
 | 
				
			||||||
 | 
					                                            <button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
 | 
				
			||||||
 | 
					                                        </div>
 | 
				
			||||||
 | 
					                                    </form>
 | 
				
			||||||
 | 
					                                    <form class="form-group mt-2" onsubmit="doSaveConfigInt('relicRewardItemCountMultiplier'); return false;">
 | 
				
			||||||
 | 
					                                        <label class="form-label" for="relicRewardItemCountMultiplier" data-loc="cheats_relicRewardItemCountMultiplier"></label>
 | 
				
			||||||
 | 
					                                        <div class="input-group">
 | 
				
			||||||
 | 
					                                            <input class="form-control" id="relicRewardItemCountMultiplier" type="number" min="1" max="1000000" data-default="1" />
 | 
				
			||||||
                                            <button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
 | 
					                                            <button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
 | 
				
			||||||
                                        </div>
 | 
					                                        </div>
 | 
				
			||||||
                                    </form>
 | 
					                                    </form>
 | 
				
			||||||
                                    <form class="form-group mt-2" onsubmit="doSaveConfigInt('nightwaveStandingMultiplier'); return false;">
 | 
					                                    <form class="form-group mt-2" onsubmit="doSaveConfigInt('nightwaveStandingMultiplier'); return false;">
 | 
				
			||||||
                                        <label class="form-label" for="nightwaveStandingMultiplier" data-loc="cheats_nightwaveStandingMultiplier"></label>
 | 
					                                        <label class="form-label" for="nightwaveStandingMultiplier" data-loc="cheats_nightwaveStandingMultiplier"></label>
 | 
				
			||||||
                                        <div class="input-group">
 | 
					                                        <div class="input-group">
 | 
				
			||||||
                                            <input class="form-control" id="nightwaveStandingMultiplier" type="number" min="1" max="1000000" value="1" />
 | 
					                                            <input class="form-control" id="nightwaveStandingMultiplier" type="number" min="1" max="1000000" data-default="1" />
 | 
				
			||||||
                                            <button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
 | 
					                                            <button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
 | 
				
			||||||
                                        </div>
 | 
					                                        </div>
 | 
				
			||||||
                                    </form>
 | 
					                                    </form>
 | 
				
			||||||
@ -919,7 +927,7 @@
 | 
				
			|||||||
                                <form class="form-group mt-2" onsubmit="doSaveConfigFloat('worldState.darvoStockMultiplier'); return false;">
 | 
					                                <form class="form-group mt-2" onsubmit="doSaveConfigFloat('worldState.darvoStockMultiplier'); return false;">
 | 
				
			||||||
                                    <label class="form-label" for="worldState.circuitGameModes" data-loc="worldState_darvoStockMultiplier"></label>
 | 
					                                    <label class="form-label" for="worldState.circuitGameModes" data-loc="worldState_darvoStockMultiplier"></label>
 | 
				
			||||||
                                    <div class="input-group">
 | 
					                                    <div class="input-group">
 | 
				
			||||||
                                        <input id="worldState.darvoStockMultiplier" class="form-control" type="number" step="0.01" placeholder="1" />
 | 
					                                        <input id="worldState.darvoStockMultiplier" class="form-control" type="number" step="0.01" data-default="1" />
 | 
				
			||||||
                                        <button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
 | 
					                                        <button class="btn btn-primary" type="submit" data-loc="cheats_save"></button>
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                </form>
 | 
					                                </form>
 | 
				
			||||||
 | 
				
			|||||||
@ -1984,16 +1984,14 @@ single.getRoute("/webui/cheats").on("beforeload", function () {
 | 
				
			|||||||
                    $(".config-admin-show").removeClass("d-none");
 | 
					                    $(".config-admin-show").removeClass("d-none");
 | 
				
			||||||
                    Object.entries(json).forEach(entry => {
 | 
					                    Object.entries(json).forEach(entry => {
 | 
				
			||||||
                        const [key, value] = entry;
 | 
					                        const [key, value] = entry;
 | 
				
			||||||
                        var x = document.getElementById(`${key}`);
 | 
					                        const elm = document.getElementById(key);
 | 
				
			||||||
                        if (x != null) {
 | 
					                        if (elm.type == "checkbox") {
 | 
				
			||||||
                            if (x.type == "checkbox") {
 | 
					                            elm.checked = value;
 | 
				
			||||||
                                x.checked = value;
 | 
					                        } else if (elm.classList.contains("tags-input")) {
 | 
				
			||||||
                            } else if (x.classList.contains("tags-input")) {
 | 
					                            elm.value = value.join(", ");
 | 
				
			||||||
                                x.value = value.join(", ");
 | 
					                            elm.oninput();
 | 
				
			||||||
                                x.oninput();
 | 
					 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                                x.value = value;
 | 
					                            elm.value = value ?? elm.getAttribute("data-default");
 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
 | 
				
			|||||||
@ -185,6 +185,7 @@ dict = {
 | 
				
			|||||||
    cheats_unlockAllSimarisResearchEntries: `[UNTRANSLATED] Unlock All Simaris Research Entries`,
 | 
					    cheats_unlockAllSimarisResearchEntries: `[UNTRANSLATED] Unlock All Simaris Research Entries`,
 | 
				
			||||||
    cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
 | 
					    cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
 | 
				
			||||||
    cheats_spoofMasteryRank: `Gefälschter Meisterschaftsrang (-1 zum deaktivieren)`,
 | 
					    cheats_spoofMasteryRank: `Gefälschter Meisterschaftsrang (-1 zum deaktivieren)`,
 | 
				
			||||||
 | 
					    cheats_relicRewardItemCountMultiplier: `[UNTRANSLATED] Relic Reward Item Count Multiplier`,
 | 
				
			||||||
    cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
 | 
					    cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
 | 
				
			||||||
    cheats_save: `[UNTRANSLATED] Save`,
 | 
					    cheats_save: `[UNTRANSLATED] Save`,
 | 
				
			||||||
    cheats_account: `Account`,
 | 
					    cheats_account: `Account`,
 | 
				
			||||||
 | 
				
			|||||||
@ -184,6 +184,7 @@ dict = {
 | 
				
			|||||||
    cheats_unlockAllSimarisResearchEntries: `Unlock All Simaris Research Entries`,
 | 
					    cheats_unlockAllSimarisResearchEntries: `Unlock All Simaris Research Entries`,
 | 
				
			||||||
    cheats_disableDailyTribute: `Disable Daily Tribute`,
 | 
					    cheats_disableDailyTribute: `Disable Daily Tribute`,
 | 
				
			||||||
    cheats_spoofMasteryRank: `Spoofed Mastery Rank (-1 to disable)`,
 | 
					    cheats_spoofMasteryRank: `Spoofed Mastery Rank (-1 to disable)`,
 | 
				
			||||||
 | 
					    cheats_relicRewardItemCountMultiplier: `Relic Reward Item Count Multiplier`,
 | 
				
			||||||
    cheats_nightwaveStandingMultiplier: `Nightwave Standing Multiplier`,
 | 
					    cheats_nightwaveStandingMultiplier: `Nightwave Standing Multiplier`,
 | 
				
			||||||
    cheats_save: `Save`,
 | 
					    cheats_save: `Save`,
 | 
				
			||||||
    cheats_account: `Account`,
 | 
					    cheats_account: `Account`,
 | 
				
			||||||
 | 
				
			|||||||
@ -185,6 +185,7 @@ dict = {
 | 
				
			|||||||
    cheats_unlockAllSimarisResearchEntries: `Desbloquear todas las entradas de investigación de Simaris`,
 | 
					    cheats_unlockAllSimarisResearchEntries: `Desbloquear todas las entradas de investigación de Simaris`,
 | 
				
			||||||
    cheats_disableDailyTribute: `Desactivar tributo diario`,
 | 
					    cheats_disableDailyTribute: `Desactivar tributo diario`,
 | 
				
			||||||
    cheats_spoofMasteryRank: `Rango de maestría simulado (-1 para desactivar)`,
 | 
					    cheats_spoofMasteryRank: `Rango de maestría simulado (-1 para desactivar)`,
 | 
				
			||||||
 | 
					    cheats_relicRewardItemCountMultiplier: `[UNTRANSLATED] Relic Reward Item Count Multiplier`,
 | 
				
			||||||
    cheats_nightwaveStandingMultiplier: `Multiplicador de Reputación de Onda Nocturna`,
 | 
					    cheats_nightwaveStandingMultiplier: `Multiplicador de Reputación de Onda Nocturna`,
 | 
				
			||||||
    cheats_save: `Guardar`,
 | 
					    cheats_save: `Guardar`,
 | 
				
			||||||
    cheats_account: `Cuenta`,
 | 
					    cheats_account: `Cuenta`,
 | 
				
			||||||
 | 
				
			|||||||
@ -185,6 +185,7 @@ dict = {
 | 
				
			|||||||
    cheats_unlockAllSimarisResearchEntries: `Débloquer toute les recherches chez Simaris`,
 | 
					    cheats_unlockAllSimarisResearchEntries: `Débloquer toute les recherches chez Simaris`,
 | 
				
			||||||
    cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
 | 
					    cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
 | 
				
			||||||
    cheats_spoofMasteryRank: `Rang de maîtrise personnalisé (-1 pour désactiver)`,
 | 
					    cheats_spoofMasteryRank: `Rang de maîtrise personnalisé (-1 pour désactiver)`,
 | 
				
			||||||
 | 
					    cheats_relicRewardItemCountMultiplier: `[UNTRANSLATED] Relic Reward Item Count Multiplier`,
 | 
				
			||||||
    cheats_nightwaveStandingMultiplier: `Multiplicateur de réputation d'Ondes Nocturnes`,
 | 
					    cheats_nightwaveStandingMultiplier: `Multiplicateur de réputation d'Ondes Nocturnes`,
 | 
				
			||||||
    cheats_save: `Sauvegarder`,
 | 
					    cheats_save: `Sauvegarder`,
 | 
				
			||||||
    cheats_account: `Compte`,
 | 
					    cheats_account: `Compte`,
 | 
				
			||||||
 | 
				
			|||||||
@ -185,6 +185,7 @@ dict = {
 | 
				
			|||||||
    cheats_unlockAllSimarisResearchEntries: `[UNTRANSLATED] Unlock All Simaris Research Entries`,
 | 
					    cheats_unlockAllSimarisResearchEntries: `[UNTRANSLATED] Unlock All Simaris Research Entries`,
 | 
				
			||||||
    cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
 | 
					    cheats_disableDailyTribute: `[UNTRANSLATED] Disable Daily Tribute`,
 | 
				
			||||||
    cheats_spoofMasteryRank: `Подделанный ранг мастерства (-1 для отключения)`,
 | 
					    cheats_spoofMasteryRank: `Подделанный ранг мастерства (-1 для отключения)`,
 | 
				
			||||||
 | 
					    cheats_relicRewardItemCountMultiplier: `[UNTRANSLATED] Relic Reward Item Count Multiplier`,
 | 
				
			||||||
    cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
 | 
					    cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
 | 
				
			||||||
    cheats_save: `[UNTRANSLATED] Save`,
 | 
					    cheats_save: `[UNTRANSLATED] Save`,
 | 
				
			||||||
    cheats_account: `Аккаунт`,
 | 
					    cheats_account: `Аккаунт`,
 | 
				
			||||||
 | 
				
			|||||||
@ -185,6 +185,7 @@ dict = {
 | 
				
			|||||||
    cheats_unlockAllSimarisResearchEntries: `解锁所有Simaris研究条目`,
 | 
					    cheats_unlockAllSimarisResearchEntries: `解锁所有Simaris研究条目`,
 | 
				
			||||||
    cheats_disableDailyTribute: `禁用每日登录奖励`,
 | 
					    cheats_disableDailyTribute: `禁用每日登录奖励`,
 | 
				
			||||||
    cheats_spoofMasteryRank: `伪造精通段位(-1为禁用)`,
 | 
					    cheats_spoofMasteryRank: `伪造精通段位(-1为禁用)`,
 | 
				
			||||||
 | 
					    cheats_relicRewardItemCountMultiplier: `[UNTRANSLATED] Relic Reward Item Count Multiplier`,
 | 
				
			||||||
    cheats_nightwaveStandingMultiplier: `午夜电波声望倍率`,
 | 
					    cheats_nightwaveStandingMultiplier: `午夜电波声望倍率`,
 | 
				
			||||||
    cheats_save: `保存`,
 | 
					    cheats_save: `保存`,
 | 
				
			||||||
    cheats_account: `账户`,
 | 
					    cheats_account: `账户`,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user