feat(webui): edit suit invigorations #2478
@ -0,0 +1,34 @@
|
||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { getInventory } from "@/src/services/inventoryService";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
const DEFAULT_UPGRADE_EXPIRY_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
||||
|
||||
export const editSuitInvigorationUpgradeController: RequestHandler = async (req, res) => {
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
const { oid, data } = req.body as {
|
||||
oid: string;
|
||||
data?: {
|
||||
DefensiveUpgrade: string;
|
||||
OffensiveUpgrade: string;
|
||||
UpgradesExpiry?: number;
|
||||
};
|
||||
};
|
||||
const inventory = await getInventory(accountId);
|
||||
const suit = inventory.Suits.id(oid)!;
|
||||
if (data) {
|
||||
suit.DefensiveUpgrade = data.DefensiveUpgrade;
|
||||
suit.OffensiveUpgrade = data.OffensiveUpgrade;
|
||||
if (data.UpgradesExpiry) {
|
||||
suit.UpgradesExpiry = new Date(data.UpgradesExpiry);
|
||||
} else {
|
||||
suit.UpgradesExpiry = new Date(Date.now() + DEFAULT_UPGRADE_EXPIRY_MS);
|
||||
}
|
||||
} else {
|
||||
suit.DefensiveUpgrade = undefined;
|
||||
suit.OffensiveUpgrade = undefined;
|
||||
suit.UpgradesExpiry = undefined;
|
||||
}
|
||||
await inventory.save();
|
||||
res.end();
|
||||
};
|
@ -14,6 +14,7 @@ import { addMissingMaxRankModsController } from "@/src/controllers/custom/addMis
|
||||
import { webuiFileChangeDetectedController } from "@/src/controllers/custom/webuiFileChangeDetectedController";
|
||||
import { completeAllMissionsController } from "@/src/controllers/custom/completeAllMissionsController";
|
||||
import { addMissingHelminthBlueprintsController } from "@/src/controllers/custom/addMissingHelminthBlueprintsController";
|
||||
import { editSuitInvigorationUpgradeController } from "@/src/controllers/custom/editSuitInvigorationUpgradeController";
|
||||
|
||||
import { createAccountController } from "@/src/controllers/custom/createAccountController";
|
||||
import { createMessageController } from "@/src/controllers/custom/createMessageController";
|
||||
@ -45,6 +46,7 @@ customRouter.get("/addMissingMaxRankMods", addMissingMaxRankModsController);
|
||||
customRouter.get("/webuiFileChangeDetected", webuiFileChangeDetectedController);
|
||||
customRouter.get("/completeAllMissions", completeAllMissionsController);
|
||||
customRouter.get("/addMissingHelminthBlueprints", addMissingHelminthBlueprintsController);
|
||||
customRouter.post("/editSuitInvigorationUpgrade", editSuitInvigorationUpgradeController);
|
||||
Sainan marked this conversation as resolved
Outdated
|
||||
|
||||
customRouter.post("/createAccount", createAccountController);
|
||||
customRouter.post("/createMessage", createMessageController);
|
||||
|
@ -977,6 +977,59 @@
|
||||
</div>
|
||||
<div class="toast-container position-fixed bottom-0 end-0 p-3"></div>
|
||||
</div>
|
||||
<div id="editSuitInvigorationForm" class="card" style="display: none;">
|
||||
Sainan marked this conversation as resolved
Outdated
Sainan
commented
What is this shit? We have a detailedView, this is completely misplaced. What is this shit? We have a detailedView, this is completely misplaced.
nyaoouo
commented
detailed view dont pass detail of item to view, cannot auto fillin data detailed view dont pass detail of item to view, cannot auto fillin data
Sainan
commented
Damn, all the other features on the detailed view must be magic then. Purely guessing the data to fill in. What a miracle that it guesses correctly. Damn, all the other features on the detailed view must be magic then. Purely guessing the data to fill in. What a miracle that it guesses correctly.
nyaoouo
commented
i found it, but i want to remind u that part is i found it, but i want to remind u that part is `id="archonShards-card"` =_=
AMelonInsideLemon
commented
And And `id="modularParts-card"` and `id="valenceBonus-card"` is under `id="detailedView-route"`
|
||||
<h5 class="card-header">Edit Suit Invigoration Upgrades</h5>
|
||||
<div class="card-body">
|
||||
<form onsubmit="submitSuitInvigorationUpgrade(event)">
|
||||
<input type="hidden" id="invigoration-oid" />
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="invigoration-offensive" class="form-label">Offensive Upgrade</label>
|
||||
<select class="form-select" id="invigoration-offensive">
|
||||
<option value="">None</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Offensive/OffensiveInvigorationPowerStrength">Power Strength</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Offensive/OffensiveInvigorationPowerRange">Power Range</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Offensive/OffensiveInvigorationPowerDuration">Power Duration</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Offensive/OffensiveInvigorationMeleeDamage">Melee Damage</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Offensive/OffensiveInvigorationPrimaryDamage">Primary Damage</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Offensive/OffensiveInvigorationSecondaryDamage">Secondary Damage</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Offensive/OffensiveInvigorationPrimaryCritChance">Primary Crit Chance</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Offensive/OffensiveInvigorationSecondaryCritChance">Secondary Crit Chance</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Offensive/OffensiveInvigorationMeleeCritChance">Melee Crit Chance</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="invigoration-defensive" class="form-label">Defensive Upgrade</label>
|
||||
<select class="form-select" id="invigoration-defensive">
|
||||
<option value="">None</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationPowerEfficiency">Power Efficiency</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationMovementSpeed">Movement Speed</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationParkourSpeed">Parkour Speed</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationHealth">Health</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationEnergy">Energy</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationStatusResistance">Status Resistance</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationReloadSpeed">Reload Speed</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationHealthRegen">Health Regen</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationArmor">Armor</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationJumps">Jumps</option>
|
||||
<option value="/Lotus/Upgrades/Invigorations/Utility/UtilityInvigorationEnergyRegen">Energy Regen</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="invigoration-expiry" class="form-label">Upgrades Expiry (optional)</label>
|
||||
<input type="datetime-local" class="form-control" id="invigoration-expiry" />
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary">Apply Upgrades</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="hideSuitInvigorationForm()">Cancel</button>
|
||||
<button type="button" class="btn btn-danger" onclick="clearSuitInvigorationUpgrades()">Clear Upgrades</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<datalist id="datalist-Suits"></datalist>
|
||||
<datalist id="datalist-SpaceSuits"></datalist>
|
||||
<datalist id="datalist-LongGuns"></datalist>
|
||||
|
@ -667,6 +667,21 @@ function updateInventory() {
|
||||
const td = document.createElement("td");
|
||||
td.classList = "text-end text-nowrap";
|
||||
|
||||
if (category == "Suits") {
|
||||
const a = document.createElement("a");
|
||||
a.href = "#";
|
||||
a.onclick = () => showSuitInvigorationForm(item);
|
||||
a.innerHTML = `<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M15.907 11.998 10.332 9.23a.9.9 0 0 1-.16-.037l-.018-.007v6.554c0 .017.008.034.01.051l2.388-2.974 3.355-.82Z"/>
|
||||
<path d="m11.463 4.054 5.579 3.323A4.02 4.02 0 0 1 18.525 9c.332.668.47 1.414.398 2.155a3.07 3.07 0 0 1-.745 1.65 3.108 3.108 0 0 1-1.55.951c-.022.007-.045.005-.07.01-.062.03-.126.057-.191.08l-2.72.667-1.992 2.48c-.18.227-.41.409-.67.534.047.034.085.077.137.107a2.05 2.05 0 0 0 1.995.035c.592-.33 2.15-1.201 4.636-2.892l.28-.19c1.328-.895 3.616-2.442 3.967-4.215a9.94 9.94 0 0 0-1.713-4.154 10.027 10.027 0 0 0-3.375-2.989 10.107 10.107 0 0 0-8.802-.418c1.162.287 2.287.704 3.354 1.243Z"/>
|
||||
<path d="M5.382 17.082v-6.457a3.7 3.7 0 0 1 .45-1.761 3.733 3.733 0 0 1 1.238-1.34 3.915 3.915 0 0 1 3.433-.245c.176.03.347.084.508.161l5.753 2.856c.082.05.161.105.236.165a2.128 2.128 0 0 0-.953-1.455l-5.51-3.284c-1.74-.857-3.906-1.523-5.244-1.097a9.96 9.96 0 0 0-2.5 3.496 9.895 9.895 0 0 0 .283 8.368 9.973 9.973 0 0 0 2.73 3.322 17.161 17.161 0 0 1-.424-2.729Z"/>
|
||||
<path d="m19.102 16.163-.272.183c-2.557 1.74-4.169 2.64-4.698 2.935a4.083 4.083 0 0 1-2 .53 3.946 3.946 0 0 1-1.983-.535 3.788 3.788 0 0 1-1.36-1.361 3.752 3.752 0 0 1-.51-1.85 1.812 1.812 0 0 1-.043-.26V9.143c0-.024.009-.046.01-.07-.056.02-.11.043-.162.07a1.796 1.796 0 0 0-.787 1.516v6.377a10.67 10.67 0 0 0 1.113 4.27 10.11 10.11 0 0 0 8.505-.53 10.022 10.022 0 0 0 3.282-2.858 9.936 9.936 0 0 0 1.75-3.97 19.615 19.615 0 0 1-2.845 2.216Z"/>
|
||||
</svg>`;
|
||||
a.style.textDecoration = "none";
|
||||
a.title = "";
|
||||
td.appendChild(a);
|
||||
}
|
||||
|
||||
let maxXP = Math.pow(uniqueLevelCaps[item.ItemType] ?? 30, 2) * 1000;
|
||||
if (
|
||||
category != "Suits" &&
|
||||
@ -2862,3 +2877,118 @@ function handleModularPartsChange(event) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function showSuitInvigorationForm(suitData) {
|
||||
document.getElementById("invigoration-oid").value = suitData.ItemId.$oid;
|
||||
|
||||
// Auto-fill form with existing data
|
||||
document.getElementById("invigoration-offensive").value = suitData?.OffensiveUpgrade || "";
|
||||
document.getElementById("invigoration-defensive").value = suitData?.DefensiveUpgrade || "";
|
||||
|
||||
// Handle expiry date
|
||||
if (suitData?.UpgradesExpiry) {
|
||||
let expiryDate;
|
||||
if (suitData.UpgradesExpiry.$date) {
|
||||
// MongoDB format: { "$date": { "$numberLong": "1752933467151" } }
|
||||
expiryDate = new Date(parseInt(suitData.UpgradesExpiry.$date.$numberLong));
|
||||
} else if (typeof suitData.UpgradesExpiry === "number") {
|
||||
// Timestamp format
|
||||
expiryDate = new Date(suitData.UpgradesExpiry);
|
||||
} else if (suitData.UpgradesExpiry instanceof Date) {
|
||||
// Date object
|
||||
expiryDate = suitData.UpgradesExpiry;
|
||||
}
|
||||
|
||||
if (expiryDate && !isNaN(expiryDate.getTime())) {
|
||||
// Format for datetime-local input (YYYY-MM-DDTHH:mm)
|
||||
const year = expiryDate.getFullYear();
|
||||
const month = String(expiryDate.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(expiryDate.getDate()).padStart(2, "0");
|
||||
const hours = String(expiryDate.getHours()).padStart(2, "0");
|
||||
const minutes = String(expiryDate.getMinutes()).padStart(2, "0");
|
||||
|
||||
document.getElementById("invigoration-expiry").value = `${year}-${month}-${day}T${hours}:${minutes}`;
|
||||
Sainan marked this conversation as resolved
Outdated
Sainan
commented
...and here. ...and here.
|
||||
} else {
|
||||
document.getElementById("invigoration-expiry").value = "";
|
||||
}
|
||||
} else {
|
||||
document.getElementById("invigoration-expiry").value = "";
|
||||
}
|
||||
|
||||
const form = document.getElementById("editSuitInvigorationForm");
|
||||
form.style.display = "block";
|
||||
form.style.position = "fixed";
|
||||
form.style.top = "50%";
|
||||
form.style.left = "50%";
|
||||
form.style.transform = "translate(-50%, -50%)";
|
||||
form.style.zIndex = "1050";
|
||||
form.style.width = "400px";
|
||||
Sainan marked this conversation as resolved
Outdated
Sainan
commented
If you need godawful custom CSS, put it in the CSS file. If you need godawful custom CSS, put it in the CSS file.
|
||||
|
||||
// Add backdrop
|
||||
const backdrop = document.createElement("div");
|
||||
backdrop.id = "invigoration-backdrop";
|
||||
backdrop.style.position = "fixed";
|
||||
backdrop.style.top = "0";
|
||||
backdrop.style.left = "0";
|
||||
backdrop.style.width = "100%";
|
||||
backdrop.style.height = "100%";
|
||||
backdrop.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
|
||||
backdrop.style.zIndex = "1040";
|
||||
backdrop.onclick = hideSuitInvigorationForm;
|
||||
document.body.appendChild(backdrop);
|
||||
}
|
||||
|
||||
function hideSuitInvigorationForm() {
|
||||
document.getElementById("editSuitInvigorationForm").style.display = "none";
|
||||
const backdrop = document.getElementById("invigoration-backdrop");
|
||||
if (backdrop) {
|
||||
backdrop.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function submitSuitInvigorationUpgrade(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const oid = document.getElementById("invigoration-oid").value;
|
||||
const offensiveUpgrade = document.getElementById("invigoration-offensive").value;
|
||||
const defensiveUpgrade = document.getElementById("invigoration-defensive").value;
|
||||
const expiry = document.getElementById("invigoration-expiry").value;
|
||||
|
||||
if (!offensiveUpgrade && !defensiveUpgrade) {
|
||||
alert("Please select at least one upgrade type.");
|
||||
return;
|
||||
}
|
||||
|
||||
const data = {
|
||||
OffensiveUpgrade: offensiveUpgrade,
|
||||
DefensiveUpgrade: defensiveUpgrade
|
||||
};
|
||||
|
||||
if (expiry) {
|
||||
data.UpgradesExpiry = new Date(expiry).getTime();
|
||||
}
|
||||
|
||||
editSuitInvigorationUpgrade(oid, data);
|
||||
hideSuitInvigorationForm();
|
||||
}
|
||||
|
||||
function clearSuitInvigorationUpgrades() {
|
||||
const oid = document.getElementById("invigoration-oid").value;
|
||||
editSuitInvigorationUpgrade(oid, null);
|
||||
hideSuitInvigorationForm();
|
||||
}
|
||||
|
||||
async function editSuitInvigorationUpgrade(oid, data) {
|
||||
/* data?: {
|
||||
DefensiveUpgrade: string;
|
||||
OffensiveUpgrade: string;
|
||||
UpgradesExpiry?: number;
|
||||
}*/
|
||||
$.post({
|
||||
url: "/custom/editSuitInvigorationUpgrade?" + window.authz,
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify({ oid, data })
|
||||
}).done(function () {
|
||||
updateInventory();
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user
Really? Don't see what's wrong here?