forked from OpenWF/SpaceNinjaServer
		
	Compare commits
	
		
			6 Commits
		
	
	
		
			f796f9a851
			...
			987b5b98ff
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 987b5b98ff | |||
| fbbd9076cf | |||
| 838818543c | |||
| a16e2716f1 | |||
| f4c7ce582b | |||
| c0187f9446 | 
@ -1,6 +1,7 @@
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { getInventory, updateCurrency } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { sendWsBroadcastTo } from "@/src/services/wsService";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const releasePetController: RequestHandler = async (req, res) => {
 | 
			
		||||
@ -19,6 +20,7 @@ export const releasePetController: RequestHandler = async (req, res) => {
 | 
			
		||||
 | 
			
		||||
    await inventory.save();
 | 
			
		||||
    res.json({ inventoryChanges }); // Not a mistake; it's "inventoryChanges" here.
 | 
			
		||||
    sendWsBroadcastTo(accountId, { update_inventory: true });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface IReleasePetRequest {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										65
									
								
								src/controllers/custom/changeModularPartsController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/controllers/custom/changeModularPartsController.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const changeModularPartsController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
    const request = req.body as IUpdateFingerPrintRequest;
 | 
			
		||||
    const inventory = await getInventory(accountId, request.category);
 | 
			
		||||
    const item = inventory[request.category].id(request.oid);
 | 
			
		||||
    if (item) {
 | 
			
		||||
        item.ModularParts = request.modularParts;
 | 
			
		||||
 | 
			
		||||
        request.modularParts.forEach(part => {
 | 
			
		||||
            const categoryMap = mapping[part];
 | 
			
		||||
            if (categoryMap && categoryMap[request.category]) {
 | 
			
		||||
                item.ItemType = categoryMap[request.category]!;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        await inventory.save();
 | 
			
		||||
    }
 | 
			
		||||
    res.end();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface IUpdateFingerPrintRequest {
 | 
			
		||||
    category: TEquipmentKey;
 | 
			
		||||
    oid: string;
 | 
			
		||||
    modularParts: string[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const mapping: Partial<Record<string, Partial<Record<TEquipmentKey, string>>>> = {
 | 
			
		||||
    "/Lotus/Weapons/SolarisUnited/Secondary/SUModularSecondarySet1/Barrel/SUModularSecondaryBarrelAPart": {
 | 
			
		||||
        LongGuns: "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryShotgun",
 | 
			
		||||
        Pistols: "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Weapons/Infested/Pistols/InfKitGun/Barrels/InfBarrelEgg/InfModularBarrelEggPart": {
 | 
			
		||||
        LongGuns: "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryShotgun",
 | 
			
		||||
        Pistols: "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Weapons/SolarisUnited/Secondary/SUModularSecondarySet1/Barrel/SUModularSecondaryBarrelBPart": {
 | 
			
		||||
        LongGuns: "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimary",
 | 
			
		||||
        Pistols: "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Weapons/SolarisUnited/Secondary/SUModularSecondarySet1/Barrel/SUModularSecondaryBarrelCPart": {
 | 
			
		||||
        LongGuns: "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimary",
 | 
			
		||||
        Pistols: "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Weapons/SolarisUnited/Secondary/SUModularSecondarySet1/Barrel/SUModularSecondaryBarrelDPart": {
 | 
			
		||||
        LongGuns: "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryBeam",
 | 
			
		||||
        Pistols: "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Weapons/Infested/Pistols/InfKitGun/Barrels/InfBarrelBeam/InfModularBarrelBeamPart": {
 | 
			
		||||
        LongGuns: "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryBeam",
 | 
			
		||||
        Pistols: "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadA": {
 | 
			
		||||
        MoaPets: "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetAPowerSuit"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadB": {
 | 
			
		||||
        MoaPets: "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetBPowerSuit"
 | 
			
		||||
    },
 | 
			
		||||
    "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadC": {
 | 
			
		||||
        MoaPets: "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetCPowerSuit"
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@ -3,6 +3,7 @@ import { config } from "@/src/services/configService";
 | 
			
		||||
import { getAccountForRequest, isAdministrator } from "@/src/services/loginService";
 | 
			
		||||
import { saveConfig } from "@/src/services/configWriterService";
 | 
			
		||||
import { sendWsBroadcastExcept } from "@/src/services/wsService";
 | 
			
		||||
import { syncConfigWithDatabase } from "@/src/services/configWatcherService";
 | 
			
		||||
 | 
			
		||||
export const getConfigController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const account = await getAccountForRequest(req);
 | 
			
		||||
@ -26,6 +27,7 @@ export const setConfigController: RequestHandler = async (req, res) => {
 | 
			
		||||
            obj[idx] = value;
 | 
			
		||||
        }
 | 
			
		||||
        sendWsBroadcastExcept(parseInt(String(req.query.wsid)), { config_reloaded: true });
 | 
			
		||||
        syncConfigWithDatabase();
 | 
			
		||||
        await saveConfig();
 | 
			
		||||
        res.end();
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@ import { manageQuestsController } from "@/src/controllers/custom/manageQuestsCon
 | 
			
		||||
import { setEvolutionProgressController } from "@/src/controllers/custom/setEvolutionProgressController";
 | 
			
		||||
import { setBoosterController } from "@/src/controllers/custom/setBoosterController";
 | 
			
		||||
import { updateFingerprintController } from "@/src/controllers/custom/updateFingerprintController";
 | 
			
		||||
import { changeModularPartsController } from "@/src/controllers/custom/changeModularPartsController";
 | 
			
		||||
 | 
			
		||||
import { getConfigController, setConfigController } from "@/src/controllers/custom/configController";
 | 
			
		||||
 | 
			
		||||
@ -55,6 +56,7 @@ customRouter.post("/manageQuests", manageQuestsController);
 | 
			
		||||
customRouter.post("/setEvolutionProgress", setEvolutionProgressController);
 | 
			
		||||
customRouter.post("/setBooster", setBoosterController);
 | 
			
		||||
customRouter.post("/updateFingerprint", updateFingerprintController);
 | 
			
		||||
customRouter.post("/changeModularParts", changeModularPartsController);
 | 
			
		||||
 | 
			
		||||
customRouter.post("/getConfig", getConfigController);
 | 
			
		||||
customRouter.post("/setConfig", setConfigController);
 | 
			
		||||
 | 
			
		||||
@ -261,7 +261,8 @@ export const getSortie = (day: number): ISortie => {
 | 
			
		||||
        if (
 | 
			
		||||
            sortieFactionToSystemIndexes[sortieBossToFaction[boss]].includes(value.systemIndex) &&
 | 
			
		||||
            sortieFactionToFactionIndexes[sortieBossToFaction[boss]].includes(value.factionIndex!) &&
 | 
			
		||||
            key in sortieTilesets
 | 
			
		||||
            key in sortieTilesets &&
 | 
			
		||||
            (key != "SolNode228" || sortieBossToFaction[boss] == "FC_GRINEER") // PoE does not work for non-infested enemies
 | 
			
		||||
        ) {
 | 
			
		||||
            nodes.push(key);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -478,6 +478,12 @@
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div id="modularParts-card" class="card mb-3 d-none">
 | 
			
		||||
                    <h5 class="card-header" data-loc="detailedView_modularPartsLabel"></h5>
 | 
			
		||||
                    <div class="card-body">
 | 
			
		||||
                        <form id="modularParts-form" class="input-group mb-3" onsubmit="handleModularPartsChange(event)"></form>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div id="valenceBonus-card" class="card mb-3 d-none">
 | 
			
		||||
                    <h5 class="card-header" data-loc="detailedView_valenceBonusLabel"></h5>
 | 
			
		||||
                    <div class="card-body">
 | 
			
		||||
 | 
			
		||||
@ -730,7 +730,10 @@ function updateInventory() {
 | 
			
		||||
                            td.appendChild(a);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (["Suits", "LongGuns", "Pistols", "Melee", "SpaceGuns", "SpaceMelee"].includes(category)) {
 | 
			
		||||
                        if (
 | 
			
		||||
                            ["Suits", "LongGuns", "Pistols", "Melee", "SpaceGuns", "SpaceMelee"].includes(category) ||
 | 
			
		||||
                            modularWeapons.includes(item.ItemType)
 | 
			
		||||
                        ) {
 | 
			
		||||
                            const a = document.createElement("a");
 | 
			
		||||
                            a.href = "/webui/detailedView?productCategory=" + category + "&itemId=" + item.ItemId.$oid;
 | 
			
		||||
                            a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M278.5 215.6L23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41c11.1-7.2 5.5-23-7.8-23c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3l-32.2 0c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7C506.4 207.6 512 184.1 512 160c0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149C91 197 64 262.1 64 330v55.3L253.6 195.8c6.2-6.2 16.4-6.2 22.6 0c5.4 5.4 6.1 13.6 2.2 19.8z"/></svg>`;
 | 
			
		||||
@ -1017,13 +1020,19 @@ function updateInventory() {
 | 
			
		||||
                if (item.ItemType.substr(0, 32) == "/Lotus/Upgrades/Mods/Randomized/") {
 | 
			
		||||
                    const rivenType = item.ItemType.substr(32);
 | 
			
		||||
                    const fingerprint = JSON.parse(item.UpgradeFingerprint);
 | 
			
		||||
                    if (fingerprint.buffs) {
 | 
			
		||||
                    if ("buffs" in fingerprint) {
 | 
			
		||||
                        // Riven has been revealed?
 | 
			
		||||
                        const tr = document.createElement("tr");
 | 
			
		||||
                        {
 | 
			
		||||
                            const td = document.createElement("td");
 | 
			
		||||
                            td.textContent = itemMap[fingerprint.compat]?.name ?? fingerprint.compat;
 | 
			
		||||
                            td.textContent += " " + RivenParser.parseRiven(rivenType, fingerprint, 1).name;
 | 
			
		||||
                            td.textContent += " ";
 | 
			
		||||
                            try {
 | 
			
		||||
                                td.textContent += RivenParser.parseRiven(rivenType, fingerprint, 1).name;
 | 
			
		||||
                            } catch (e) {
 | 
			
		||||
                                console.warn("malformed riven", { rivenType, fingerprint });
 | 
			
		||||
                                td.textContent += " [Malformed Riven]";
 | 
			
		||||
                            }
 | 
			
		||||
                            td.innerHTML +=
 | 
			
		||||
                                " <span title='" +
 | 
			
		||||
                                loc("code_buffsNumber") +
 | 
			
		||||
@ -1233,6 +1242,35 @@ function updateInventory() {
 | 
			
		||||
                            document.getElementById("valenceBonus-procent").value = Math.round(buffValue * 1000) / 10;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (modularWeapons.includes(item.ItemType)) {
 | 
			
		||||
                        document.getElementById("modularParts-card").classList.remove("d-none");
 | 
			
		||||
                        const form = document.getElementById("modularParts-form");
 | 
			
		||||
                        form.innerHTML = "";
 | 
			
		||||
                        const requiredParts = getRequiredParts(category, item.ItemType);
 | 
			
		||||
 | 
			
		||||
                        requiredParts.forEach(modularPart => {
 | 
			
		||||
                            const input = document.createElement("input");
 | 
			
		||||
                            input.classList.add("form-control");
 | 
			
		||||
                            input.id = "detailedView-modularPart-" + modularPart;
 | 
			
		||||
                            input.setAttribute("list", "datalist-ModularParts-" + modularPart);
 | 
			
		||||
 | 
			
		||||
                            const datalist = document.getElementById("datalist-ModularParts-" + modularPart);
 | 
			
		||||
                            const options = Array.from(datalist.options);
 | 
			
		||||
 | 
			
		||||
                            input.value =
 | 
			
		||||
                                options.find(option => item.ModularParts.includes(option.getAttribute("data-key")))
 | 
			
		||||
                                    ?.value || "";
 | 
			
		||||
                            form.appendChild(input);
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
                        const changeButton = document.createElement("button");
 | 
			
		||||
                        changeButton.classList.add("btn");
 | 
			
		||||
                        changeButton.classList.add("btn-primary");
 | 
			
		||||
                        changeButton.type = "submit";
 | 
			
		||||
                        changeButton.setAttribute("data-loc", "cheats_changeButton");
 | 
			
		||||
                        changeButton.innerHTML = loc("cheats_changeButton");
 | 
			
		||||
                        form.appendChild(changeButton);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    single.loadRoute("/webui/inventory");
 | 
			
		||||
                }
 | 
			
		||||
@ -1332,47 +1370,41 @@ function doAcquireEquipment(category) {
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function doAcquireModularEquipment(category, WeaponType) {
 | 
			
		||||
    let requiredParts;
 | 
			
		||||
    let Parts = [];
 | 
			
		||||
function getRequiredParts(category, WeaponType) {
 | 
			
		||||
    switch (category) {
 | 
			
		||||
        case "HoverBoards":
 | 
			
		||||
            WeaponType = "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit";
 | 
			
		||||
            requiredParts = ["HB_DECK", "HB_ENGINE", "HB_FRONT", "HB_JET"];
 | 
			
		||||
            break;
 | 
			
		||||
        case "Hoverboards":
 | 
			
		||||
            return ["HB_DECK", "HB_ENGINE", "HB_FRONT", "HB_JET"];
 | 
			
		||||
 | 
			
		||||
        case "OperatorAmps":
 | 
			
		||||
            requiredParts = ["AMP_OCULUS", "AMP_CORE", "AMP_BRACE"];
 | 
			
		||||
            break;
 | 
			
		||||
            return ["AMP_OCULUS", "AMP_CORE", "AMP_BRACE"];
 | 
			
		||||
 | 
			
		||||
        case "Melee":
 | 
			
		||||
            requiredParts = ["BLADE", "HILT", "HILT_WEIGHT"];
 | 
			
		||||
            break;
 | 
			
		||||
            return ["BLADE", "HILT", "HILT_WEIGHT"];
 | 
			
		||||
 | 
			
		||||
        case "LongGuns":
 | 
			
		||||
            requiredParts = ["GUN_BARREL", "GUN_PRIMARY_HANDLE", "GUN_CLIP"];
 | 
			
		||||
            break;
 | 
			
		||||
            return ["GUN_BARREL", "GUN_PRIMARY_HANDLE", "GUN_CLIP"];
 | 
			
		||||
 | 
			
		||||
        case "Pistols":
 | 
			
		||||
            requiredParts = ["GUN_BARREL", "GUN_SECONDARY_HANDLE", "GUN_CLIP"];
 | 
			
		||||
            break;
 | 
			
		||||
            return ["GUN_BARREL", "GUN_SECONDARY_HANDLE", "GUN_CLIP"];
 | 
			
		||||
 | 
			
		||||
        case "MoaPets":
 | 
			
		||||
            if (WeaponType == "/Lotus/Types/Friendly/Pets/MoaPets/MoaPetPowerSuit") {
 | 
			
		||||
                requiredParts = ["MOA_ENGINE", "MOA_PAYLOAD", "MOA_HEAD", "MOA_LEG"];
 | 
			
		||||
            } else {
 | 
			
		||||
                requiredParts = ["ZANUKA_BODY", "ZANUKA_HEAD", "ZANUKA_LEG", "ZANUKA_TAIL"];
 | 
			
		||||
            return WeaponType === "/Lotus/Types/Friendly/Pets/MoaPets/MoaPetPowerSuit"
 | 
			
		||||
                ? ["MOA_ENGINE", "MOA_PAYLOAD", "MOA_HEAD", "MOA_LEG"]
 | 
			
		||||
                : ["ZANUKA_BODY", "ZANUKA_HEAD", "ZANUKA_LEG", "ZANUKA_TAIL"];
 | 
			
		||||
 | 
			
		||||
        case "KubrowPets": {
 | 
			
		||||
            return WeaponType.endsWith("InfestedCatbrowPetPowerSuit")
 | 
			
		||||
                ? ["CATBROW_ANTIGEN", "CATBROW_MUTAGEN"]
 | 
			
		||||
                : ["KUBROW_ANTIGEN", "KUBROW_MUTAGEN"];
 | 
			
		||||
        }
 | 
			
		||||
            break;
 | 
			
		||||
        case "KubrowPets":
 | 
			
		||||
            if (
 | 
			
		||||
                [
 | 
			
		||||
                    "/Lotus/Types/Friendly/Pets/CreaturePets/VulpineInfestedCatbrowPetPowerSuit",
 | 
			
		||||
                    "/Lotus/Types/Friendly/Pets/CreaturePets/HornedInfestedCatbrowPetPowerSuit",
 | 
			
		||||
                    "/Lotus/Types/Friendly/Pets/CreaturePets/ArmoredInfestedCatbrowPetPowerSuit"
 | 
			
		||||
                ].includes(WeaponType)
 | 
			
		||||
            ) {
 | 
			
		||||
                requiredParts = ["CATBROW_ANTIGEN", "CATBROW_MUTAGEN"];
 | 
			
		||||
            } else {
 | 
			
		||||
                requiredParts = ["KUBROW_ANTIGEN", "KUBROW_MUTAGEN"];
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function doAcquireModularEquipment(category, WeaponType) {
 | 
			
		||||
    if (category === "Hoverboards") WeaponType = "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit";
 | 
			
		||||
    const requiredParts = getRequiredParts(category, WeaponType);
 | 
			
		||||
    let Parts = [];
 | 
			
		||||
 | 
			
		||||
    requiredParts.forEach(part => {
 | 
			
		||||
        const partName = getKey(document.getElementById("acquire-type-" + category + "-" + part));
 | 
			
		||||
        if (partName) {
 | 
			
		||||
@ -1489,7 +1521,7 @@ function doAcquireEvolution() {
 | 
			
		||||
    setEvolutionProgress([{ ItemType: uniqueName, Rank: permanentEvolutionWeapons.has(uniqueName) ? 0 : 1 }]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$("input[list]").on("input", function () {
 | 
			
		||||
$(document).on("input", "input[list]", function () {
 | 
			
		||||
    $(this).removeClass("is-invalid");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -2196,6 +2228,8 @@ single.getRoute("#detailedView-route").on("beforeload", function () {
 | 
			
		||||
    document.getElementById("detailedView-title").textContent = "";
 | 
			
		||||
    document.querySelector("#detailedView-route .text-body-secondary").textContent = "";
 | 
			
		||||
    document.getElementById("archonShards-card").classList.add("d-none");
 | 
			
		||||
    document.getElementById("modularParts-card").classList.add("d-none");
 | 
			
		||||
    document.getElementById("modularParts-form").innerHTML = "";
 | 
			
		||||
    document.getElementById("valenceBonus-card").classList.add("d-none");
 | 
			
		||||
    if (window.didInitialInventoryUpdate) {
 | 
			
		||||
        updateInventory();
 | 
			
		||||
@ -2353,22 +2387,10 @@ function handleModularSelection(category) {
 | 
			
		||||
                        modularFieldsZanuka.style.display = "none";
 | 
			
		||||
                    }
 | 
			
		||||
                } else if (inventoryCategory === "KubrowPets") {
 | 
			
		||||
                    if (
 | 
			
		||||
                        [
 | 
			
		||||
                            "/Lotus/Types/Friendly/Pets/CreaturePets/VulpineInfestedCatbrowPetPowerSuit",
 | 
			
		||||
                            "/Lotus/Types/Friendly/Pets/CreaturePets/HornedInfestedCatbrowPetPowerSuit",
 | 
			
		||||
                            "/Lotus/Types/Friendly/Pets/CreaturePets/ArmoredInfestedCatbrowPetPowerSuit"
 | 
			
		||||
                        ].includes(key)
 | 
			
		||||
                    ) {
 | 
			
		||||
                    if (key.endsWith("InfestedCatbrowPetPowerSuit")) {
 | 
			
		||||
                        modularFieldsCatbrow.style.display = "";
 | 
			
		||||
                        modularFieldsKubrow.style.display = "none";
 | 
			
		||||
                    } else if (
 | 
			
		||||
                        [
 | 
			
		||||
                            "/Lotus/Types/Friendly/Pets/CreaturePets/VizierPredatorKubrowPetPowerSuit",
 | 
			
		||||
                            "/Lotus/Types/Friendly/Pets/CreaturePets/PharaohPredatorKubrowPetPowerSuit",
 | 
			
		||||
                            "/Lotus/Types/Friendly/Pets/CreaturePets/MedjayPredatorKubrowPetPowerSuit"
 | 
			
		||||
                        ].includes(key)
 | 
			
		||||
                    ) {
 | 
			
		||||
                    } else if (key.endsWith("PredatorKubrowPetPowerSuit")) {
 | 
			
		||||
                        modularFieldsCatbrow.style.display = "none";
 | 
			
		||||
                        modularFieldsKubrow.style.display = "";
 | 
			
		||||
                    } else {
 | 
			
		||||
@ -2807,3 +2829,36 @@ async function markAllAsRead() {
 | 
			
		||||
    }
 | 
			
		||||
    toast(loc(any ? "code_succRelog" : "code_nothingToDo"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleModularPartsChange(event) {
 | 
			
		||||
    event.preventDefault();
 | 
			
		||||
    const urlParams = new URLSearchParams(window.location.search);
 | 
			
		||||
    const form = document.getElementById("modularParts-form");
 | 
			
		||||
    const inputs = form.querySelectorAll("input");
 | 
			
		||||
    const modularParts = [];
 | 
			
		||||
    inputs.forEach(input => {
 | 
			
		||||
        const key = getKey(input);
 | 
			
		||||
        if (!key) {
 | 
			
		||||
            input.classList.add("is-invalid");
 | 
			
		||||
        } else {
 | 
			
		||||
            modularParts.push(key);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (inputs.length == modularParts.length) {
 | 
			
		||||
        revalidateAuthz().then(() => {
 | 
			
		||||
            $.post({
 | 
			
		||||
                url: "/custom/changeModularParts?" + window.authz,
 | 
			
		||||
                contentType: "application/json",
 | 
			
		||||
                data: JSON.stringify({
 | 
			
		||||
                    category: urlParams.get("productCategory"),
 | 
			
		||||
                    oid: urlParams.get("itemId"),
 | 
			
		||||
                    modularParts
 | 
			
		||||
                })
 | 
			
		||||
            }).then(function () {
 | 
			
		||||
                toast(loc("code_succChange"));
 | 
			
		||||
                updateInventory();
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -61,6 +61,7 @@ dict = {
 | 
			
		||||
    code_pigment: `Pigment`,
 | 
			
		||||
    code_mature: `Für den Kampf auswachsen lassen`,
 | 
			
		||||
    code_unmature: `Genetisches Altern zurücksetzen`,
 | 
			
		||||
    code_succChange: `[UNTRANSLATED] Successfully changed.`,
 | 
			
		||||
    login_description: `Melde dich mit deinem OpenWF-Account an (denselben Angaben wie im Spiel, wenn du dich mit diesem Server verbindest).`,
 | 
			
		||||
    login_emailLabel: `E-Mail-Adresse`,
 | 
			
		||||
    login_passwordLabel: `Passwort`,
 | 
			
		||||
@ -123,6 +124,7 @@ dict = {
 | 
			
		||||
    detailedView_archonShardsDescription2: `Hinweis: Jede Archon-Scherbe benötigt beim Laden etwas Zeit, um angewendet zu werden.`,
 | 
			
		||||
    detailedView_valenceBonusLabel: `Valenz-Bonus`,
 | 
			
		||||
    detailedView_valenceBonusDescription: `[UNTRANSLATED] You can set or remove the Valence Bonus from your weapon.`,
 | 
			
		||||
    detailedView_modularPartsLabel: `[UNTRANSLATED] Change Modular Parts`,
 | 
			
		||||
 | 
			
		||||
    mods_addRiven: `Riven hinzufügen`,
 | 
			
		||||
    mods_fingerprint: `Fingerabdruck`,
 | 
			
		||||
 | 
			
		||||
@ -60,6 +60,7 @@ dict = {
 | 
			
		||||
    code_pigment: `Pigment`,
 | 
			
		||||
    code_mature: `Mature for combat`,
 | 
			
		||||
    code_unmature: `Regress genetic aging`,
 | 
			
		||||
    code_succChange: `Successfully changed.`,
 | 
			
		||||
    login_description: `Login using your OpenWF account credentials (same as in-game when connecting to this server).`,
 | 
			
		||||
    login_emailLabel: `Email address`,
 | 
			
		||||
    login_passwordLabel: `Password`,
 | 
			
		||||
@ -122,6 +123,7 @@ dict = {
 | 
			
		||||
    detailedView_archonShardsDescription2: `Note that each archon shard takes some time to be applied when loading in.`,
 | 
			
		||||
    detailedView_valenceBonusLabel: `Valence Bonus`,
 | 
			
		||||
    detailedView_valenceBonusDescription: `You can set or remove the Valence Bonus from your weapon.`,
 | 
			
		||||
    detailedView_modularPartsLabel: `Change Modular Parts`,
 | 
			
		||||
 | 
			
		||||
    mods_addRiven: `Add Riven`,
 | 
			
		||||
    mods_fingerprint: `Fingerprint`,
 | 
			
		||||
 | 
			
		||||
@ -61,6 +61,7 @@ dict = {
 | 
			
		||||
    code_pigment: `Pigmento`,
 | 
			
		||||
    code_mature: `Listo para el combate`,
 | 
			
		||||
    code_unmature: `Regresar el envejecimiento genético`,
 | 
			
		||||
    code_succChange: `[UNTRANSLATED] Successfully changed.`,
 | 
			
		||||
    login_description: `Inicia sesión con las credenciales de tu cuenta OpenWF (las mismas que usas en el juego al conectarte a este servidor).`,
 | 
			
		||||
    login_emailLabel: `Dirección de correo electrónico`,
 | 
			
		||||
    login_passwordLabel: `Contraseña`,
 | 
			
		||||
@ -123,6 +124,7 @@ dict = {
 | 
			
		||||
    detailedView_archonShardsDescription2: `Ten en cuenta que cada fragmento de archón tarda un poco en aplicarse al cargar`,
 | 
			
		||||
    detailedView_valenceBonusLabel: `Bônus de Valência`,
 | 
			
		||||
    detailedView_valenceBonusDescription: `Puedes establecer o quitar el bono de valencia de tu arma.`,
 | 
			
		||||
    detailedView_modularPartsLabel: `[UNTRANSLATED] Change Modular Parts`,
 | 
			
		||||
 | 
			
		||||
    mods_addRiven: `Agregar Agrietado`,
 | 
			
		||||
    mods_fingerprint: `Huella digital`,
 | 
			
		||||
 | 
			
		||||
@ -61,6 +61,7 @@ dict = {
 | 
			
		||||
    code_pigment: `Pigment`,
 | 
			
		||||
    code_mature: `Maturer pour le combat`,
 | 
			
		||||
    code_unmature: `Régrésser l'âge génétique`,
 | 
			
		||||
    code_succChange: `[UNTRANSLATED] Successfully changed.`,
 | 
			
		||||
    login_description: `Connexion avec les informations de connexion OpenWF.`,
 | 
			
		||||
    login_emailLabel: `Email`,
 | 
			
		||||
    login_passwordLabel: `Mot de passe`,
 | 
			
		||||
@ -123,6 +124,7 @@ dict = {
 | 
			
		||||
    detailedView_archonShardsDescription2: `Un délai sera présent entre l'application des éclats et le chargement en jeu.`,
 | 
			
		||||
    detailedView_valenceBonusLabel: `Bonus de Valence`,
 | 
			
		||||
    detailedView_valenceBonusDescription: `[UNTRANSLATED] You can set or remove the Valence Bonus from your weapon.`,
 | 
			
		||||
    detailedView_modularPartsLabel: `[UNTRANSLATED] Change Modular Parts`,
 | 
			
		||||
 | 
			
		||||
    mods_addRiven: `Ajouter un riven`,
 | 
			
		||||
    mods_fingerprint: `Empreinte`,
 | 
			
		||||
 | 
			
		||||
@ -61,6 +61,7 @@ dict = {
 | 
			
		||||
    code_pigment: `Пигмент`,
 | 
			
		||||
    code_mature: `Подготовить к сражениям`,
 | 
			
		||||
    code_unmature: `Регрессия генетического старения`,
 | 
			
		||||
    code_succChange: `Успешно изменено.`,
 | 
			
		||||
    login_description: `Войдите, используя учетные данные OpenWF (те же, что и в игре при подключении к этому серверу).`,
 | 
			
		||||
    login_emailLabel: `Адрес электронной почты`,
 | 
			
		||||
    login_passwordLabel: `Пароль`,
 | 
			
		||||
@ -123,6 +124,7 @@ dict = {
 | 
			
		||||
    detailedView_archonShardsDescription2: `Обратите внимание: каждый фрагмент архонта применяется с задержкой при загрузке.`,
 | 
			
		||||
    detailedView_valenceBonusLabel: `Бонус Валентности`,
 | 
			
		||||
    detailedView_valenceBonusDescription: `Вы можете установить или убрать бонус валентности с вашего оружия.`,
 | 
			
		||||
    detailedView_modularPartsLabel: `Изменить Модульные Части`,
 | 
			
		||||
 | 
			
		||||
    mods_addRiven: `Добавить Мод Разлома`,
 | 
			
		||||
    mods_fingerprint: `Отпечаток`,
 | 
			
		||||
 | 
			
		||||
@ -61,6 +61,7 @@ dict = {
 | 
			
		||||
    code_pigment: `颜料`,
 | 
			
		||||
    code_mature: `成长并战备`,
 | 
			
		||||
    code_unmature: `逆转衰老基因`,
 | 
			
		||||
    code_succChange: `更改成功.`,
 | 
			
		||||
    login_description: `使用您的 OpenWF 账户凭证登录(与游戏内连接本服务器时使用的昵称相同).`,
 | 
			
		||||
    login_emailLabel: `电子邮箱`,
 | 
			
		||||
    login_passwordLabel: `密码`,
 | 
			
		||||
@ -123,6 +124,7 @@ dict = {
 | 
			
		||||
    detailedView_archonShardsDescription2: `请注意,在加载时,每个执政官源力石都需要一定的时间来生效。`,
 | 
			
		||||
    detailedView_valenceBonusLabel: `效价加成`,
 | 
			
		||||
    detailedView_valenceBonusDescription: `您可以设置或移除武器上的效价加成.`,
 | 
			
		||||
    detailedView_modularPartsLabel: `更换部件`,
 | 
			
		||||
 | 
			
		||||
    mods_addRiven: `添加裂罅MOD`,
 | 
			
		||||
    mods_fingerprint: `印记`,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user