forked from OpenWF/SpaceNinjaServer
merge upstream
This commit is contained in:
commit
cfff91ca5d
@ -69,6 +69,7 @@
|
|||||||
"affinityBoost": false,
|
"affinityBoost": false,
|
||||||
"resourceBoost": false,
|
"resourceBoost": false,
|
||||||
"starDays": true,
|
"starDays": true,
|
||||||
|
"galleonOfGhouls": 0,
|
||||||
"eidolonOverride": "",
|
"eidolonOverride": "",
|
||||||
"vallisOverride": "",
|
"vallisOverride": "",
|
||||||
"duviriOverride": "",
|
"duviriOverride": "",
|
||||||
|
80
package-lock.json
generated
80
package-lock.json
generated
@ -13,6 +13,7 @@
|
|||||||
"@types/morgan": "^1.9.9",
|
"@types/morgan": "^1.9.9",
|
||||||
"@types/websocket": "^1.0.10",
|
"@types/websocket": "^1.0.10",
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
|
"@typescript/native-preview": "^7.0.0-dev.20250625.1",
|
||||||
"crc-32": "^1.2.2",
|
"crc-32": "^1.2.2",
|
||||||
"express": "^5",
|
"express": "^5",
|
||||||
"json-with-bigint": "^3.4.4",
|
"json-with-bigint": "^3.4.4",
|
||||||
@ -21,7 +22,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.69",
|
"warframe-public-export-plus": "^0.5.71",
|
||||||
"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",
|
||||||
@ -30,7 +31,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
||||||
"@typescript-eslint/parser": "^8.28.0",
|
"@typescript-eslint/parser": "^8.28.0",
|
||||||
"@typescript/native-preview": "^7.0.0-dev.20250523.1",
|
|
||||||
"chokidar": "^4.0.3",
|
"chokidar": "^4.0.3",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-plugin-prettier": "^5.2.5",
|
"eslint-plugin-prettier": "^5.2.5",
|
||||||
@ -605,10 +605,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript/native-preview": {
|
"node_modules/@typescript/native-preview": {
|
||||||
"version": "7.0.0-dev.20250523.1",
|
"version": "7.0.0-dev.20250625.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript/native-preview/-/native-preview-7.0.0-dev.20250523.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript/native-preview/-/native-preview-7.0.0-dev.20250625.1.tgz",
|
||||||
"integrity": "sha512-CgdgP/gmyaMThY7Fho19nDaTVryn9QV/zD/6w1KfDCn3M4Rq4WvkSc7Ob1ohc4V1XjCSIzg6Ul+HbLEc7xvV4Q==",
|
"integrity": "sha512-7781zmsKURCHknc37H4U4la4kZduyxmmUshZLBzNhPHhV5DKo++K8MF69kxhRG3/vS4HBhozf0YI0mZMIbkSDA==",
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsgo": "bin/tsgo.js"
|
"tsgo": "bin/tsgo.js"
|
||||||
@ -617,23 +616,22 @@
|
|||||||
"node": ">=20.6.0"
|
"node": ">=20.6.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@typescript/native-preview-darwin-arm64": "7.0.0-dev.20250523.1",
|
"@typescript/native-preview-darwin-arm64": "7.0.0-dev.20250625.1",
|
||||||
"@typescript/native-preview-darwin-x64": "7.0.0-dev.20250523.1",
|
"@typescript/native-preview-darwin-x64": "7.0.0-dev.20250625.1",
|
||||||
"@typescript/native-preview-linux-arm": "7.0.0-dev.20250523.1",
|
"@typescript/native-preview-linux-arm": "7.0.0-dev.20250625.1",
|
||||||
"@typescript/native-preview-linux-arm64": "7.0.0-dev.20250523.1",
|
"@typescript/native-preview-linux-arm64": "7.0.0-dev.20250625.1",
|
||||||
"@typescript/native-preview-linux-x64": "7.0.0-dev.20250523.1",
|
"@typescript/native-preview-linux-x64": "7.0.0-dev.20250625.1",
|
||||||
"@typescript/native-preview-win32-arm64": "7.0.0-dev.20250523.1",
|
"@typescript/native-preview-win32-arm64": "7.0.0-dev.20250625.1",
|
||||||
"@typescript/native-preview-win32-x64": "7.0.0-dev.20250523.1"
|
"@typescript/native-preview-win32-x64": "7.0.0-dev.20250625.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript/native-preview-darwin-arm64": {
|
"node_modules/@typescript/native-preview-darwin-arm64": {
|
||||||
"version": "7.0.0-dev.20250523.1",
|
"version": "7.0.0-dev.20250625.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-arm64/-/native-preview-darwin-arm64-7.0.0-dev.20250523.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-arm64/-/native-preview-darwin-arm64-7.0.0-dev.20250625.1.tgz",
|
||||||
"integrity": "sha512-oWJMPD+lfH9/dvHhPSZdTv43lfyZGrn7crytefhkiQPSwP0MIUCpnDkofGP/ML1nv0xx0pwWhH+Ein88NW3LuA==",
|
"integrity": "sha512-JcLCql0O6+0iHIMllvax02kqpNtY1RUckGKomuO5kSbrOo9PsR+6r5MEcspfj47gwOl7AS0vrGhBCFFogF+KGw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@ -644,13 +642,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript/native-preview-darwin-x64": {
|
"node_modules/@typescript/native-preview-darwin-x64": {
|
||||||
"version": "7.0.0-dev.20250523.1",
|
"version": "7.0.0-dev.20250625.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-x64/-/native-preview-darwin-x64-7.0.0-dev.20250523.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript/native-preview-darwin-x64/-/native-preview-darwin-x64-7.0.0-dev.20250625.1.tgz",
|
||||||
"integrity": "sha512-Yk8bJEsYsRKgRqYlwPvh7DPdgBMC/oPN60X0LWeuMLci65+4kyqF8Cv6K/W3ABc005cB4tYn4iR+9T6zipvrKw==",
|
"integrity": "sha512-0vCkk3FdS92W625JyzA8Slu/0vgkeu10fRQNfgIbf+E29DKMKnwXW56WhHSdGXAivU44Mewwc589+CbsABq3Sw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@ -661,13 +658,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript/native-preview-linux-arm": {
|
"node_modules/@typescript/native-preview-linux-arm": {
|
||||||
"version": "7.0.0-dev.20250523.1",
|
"version": "7.0.0-dev.20250625.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm/-/native-preview-linux-arm-7.0.0-dev.20250523.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm/-/native-preview-linux-arm-7.0.0-dev.20250625.1.tgz",
|
||||||
"integrity": "sha512-B+8CRIv6ebL8gzAagnJP8wml3baFV2FtFWuXYl6jlAcLGoQOh/yGdcAueZoJjJKNod4gAOl8OJoTicuC0BVIxw==",
|
"integrity": "sha512-MumU7p+09ikH/x5IOJRV6DUj6N5/0kSlI4IsAUPtpT2WGkQdDtL2CC523/94YvOfWB1/+9r01636LVCGOJ135g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@ -678,13 +674,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript/native-preview-linux-arm64": {
|
"node_modules/@typescript/native-preview-linux-arm64": {
|
||||||
"version": "7.0.0-dev.20250523.1",
|
"version": "7.0.0-dev.20250625.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm64/-/native-preview-linux-arm64-7.0.0-dev.20250523.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-arm64/-/native-preview-linux-arm64-7.0.0-dev.20250625.1.tgz",
|
||||||
"integrity": "sha512-IErNI08z9qE6mHaJaT6tM7il8j21ryH3DNVyFP4yz5FTKnkXFj1Kb4NcI41Q8w226LTQgBR8kNErVlbUWr7ywA==",
|
"integrity": "sha512-IgnoWQSKeoeL7Y7tvlbcDQx0nidK3UWa/bbm1zJv+AfQlAGMrEMygp+ZzocmycUCYOVM0dcIbymjoiI/QRHTng==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@ -695,13 +690,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript/native-preview-linux-x64": {
|
"node_modules/@typescript/native-preview-linux-x64": {
|
||||||
"version": "7.0.0-dev.20250523.1",
|
"version": "7.0.0-dev.20250625.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-x64/-/native-preview-linux-x64-7.0.0-dev.20250523.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript/native-preview-linux-x64/-/native-preview-linux-x64-7.0.0-dev.20250625.1.tgz",
|
||||||
"integrity": "sha512-TCZtknsLUgPRaEfX9CvBZNgrHhMRZPYYZgF1Aasdv0PONv9mB8w0Xforgxoo4UFjdF5ZzOu2icgc7sKJJeu5vw==",
|
"integrity": "sha512-6fE8piqPfzPPqmQ37ewTSbm4HW0cNqOEhfLG2F37zJd4525mefhIpWvj2iCkEHWp+BDlF2dYCbB4cY2nmfrNNw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@ -712,13 +706,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript/native-preview-win32-arm64": {
|
"node_modules/@typescript/native-preview-win32-arm64": {
|
||||||
"version": "7.0.0-dev.20250523.1",
|
"version": "7.0.0-dev.20250625.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-arm64/-/native-preview-win32-arm64-7.0.0-dev.20250523.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-arm64/-/native-preview-win32-arm64-7.0.0-dev.20250625.1.tgz",
|
||||||
"integrity": "sha512-bulwrkLEkoY4Jqeuvfz24RiVOiZZ7Rr9TblFqZAgZFZOnyXuhjM1jE8F1hnJFC5AghJe2HdLD3EKfabqlffrIw==",
|
"integrity": "sha512-ppCkjBAFotPxL8j9Vk5cNSwMreOvAt02AMa5Hko3JQGSVA2TQCIlvTFn+SHSIWzYbzomc9j4j5WOcOR0rmAAHg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@ -729,13 +722,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript/native-preview-win32-x64": {
|
"node_modules/@typescript/native-preview-win32-x64": {
|
||||||
"version": "7.0.0-dev.20250523.1",
|
"version": "7.0.0-dev.20250625.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-x64/-/native-preview-win32-x64-7.0.0-dev.20250523.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript/native-preview-win32-x64/-/native-preview-win32-x64-7.0.0-dev.20250625.1.tgz",
|
||||||
"integrity": "sha512-ztzfO0oF/rj8xO5y3SyAcigmgvgczrqobCugEWFqiYumteWZPN2MYWcNYk2k8Y5LAgg1fN1xHIg8RRSPoo6XUg==",
|
"integrity": "sha512-BsnJqso5MKAW4Y7fPmcamJ+EIrWOTqwLjeZP74NNFvTqCsA4RkITCw4NpLwD0lzrv9VsQcQ+bNwB8DrT+oDqoQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@ -3396,9 +3388,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/warframe-public-export-plus": {
|
"node_modules/warframe-public-export-plus": {
|
||||||
"version": "0.5.69",
|
"version": "0.5.71",
|
||||||
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.69.tgz",
|
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.71.tgz",
|
||||||
"integrity": "sha512-vTU1tUzqpihzpseUSJMrM82pYbCDZCfW40jXIi+Ol9B3a3Acz0DccfP7i4eoXf7Abahu4H/sjRt/nSHLNBvLHA=="
|
"integrity": "sha512-TCS2wPRsBzuURJlIMDhygAHaLsKVZ7dGuC73WZ/iMyn3gKVwA98nnaIj24D+UceWS08fwq4ilWAfUzHJd6X29A=="
|
||||||
},
|
},
|
||||||
"node_modules/warframe-riven-info": {
|
"node_modules/warframe-riven-info": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
|
10
package.json
10
package.json
@ -5,8 +5,10 @@
|
|||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node --enable-source-maps --import ./build/src/pathman.js build/src/index.js",
|
"start": "node --enable-source-maps --import ./build/src/pathman.js build/src/index.js",
|
||||||
"build": "tsc --incremental --sourceMap && ncp static/webui build/static/webui",
|
"build": "tsgo --sourceMap && ncp static/webui build/static/webui",
|
||||||
"build:dev": "tsc --incremental --sourceMap",
|
"build:tsc": "tsc --incremental --sourceMap && ncp static/webui build/static/webui",
|
||||||
|
"build:dev": "tsgo --sourceMap",
|
||||||
|
"build:dev:tsc": "tsc --incremental --sourceMap",
|
||||||
"build-and-start": "npm run build && npm run start",
|
"build-and-start": "npm run build && npm run start",
|
||||||
"build-and-start:bun": "npm run verify && npm run bun-run",
|
"build-and-start:bun": "npm run verify && npm run bun-run",
|
||||||
"dev": "node scripts/dev.js",
|
"dev": "node scripts/dev.js",
|
||||||
@ -25,6 +27,7 @@
|
|||||||
"@types/morgan": "^1.9.9",
|
"@types/morgan": "^1.9.9",
|
||||||
"@types/websocket": "^1.0.10",
|
"@types/websocket": "^1.0.10",
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
|
"@typescript/native-preview": "^7.0.0-dev.20250625.1",
|
||||||
"crc-32": "^1.2.2",
|
"crc-32": "^1.2.2",
|
||||||
"express": "^5",
|
"express": "^5",
|
||||||
"json-with-bigint": "^3.4.4",
|
"json-with-bigint": "^3.4.4",
|
||||||
@ -33,7 +36,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.69",
|
"warframe-public-export-plus": "^0.5.71",
|
||||||
"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",
|
||||||
@ -42,7 +45,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
||||||
"@typescript-eslint/parser": "^8.28.0",
|
"@typescript-eslint/parser": "^8.28.0",
|
||||||
"@typescript/native-preview": "^7.0.0-dev.20250523.1",
|
|
||||||
"chokidar": "^4.0.3",
|
"chokidar": "^4.0.3",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-plugin-prettier": "^5.2.5",
|
"eslint-plugin-prettier": "^5.2.5",
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||||
|
import { combineInventoryChanges, getInventory } from "@/src/services/inventoryService";
|
||||||
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
|
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
|
||||||
|
import { RequestHandler } from "express";
|
||||||
|
import { ExportChallenges } from "warframe-public-export-plus";
|
||||||
|
|
||||||
|
export const claimJunctionChallengeRewardController: RequestHandler = async (req, res) => {
|
||||||
|
const accountId = await getAccountIdForRequest(req);
|
||||||
|
const inventory = await getInventory(accountId);
|
||||||
|
const data = getJSONfromString<IClaimJunctionChallengeRewardRequest>(String(req.body));
|
||||||
|
const challengeProgress = inventory.ChallengeProgress.find(x => x.Name == data.Challenge)!;
|
||||||
|
if (challengeProgress.ReceivedJunctionReward) {
|
||||||
|
throw new Error(`attempt to double-claim junction reward`);
|
||||||
|
}
|
||||||
|
challengeProgress.ReceivedJunctionReward = true;
|
||||||
|
inventory.ClaimedJunctionChallengeRewards ??= [];
|
||||||
|
inventory.ClaimedJunctionChallengeRewards.push(data.Challenge);
|
||||||
|
const challengeMeta = Object.entries(ExportChallenges).find(arr => arr[0].endsWith("/" + data.Challenge))![1];
|
||||||
|
const inventoryChanges = {};
|
||||||
|
for (const reward of challengeMeta.countedRewards!) {
|
||||||
|
combineInventoryChanges(
|
||||||
|
inventoryChanges,
|
||||||
|
(await handleStoreItemAcquisition(reward.StoreItem, inventory, reward.ItemCount)).InventoryChanges
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await inventory.save();
|
||||||
|
res.json({
|
||||||
|
inventoryChanges: inventoryChanges // Yeah, it's "inventoryChanges" in the response here.
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IClaimJunctionChallengeRewardRequest {
|
||||||
|
Challenge: string;
|
||||||
|
}
|
@ -22,7 +22,8 @@ import { getNemesisManifest } from "@/src/helpers/nemesisHelpers";
|
|||||||
import { getPersonalRooms } from "@/src/services/personalRoomsService";
|
import { getPersonalRooms } from "@/src/services/personalRoomsService";
|
||||||
import { IPersonalRoomsClient } from "@/src/types/personalRoomsTypes";
|
import { IPersonalRoomsClient } from "@/src/types/personalRoomsTypes";
|
||||||
import { Ship } from "@/src/models/shipModel";
|
import { Ship } from "@/src/models/shipModel";
|
||||||
import { toLegacyOid, version_compare } from "@/src/helpers/inventoryHelpers";
|
import { toLegacyOid, toOid, version_compare } from "@/src/helpers/inventoryHelpers";
|
||||||
|
import { Inbox } from "@/src/models/inboxModel";
|
||||||
|
|
||||||
export const inventoryController: RequestHandler = async (request, response) => {
|
export const inventoryController: RequestHandler = async (request, response) => {
|
||||||
const account = await getAccountForRequest(request);
|
const account = await getAccountForRequest(request);
|
||||||
@ -128,13 +129,21 @@ export const getInventoryResponse = async (
|
|||||||
xpBasedLevelCapDisabled: boolean,
|
xpBasedLevelCapDisabled: boolean,
|
||||||
buildLabel: string | undefined
|
buildLabel: string | undefined
|
||||||
): Promise<IInventoryClient> => {
|
): Promise<IInventoryClient> => {
|
||||||
const [inventoryWithLoadOutPresets, ships] = await Promise.all([
|
const [inventoryWithLoadOutPresets, ships, latestMessage] = await Promise.all([
|
||||||
inventory.populate<{ LoadOutPresets: ILoadoutDatabase }>("LoadOutPresets"),
|
inventory.populate<{ LoadOutPresets: ILoadoutDatabase }>("LoadOutPresets"),
|
||||||
Ship.find({ ShipOwnerId: inventory.accountOwnerId })
|
Ship.find({ ShipOwnerId: inventory.accountOwnerId }),
|
||||||
|
Inbox.findOne({ ownerId: inventory.accountOwnerId }, "_id").sort({ date: -1 })
|
||||||
]);
|
]);
|
||||||
const inventoryResponse = inventoryWithLoadOutPresets.toJSON<IInventoryClient>();
|
const inventoryResponse = inventoryWithLoadOutPresets.toJSON<IInventoryClient>();
|
||||||
inventoryResponse.Ships = ships.map(x => x.toJSON<IShipInventory>());
|
inventoryResponse.Ships = ships.map(x => x.toJSON<IShipInventory>());
|
||||||
|
|
||||||
|
// In case mission inventory update added an inbox message, we need to send the Mailbox part so the client knows to refresh it.
|
||||||
|
if (latestMessage) {
|
||||||
|
inventoryResponse.Mailbox = {
|
||||||
|
LastInboxId: toOid(latestMessage._id)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (config.infiniteCredits) {
|
if (config.infiniteCredits) {
|
||||||
inventoryResponse.RegularCredits = 999999999;
|
inventoryResponse.RegularCredits = 999999999;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
|
import { getInventory, addRecipes } from "@/src/services/inventoryService";
|
||||||
|
import { RequestHandler } from "express";
|
||||||
|
import { ExportRecipes } from "warframe-public-export-plus";
|
||||||
|
|
||||||
|
export const addMissingHelminthBlueprintsController: RequestHandler = async (req, res) => {
|
||||||
|
const accountId = await getAccountIdForRequest(req);
|
||||||
|
const inventory = await getInventory(accountId, "Recipes");
|
||||||
|
const allHelminthRecipes = Object.keys(ExportRecipes).filter(
|
||||||
|
key => ExportRecipes[key].secretIngredientAction === "SIA_WARFRAME_ABILITY"
|
||||||
|
);
|
||||||
|
const inventoryHelminthRecipes = inventory.Recipes.filter(recipe =>
|
||||||
|
recipe.ItemType.startsWith("/Lotus/Types/Recipes/AbilityOverrides/")
|
||||||
|
).map(recipe => recipe.ItemType);
|
||||||
|
|
||||||
|
const missingHelminthRecipes = allHelminthRecipes
|
||||||
|
.filter(key => !inventoryHelminthRecipes.includes(key))
|
||||||
|
.map(ItemType => ({ ItemType, ItemCount: 1 }));
|
||||||
|
|
||||||
|
addRecipes(inventory, missingHelminthRecipes);
|
||||||
|
|
||||||
|
await inventory.save();
|
||||||
|
res.end();
|
||||||
|
};
|
@ -12,18 +12,24 @@ export const completeAllMissionsController: RequestHandler = async (req, res) =>
|
|||||||
const inventory = await getInventory(accountId);
|
const inventory = await getInventory(accountId);
|
||||||
const MissionRewards: IMissionReward[] = [];
|
const MissionRewards: IMissionReward[] = [];
|
||||||
for (const [tag, node] of Object.entries(ExportRegions)) {
|
for (const [tag, node] of Object.entries(ExportRegions)) {
|
||||||
if (!inventory.Missions.find(x => x.Tag == tag)) {
|
let mission = inventory.Missions.find(x => x.Tag == tag);
|
||||||
inventory.Missions.push({
|
if (!mission) {
|
||||||
Completes: 1,
|
mission =
|
||||||
Tier: 1,
|
inventory.Missions[
|
||||||
Tag: tag
|
inventory.Missions.push({
|
||||||
});
|
Completes: 0,
|
||||||
|
Tier: 0,
|
||||||
|
Tag: tag
|
||||||
|
}) - 1
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (mission.Completes == 0) {
|
||||||
|
mission.Completes++;
|
||||||
if (node.missionReward) {
|
if (node.missionReward) {
|
||||||
console.log(node.missionReward);
|
|
||||||
addFixedLevelRewards(node.missionReward, inventory, MissionRewards);
|
addFixedLevelRewards(node.missionReward, inventory, MissionRewards);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mission.Tier = 1;
|
||||||
}
|
}
|
||||||
for (const reward of MissionRewards) {
|
for (const reward of MissionRewards) {
|
||||||
await handleStoreItemAcquisition(reward.StoreItem, inventory, reward.ItemCount, undefined, true);
|
await handleStoreItemAcquisition(reward.StoreItem, inventory, reward.ItemCount, undefined, true);
|
||||||
|
@ -21,13 +21,14 @@ import mongoose from "mongoose";
|
|||||||
import { JSONStringify } from "json-with-bigint";
|
import { JSONStringify } from "json-with-bigint";
|
||||||
import { startWebServer } from "./services/webService";
|
import { startWebServer } from "./services/webService";
|
||||||
|
|
||||||
import { validateConfig } from "@/src/services/configWatcherService";
|
import { syncConfigWithDatabase, validateConfig } from "@/src/services/configWatcherService";
|
||||||
import { updateWorldStateCollections } from "./services/worldStateService";
|
import { updateWorldStateCollections } from "./services/worldStateService";
|
||||||
|
|
||||||
// Patch JSON.stringify to work flawlessly with Bigints.
|
// Patch JSON.stringify to work flawlessly with Bigints.
|
||||||
JSON.stringify = JSONStringify;
|
JSON.stringify = JSONStringify;
|
||||||
|
|
||||||
validateConfig();
|
validateConfig();
|
||||||
|
syncConfigWithDatabase();
|
||||||
|
|
||||||
mongoose
|
mongoose
|
||||||
.connect(config.mongodbUrl)
|
.connect(config.mongodbUrl)
|
||||||
|
@ -27,11 +27,12 @@ export interface IMessage {
|
|||||||
icon?: string;
|
icon?: string;
|
||||||
highPriority?: boolean;
|
highPriority?: boolean;
|
||||||
lowPrioNewPlayers?: boolean;
|
lowPrioNewPlayers?: boolean;
|
||||||
startDate?: Date;
|
transmission?: string;
|
||||||
endDate?: Date;
|
|
||||||
att?: string[];
|
att?: string[];
|
||||||
countedAtt?: ITypeCount[];
|
countedAtt?: ITypeCount[];
|
||||||
transmission?: string;
|
startDate?: Date;
|
||||||
|
endDate?: Date;
|
||||||
|
goalTag?: string;
|
||||||
CrossPlatform?: boolean;
|
CrossPlatform?: boolean;
|
||||||
arg?: Arg[];
|
arg?: Arg[];
|
||||||
gifts?: IGift[];
|
gifts?: IGift[];
|
||||||
@ -107,6 +108,7 @@ const messageSchema = new Schema<IMessageDatabase>(
|
|||||||
lowPrioNewPlayers: Boolean,
|
lowPrioNewPlayers: Boolean,
|
||||||
startDate: Date,
|
startDate: Date,
|
||||||
endDate: Date,
|
endDate: Date,
|
||||||
|
goalTag: String,
|
||||||
date: { type: Date, required: true },
|
date: { type: Date, required: true },
|
||||||
r: Boolean,
|
r: Boolean,
|
||||||
CrossPlatform: Boolean,
|
CrossPlatform: Boolean,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Document, HydratedDocument, Model, Schema, Types, model } from "mongoose";
|
import { Document, Model, Schema, Types, model } from "mongoose";
|
||||||
import {
|
import {
|
||||||
IFlavourItem,
|
IFlavourItem,
|
||||||
IRawUpgrade,
|
IRawUpgrade,
|
||||||
@ -7,7 +7,6 @@ import {
|
|||||||
IBooster,
|
IBooster,
|
||||||
IInventoryClient,
|
IInventoryClient,
|
||||||
ISlots,
|
ISlots,
|
||||||
IMailboxDatabase,
|
|
||||||
IDuviriInfo,
|
IDuviriInfo,
|
||||||
IPendingRecipeDatabase,
|
IPendingRecipeDatabase,
|
||||||
IPendingRecipeClient,
|
IPendingRecipeClient,
|
||||||
@ -54,7 +53,6 @@ import {
|
|||||||
IUpgradeDatabase,
|
IUpgradeDatabase,
|
||||||
ICrewShipMemberDatabase,
|
ICrewShipMemberDatabase,
|
||||||
ICrewShipMemberClient,
|
ICrewShipMemberClient,
|
||||||
IMailboxClient,
|
|
||||||
TEquipmentKey,
|
TEquipmentKey,
|
||||||
equipmentKeys,
|
equipmentKeys,
|
||||||
IKubrowPetDetailsDatabase,
|
IKubrowPetDetailsDatabase,
|
||||||
@ -99,7 +97,9 @@ import {
|
|||||||
IAccolades,
|
IAccolades,
|
||||||
IHubNpcCustomization,
|
IHubNpcCustomization,
|
||||||
ILotusCustomization,
|
ILotusCustomization,
|
||||||
IEndlessXpReward
|
IEndlessXpReward,
|
||||||
|
IPersonalGoalProgressDatabase,
|
||||||
|
IPersonalGoalProgressClient
|
||||||
} from "../../types/inventoryTypes/inventoryTypes";
|
} from "../../types/inventoryTypes/inventoryTypes";
|
||||||
import { IOid } from "../../types/commonTypes";
|
import { IOid } from "../../types/commonTypes";
|
||||||
import {
|
import {
|
||||||
@ -371,7 +371,7 @@ FlavourItemSchema.set("toJSON", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const MailboxSchema = new Schema<IMailboxDatabase>(
|
/*const MailboxSchema = new Schema<IMailboxDatabase>(
|
||||||
{
|
{
|
||||||
LastInboxId: Schema.Types.ObjectId
|
LastInboxId: Schema.Types.ObjectId
|
||||||
},
|
},
|
||||||
@ -384,7 +384,7 @@ MailboxSchema.set("toJSON", {
|
|||||||
delete mailboxDatabase.__v;
|
delete mailboxDatabase.__v;
|
||||||
(returnedObject as IMailboxClient).LastInboxId = toOid(mailboxDatabase.LastInboxId);
|
(returnedObject as IMailboxClient).LastInboxId = toOid(mailboxDatabase.LastInboxId);
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
|
|
||||||
const DuviriInfoSchema = new Schema<IDuviriInfo>(
|
const DuviriInfoSchema = new Schema<IDuviriInfo>(
|
||||||
{
|
{
|
||||||
@ -457,11 +457,35 @@ const discoveredMarkerSchema = new Schema<IDiscoveredMarker>(
|
|||||||
{ _id: false }
|
{ _id: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const personalGoalProgressSchema = new Schema<IPersonalGoalProgressDatabase>(
|
||||||
|
{
|
||||||
|
Best: Number,
|
||||||
|
Count: Number,
|
||||||
|
Tag: String,
|
||||||
|
goalId: Types.ObjectId
|
||||||
|
},
|
||||||
|
{ _id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
personalGoalProgressSchema.set("toJSON", {
|
||||||
|
virtuals: true,
|
||||||
|
transform(_doc, obj) {
|
||||||
|
const db = obj as IPersonalGoalProgressDatabase;
|
||||||
|
const client = obj as IPersonalGoalProgressClient;
|
||||||
|
|
||||||
|
client._id = toOid(db.goalId);
|
||||||
|
|
||||||
|
delete obj.goalId;
|
||||||
|
delete obj.__v;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const challengeProgressSchema = new Schema<IChallengeProgress>(
|
const challengeProgressSchema = new Schema<IChallengeProgress>(
|
||||||
{
|
{
|
||||||
Progress: Number,
|
Progress: Number,
|
||||||
Name: String,
|
Completed: { type: [String], default: undefined },
|
||||||
Completed: [String]
|
ReceivedJunctionReward: Boolean,
|
||||||
|
Name: { type: String, required: true }
|
||||||
},
|
},
|
||||||
{ _id: false }
|
{ _id: false }
|
||||||
);
|
);
|
||||||
@ -1630,7 +1654,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
//CompletedJobs: [Schema.Types.Mixed],
|
//CompletedJobs: [Schema.Types.Mixed],
|
||||||
|
|
||||||
//Game mission\ivent score example "Tag": "WaterFight", "Best": 170, "Count": 1258,
|
//Game mission\ivent score example "Tag": "WaterFight", "Best": 170, "Count": 1258,
|
||||||
//PersonalGoalProgress: [Schema.Types.Mixed],
|
PersonalGoalProgress: { type: [personalGoalProgressSchema], default: undefined },
|
||||||
|
|
||||||
//Setting interface Style
|
//Setting interface Style
|
||||||
ThemeStyle: String,
|
ThemeStyle: String,
|
||||||
@ -1701,7 +1725,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
//Unknown and system
|
//Unknown and system
|
||||||
DuviriInfo: DuviriInfoSchema,
|
DuviriInfo: DuviriInfoSchema,
|
||||||
LastInventorySync: Schema.Types.ObjectId,
|
LastInventorySync: Schema.Types.ObjectId,
|
||||||
Mailbox: MailboxSchema,
|
//Mailbox: MailboxSchema,
|
||||||
HandlerPoints: Number,
|
HandlerPoints: Number,
|
||||||
ChallengesFixVersion: Number,
|
ChallengesFixVersion: Number,
|
||||||
PlayedParkourTutorial: Boolean,
|
PlayedParkourTutorial: Boolean,
|
||||||
@ -1754,7 +1778,9 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
BrandedSuits: { type: [Schema.Types.ObjectId], default: undefined },
|
BrandedSuits: { type: [Schema.Types.ObjectId], default: undefined },
|
||||||
LockedWeaponGroup: { type: lockedWeaponGroupSchema, default: undefined },
|
LockedWeaponGroup: { type: lockedWeaponGroupSchema, default: undefined },
|
||||||
|
|
||||||
HubNpcCustomizations: { type: [hubNpcCustomizationSchema], default: undefined }
|
HubNpcCustomizations: { type: [hubNpcCustomizationSchema], default: undefined },
|
||||||
|
|
||||||
|
ClaimedJunctionChallengeRewards: { type: [String], default: undefined }
|
||||||
},
|
},
|
||||||
{ timestamps: { createdAt: "Created", updatedAt: false } }
|
{ timestamps: { createdAt: "Created", updatedAt: false } }
|
||||||
);
|
);
|
||||||
|
@ -40,6 +40,7 @@ const placedDecosSchema = new Schema<IPlacedDecosDatabase>(
|
|||||||
Pos: [Number],
|
Pos: [Number],
|
||||||
Rot: [Number],
|
Rot: [Number],
|
||||||
Scale: Number,
|
Scale: Number,
|
||||||
|
Sockets: Number,
|
||||||
PictureFrameInfo: { type: pictureFrameInfoSchema, default: undefined }
|
PictureFrameInfo: { type: pictureFrameInfoSchema, default: undefined }
|
||||||
},
|
},
|
||||||
{ id: false }
|
{ id: false }
|
||||||
|
@ -19,6 +19,7 @@ import { changeDojoRootController } from "@/src/controllers/api/changeDojoRootCo
|
|||||||
import { changeGuildRankController } from "@/src/controllers/api/changeGuildRankController";
|
import { changeGuildRankController } from "@/src/controllers/api/changeGuildRankController";
|
||||||
import { checkDailyMissionBonusController } from "@/src/controllers/api/checkDailyMissionBonusController";
|
import { checkDailyMissionBonusController } from "@/src/controllers/api/checkDailyMissionBonusController";
|
||||||
import { claimCompletedRecipeController } from "@/src/controllers/api/claimCompletedRecipeController";
|
import { claimCompletedRecipeController } from "@/src/controllers/api/claimCompletedRecipeController";
|
||||||
|
import { claimJunctionChallengeRewardController } from "@/src/controllers/api/claimJunctionChallengeRewardController";
|
||||||
import { claimLibraryDailyTaskRewardController } from "@/src/controllers/api/claimLibraryDailyTaskRewardController";
|
import { claimLibraryDailyTaskRewardController } from "@/src/controllers/api/claimLibraryDailyTaskRewardController";
|
||||||
import { clearDialogueHistoryController } from "@/src/controllers/api/clearDialogueHistoryController";
|
import { clearDialogueHistoryController } from "@/src/controllers/api/clearDialogueHistoryController";
|
||||||
import { clearNewEpisodeRewardController } from "@/src/controllers/api/clearNewEpisodeRewardController";
|
import { clearNewEpisodeRewardController } from "@/src/controllers/api/clearNewEpisodeRewardController";
|
||||||
@ -237,6 +238,7 @@ apiRouter.post("/artifacts.php", artifactsController);
|
|||||||
apiRouter.post("/artifactTransmutation.php", artifactTransmutationController);
|
apiRouter.post("/artifactTransmutation.php", artifactTransmutationController);
|
||||||
apiRouter.post("/changeDojoRoot.php", changeDojoRootController);
|
apiRouter.post("/changeDojoRoot.php", changeDojoRootController);
|
||||||
apiRouter.post("/claimCompletedRecipe.php", claimCompletedRecipeController);
|
apiRouter.post("/claimCompletedRecipe.php", claimCompletedRecipeController);
|
||||||
|
apiRouter.post("/claimJunctionChallengeReward.php", claimJunctionChallengeRewardController);
|
||||||
apiRouter.post("/clearDialogueHistory.php", clearDialogueHistoryController);
|
apiRouter.post("/clearDialogueHistory.php", clearDialogueHistoryController);
|
||||||
apiRouter.post("/clearNewEpisodeReward.php", clearNewEpisodeRewardController);
|
apiRouter.post("/clearNewEpisodeReward.php", clearNewEpisodeRewardController);
|
||||||
apiRouter.post("/commitStoryModeDecision.php", (_req, res) => { res.end(); }); // U14 (maybe wanna actually unlock the ship features?)
|
apiRouter.post("/commitStoryModeDecision.php", (_req, res) => { res.end(); }); // U14 (maybe wanna actually unlock the ship features?)
|
||||||
|
@ -13,6 +13,7 @@ import { unlockAllIntrinsicsController } from "@/src/controllers/custom/unlockAl
|
|||||||
import { addMissingMaxRankModsController } from "@/src/controllers/custom/addMissingMaxRankModsController";
|
import { addMissingMaxRankModsController } from "@/src/controllers/custom/addMissingMaxRankModsController";
|
||||||
import { webuiFileChangeDetectedController } from "@/src/controllers/custom/webuiFileChangeDetectedController";
|
import { webuiFileChangeDetectedController } from "@/src/controllers/custom/webuiFileChangeDetectedController";
|
||||||
import { completeAllMissionsController } from "@/src/controllers/custom/completeAllMissionsController";
|
import { completeAllMissionsController } from "@/src/controllers/custom/completeAllMissionsController";
|
||||||
|
import { addMissingHelminthBlueprintsController } from "@/src/controllers/custom/addMissingHelminthBlueprintsController";
|
||||||
|
|
||||||
import { createAccountController } from "@/src/controllers/custom/createAccountController";
|
import { createAccountController } from "@/src/controllers/custom/createAccountController";
|
||||||
import { createMessageController } from "@/src/controllers/custom/createMessageController";
|
import { createMessageController } from "@/src/controllers/custom/createMessageController";
|
||||||
@ -42,6 +43,7 @@ customRouter.get("/unlockAllIntrinsics", unlockAllIntrinsicsController);
|
|||||||
customRouter.get("/addMissingMaxRankMods", addMissingMaxRankModsController);
|
customRouter.get("/addMissingMaxRankMods", addMissingMaxRankModsController);
|
||||||
customRouter.get("/webuiFileChangeDetected", webuiFileChangeDetectedController);
|
customRouter.get("/webuiFileChangeDetected", webuiFileChangeDetectedController);
|
||||||
customRouter.get("/completeAllMissions", completeAllMissionsController);
|
customRouter.get("/completeAllMissions", completeAllMissionsController);
|
||||||
|
customRouter.get("/addMissingHelminthBlueprints", addMissingHelminthBlueprintsController);
|
||||||
|
|
||||||
customRouter.post("/createAccount", createAccountController);
|
customRouter.post("/createAccount", createAccountController);
|
||||||
customRouter.post("/createMessage", createMessageController);
|
customRouter.post("/createMessage", createMessageController);
|
||||||
|
@ -76,6 +76,7 @@ export interface IConfig {
|
|||||||
affinityBoost?: boolean;
|
affinityBoost?: boolean;
|
||||||
resourceBoost?: boolean;
|
resourceBoost?: boolean;
|
||||||
starDays?: boolean;
|
starDays?: boolean;
|
||||||
|
galleonOfGhouls?: number;
|
||||||
eidolonOverride?: string;
|
eidolonOverride?: string;
|
||||||
vallisOverride?: string;
|
vallisOverride?: string;
|
||||||
duviriOverride?: string;
|
duviriOverride?: string;
|
||||||
|
@ -3,6 +3,7 @@ import fsPromises from "fs/promises";
|
|||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { config, configPath, loadConfig } from "./configService";
|
import { config, configPath, loadConfig } from "./configService";
|
||||||
import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./webService";
|
import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./webService";
|
||||||
|
import { Inbox } from "../models/inboxModel";
|
||||||
|
|
||||||
let amnesia = false;
|
let amnesia = false;
|
||||||
fs.watchFile(configPath, (now, then) => {
|
fs.watchFile(configPath, (now, then) => {
|
||||||
@ -22,6 +23,7 @@ fs.watchFile(configPath, (now, then) => {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
validateConfig();
|
validateConfig();
|
||||||
|
syncConfigWithDatabase();
|
||||||
|
|
||||||
const webPorts = getWebPorts();
|
const webPorts = getWebPorts();
|
||||||
if (config.httpPort != webPorts.http || config.httpsPort != webPorts.https) {
|
if (config.httpPort != webPorts.http || config.httpsPort != webPorts.https) {
|
||||||
@ -51,6 +53,15 @@ export const validateConfig = (): void => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
config.worldState?.galleonOfGhouls &&
|
||||||
|
config.worldState.galleonOfGhouls != 1 &&
|
||||||
|
config.worldState.galleonOfGhouls != 2 &&
|
||||||
|
config.worldState.galleonOfGhouls != 3
|
||||||
|
) {
|
||||||
|
config.worldState.galleonOfGhouls = 0;
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
if (modified) {
|
if (modified) {
|
||||||
logger.info(`Updating config file to fix some issues with it.`);
|
logger.info(`Updating config file to fix some issues with it.`);
|
||||||
void saveConfig();
|
void saveConfig();
|
||||||
@ -61,3 +72,10 @@ export const saveConfig = async (): Promise<void> => {
|
|||||||
amnesia = true;
|
amnesia = true;
|
||||||
await fsPromises.writeFile(configPath, JSON.stringify(config, null, 2));
|
await fsPromises.writeFile(configPath, JSON.stringify(config, null, 2));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const syncConfigWithDatabase = (): void => {
|
||||||
|
// Event messages are deleted after endDate. Since we don't use beginDate/endDate and instead have config toggles, we need to delete the messages once those bools are false.
|
||||||
|
if (!config.worldState?.galleonOfGhouls) {
|
||||||
|
void Inbox.deleteMany({ goalTag: "GalleonRobbery" }).then(() => {}); // For some reason, I can't just do `Inbox.deleteMany(...)`; it needs this whole circus.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -54,6 +54,22 @@ export const createNewEventMessages = async (req: Request): Promise<void> => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BUG: Deleting the inbox message manually means it'll just be automatically re-created. This is because we don't use startDate/endDate for these config-toggled events.
|
||||||
|
if (config.worldState?.galleonOfGhouls) {
|
||||||
|
if (!(await Inbox.exists({ ownerId: account._id, goalTag: "GalleonRobbery" }))) {
|
||||||
|
newEventMessages.push({
|
||||||
|
sndr: "/Lotus/Language/Bosses/BossCouncilorVayHek",
|
||||||
|
sub: "/Lotus/Language/Events/GalleonRobberyIntroMsgTitle",
|
||||||
|
msg: "/Lotus/Language/Events/GalleonRobberyIntroMsgDesc",
|
||||||
|
icon: "/Lotus/Interface/Icons/Npcs/VayHekPortrait.png",
|
||||||
|
transmission: "/Lotus/Sounds/Dialog/GalleonOfGhouls/DGhoulsWeekOneInbox0010VayHek",
|
||||||
|
att: ["/Lotus/Upgrades/Skins/Events/OgrisOldSchool"],
|
||||||
|
startDate: new Date(),
|
||||||
|
goalTag: "GalleonRobbery"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newEventMessages.length === 0) {
|
if (newEventMessages.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ import {
|
|||||||
import { updateQuestKey } from "@/src/services/questService";
|
import { updateQuestKey } from "@/src/services/questService";
|
||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import { IAffiliationMods, IInventoryChanges } from "@/src/types/purchaseTypes";
|
import { IAffiliationMods, IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||||
import { fromStoreItem, getLevelKeyRewards, toStoreItem } from "@/src/services/itemDataService";
|
import { fromStoreItem, getLevelKeyRewards, isStoreItem, toStoreItem } from "@/src/services/itemDataService";
|
||||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
||||||
import { getEntriesUnsafe } from "@/src/utils/ts-utils";
|
import { getEntriesUnsafe } from "@/src/utils/ts-utils";
|
||||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||||
@ -609,6 +609,47 @@ export const addMissionInventoryUpdates = async (
|
|||||||
inventoryChanges.RegularCredits -= value;
|
inventoryChanges.RegularCredits -= value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "GoalProgress": {
|
||||||
|
for (const uploadProgress of value) {
|
||||||
|
const goal = getWorldState().Goals.find(x => x._id.$oid == uploadProgress._id.$oid);
|
||||||
|
if (goal && goal.Personal) {
|
||||||
|
inventory.PersonalGoalProgress ??= [];
|
||||||
|
const goalProgress = inventory.PersonalGoalProgress.find(x => x.goalId.equals(goal._id.$oid));
|
||||||
|
if (goalProgress) {
|
||||||
|
goalProgress.Best = Math.max(goalProgress.Best, uploadProgress.Best);
|
||||||
|
goalProgress.Count += uploadProgress.Count;
|
||||||
|
} else {
|
||||||
|
inventory.PersonalGoalProgress.push({
|
||||||
|
Best: uploadProgress.Best,
|
||||||
|
Count: uploadProgress.Count,
|
||||||
|
Tag: goal.Tag,
|
||||||
|
goalId: new Types.ObjectId(goal._id.$oid)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
goal.Reward &&
|
||||||
|
goal.Reward.items &&
|
||||||
|
goal.MissionKeyName &&
|
||||||
|
goal.MissionKeyName in goalMessagesByKey
|
||||||
|
) {
|
||||||
|
// Send reward via inbox
|
||||||
|
const info = goalMessagesByKey[goal.MissionKeyName];
|
||||||
|
await createMessage(inventory.accountOwnerId, [
|
||||||
|
{
|
||||||
|
sndr: info.sndr,
|
||||||
|
msg: info.msg,
|
||||||
|
att: goal.Reward.items.map(x => (isStoreItem(x) ? fromStoreItem(x) : x)),
|
||||||
|
sub: info.sub,
|
||||||
|
icon: info.icon,
|
||||||
|
highPriority: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "InvasionProgress": {
|
case "InvasionProgress": {
|
||||||
for (const clientProgress of value) {
|
for (const clientProgress of value) {
|
||||||
const dbProgress = inventory.QualifyingInvasions.find(x =>
|
const dbProgress = inventory.QualifyingInvasions.find(x =>
|
||||||
@ -962,6 +1003,14 @@ export const addMissionRewards = async (
|
|||||||
|
|
||||||
let missionCompletionCredits = 0;
|
let missionCompletionCredits = 0;
|
||||||
//inventory change is what the client has not rewarded itself, also the client needs to know the credit changes for display
|
//inventory change is what the client has not rewarded itself, also the client needs to know the credit changes for display
|
||||||
|
|
||||||
|
if (rewardInfo.goalId) {
|
||||||
|
const goal = getWorldState().Goals.find(x => x._id.$oid == rewardInfo.goalId);
|
||||||
|
if (goal?.MissionKeyName) {
|
||||||
|
levelKeyName = goal.MissionKeyName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (levelKeyName) {
|
if (levelKeyName) {
|
||||||
const fixedLevelRewards = getLevelKeyRewards(levelKeyName);
|
const fixedLevelRewards = getLevelKeyRewards(levelKeyName);
|
||||||
//logger.debug(`fixedLevelRewards ${fixedLevelRewards}`);
|
//logger.debug(`fixedLevelRewards ${fixedLevelRewards}`);
|
||||||
@ -1978,3 +2027,24 @@ const getHexBounties = (seed: number): { nodes: string[]; buddies: string[] } =>
|
|||||||
}
|
}
|
||||||
return { nodes, buddies };
|
return { nodes, buddies };
|
||||||
};*/
|
};*/
|
||||||
|
|
||||||
|
const goalMessagesByKey: Record<string, { sndr: string; msg: string; sub: string; icon: string }> = {
|
||||||
|
"/Lotus/Types/Keys/GalleonRobberyAlert": {
|
||||||
|
sndr: "/Lotus/Language/Bosses/BossCouncilorVayHek",
|
||||||
|
msg: "/Lotus/Language/Messages/GalleonRobbery2025RewardMsgA",
|
||||||
|
sub: "/Lotus/Language/Messages/GalleonRobbery2025MissionTitleA",
|
||||||
|
icon: "/Lotus/Interface/Icons/Npcs/VayHekPortrait.png"
|
||||||
|
},
|
||||||
|
"/Lotus/Types/Keys/GalleonRobberyAlertB": {
|
||||||
|
sndr: "/Lotus/Language/Bosses/BossCouncilorVayHek",
|
||||||
|
msg: "/Lotus/Language/Messages/GalleonRobbery2025RewardMsgB",
|
||||||
|
sub: "/Lotus/Language/Messages/GalleonRobbery2025MissionTitleB",
|
||||||
|
icon: "/Lotus/Interface/Icons/Npcs/VayHekPortrait.png"
|
||||||
|
},
|
||||||
|
"/Lotus/Types/Keys/GalleonRobberyAlertC": {
|
||||||
|
sndr: "/Lotus/Language/Bosses/BossCouncilorVayHek",
|
||||||
|
msg: "/Lotus/Language/Messages/GalleonRobbery2025RewardMsgC",
|
||||||
|
sub: "/Lotus/Language/Messages/GalleonRobbery2025MissionTitleC",
|
||||||
|
icon: "/Lotus/Interface/Icons/Npcs/VayHekPortrait.png"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -107,6 +107,16 @@ export class SRng {
|
|||||||
return arr[this.randomInt(0, arr.length - 1)];
|
return arr[this.randomInt(0, arr.length - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
randomElementPop<T>(arr: T[]): T | undefined {
|
||||||
|
if (arr.length != 0) {
|
||||||
|
const index = this.randomInt(0, arr.length - 1);
|
||||||
|
const elm = arr[index];
|
||||||
|
arr.splice(index, 1);
|
||||||
|
return elm;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
randomFloat(): number {
|
randomFloat(): number {
|
||||||
this.state = (0x5851f42d4c957f2dn * this.state + 0x14057b7ef767814fn) & 0xffffffffffffffffn;
|
this.state = (0x5851f42d4c957f2dn * this.state + 0x14057b7ef767814fn) & 0xffffffffffffffffn;
|
||||||
return (Number(this.state >> 38n) & 0xffffff) * 0.000000059604645;
|
return (Number(this.state >> 38n) & 0xffffff) * 0.000000059604645;
|
||||||
|
@ -8,11 +8,12 @@ import {
|
|||||||
} from "@/src/types/shipTypes";
|
} from "@/src/types/shipTypes";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import { addShipDecorations, getInventory } from "./inventoryService";
|
import { addFusionTreasures, addShipDecorations, getInventory } from "./inventoryService";
|
||||||
import { config } from "./configService";
|
import { config } from "./configService";
|
||||||
import { Guild } from "../models/guildModel";
|
import { Guild } from "../models/guildModel";
|
||||||
import { hasGuildPermission } from "./guildService";
|
import { hasGuildPermission } from "./guildService";
|
||||||
import { GuildPermission } from "../types/guildTypes";
|
import { GuildPermission } from "../types/guildTypes";
|
||||||
|
import { ExportResources } from "warframe-public-export-plus";
|
||||||
|
|
||||||
export const setShipCustomizations = async (
|
export const setShipCustomizations = async (
|
||||||
accountId: string,
|
accountId: string,
|
||||||
@ -101,6 +102,7 @@ export const handleSetShipDecorations = async (
|
|||||||
Pos: placedDecoration.Pos,
|
Pos: placedDecoration.Pos,
|
||||||
Rot: placedDecoration.Rot,
|
Rot: placedDecoration.Rot,
|
||||||
Scale: placedDecoration.Scale,
|
Scale: placedDecoration.Scale,
|
||||||
|
Sockets: placedDecoration.Sockets,
|
||||||
_id: placedDecoration.MoveId
|
_id: placedDecoration.MoveId
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -116,12 +118,19 @@ export const handleSetShipDecorations = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (placedDecoration.RemoveId) {
|
if (placedDecoration.RemoveId) {
|
||||||
roomToPlaceIn.PlacedDecos.pull({ _id: placedDecoration.RemoveId });
|
const decoIndex = roomToPlaceIn.PlacedDecos.findIndex(x => x._id.equals(placedDecoration.RemoveId));
|
||||||
|
const deco = roomToPlaceIn.PlacedDecos[decoIndex];
|
||||||
|
roomToPlaceIn.PlacedDecos.splice(decoIndex, 1);
|
||||||
await personalRooms.save();
|
await personalRooms.save();
|
||||||
|
|
||||||
if (!config.unlockAllShipDecorations) {
|
if (!config.unlockAllShipDecorations) {
|
||||||
const inventory = await getInventory(accountId);
|
const inventory = await getInventory(accountId);
|
||||||
addShipDecorations(inventory, [{ ItemType: placedDecoration.Type, ItemCount: 1 }]);
|
const itemType = Object.entries(ExportResources).find(arr => arr[1].deco == deco.Type)![0];
|
||||||
|
if (deco.Sockets !== undefined) {
|
||||||
|
addFusionTreasures(inventory, [{ ItemType: itemType, Sockets: deco.Sockets, ItemCount: 1 }]);
|
||||||
|
} else {
|
||||||
|
addShipDecorations(inventory, [{ ItemType: itemType, ItemCount: 1 }]);
|
||||||
|
}
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +143,14 @@ export const handleSetShipDecorations = async (
|
|||||||
} else {
|
} else {
|
||||||
if (!config.unlockAllShipDecorations) {
|
if (!config.unlockAllShipDecorations) {
|
||||||
const inventory = await getInventory(accountId);
|
const inventory = await getInventory(accountId);
|
||||||
addShipDecorations(inventory, [{ ItemType: placedDecoration.Type, ItemCount: -1 }]);
|
const itemType = Object.entries(ExportResources).find(arr => arr[1].deco == placedDecoration.Type)![0];
|
||||||
|
if (placedDecoration.Sockets !== undefined) {
|
||||||
|
addFusionTreasures(inventory, [
|
||||||
|
{ ItemType: itemType, Sockets: placedDecoration.Sockets, ItemCount: -1 }
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
addShipDecorations(inventory, [{ ItemType: itemType, ItemCount: -1 }]);
|
||||||
|
}
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,6 +164,7 @@ export const handleSetShipDecorations = async (
|
|||||||
Pos: placedDecoration.Pos,
|
Pos: placedDecoration.Pos,
|
||||||
Rot: placedDecoration.Rot,
|
Rot: placedDecoration.Rot,
|
||||||
Scale: placedDecoration.Scale,
|
Scale: placedDecoration.Scale,
|
||||||
|
Sockets: placedDecoration.Sockets,
|
||||||
_id: decoId
|
_id: decoId
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ const sortieBossNode: Record<Exclude<TSortieBoss, "SORTIE_BOSS_CORRUPTED_VOR">,
|
|||||||
SORTIE_BOSS_VOR: "SolNode108"
|
SORTIE_BOSS_VOR: "SolNode108"
|
||||||
};
|
};
|
||||||
|
|
||||||
const eidolonJobs = [
|
const eidolonJobs: readonly string[] = [
|
||||||
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyAss",
|
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyAss",
|
||||||
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyCap",
|
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyCap",
|
||||||
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountySab",
|
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountySab",
|
||||||
@ -117,14 +117,14 @@ const eidolonJobs = [
|
|||||||
"/Lotus/Types/Gameplay/Eidolon/Jobs/RescueBountyResc"
|
"/Lotus/Types/Gameplay/Eidolon/Jobs/RescueBountyResc"
|
||||||
];
|
];
|
||||||
|
|
||||||
const eidolonNarmerJobs = [
|
const eidolonNarmerJobs: readonly string[] = [
|
||||||
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AssassinateBountyAss",
|
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AssassinateBountyAss",
|
||||||
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyExt",
|
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyExt",
|
||||||
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/ReclamationBountyTheft",
|
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/ReclamationBountyTheft",
|
||||||
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyLib"
|
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyLib"
|
||||||
];
|
];
|
||||||
|
|
||||||
const venusJobs = [
|
const venusJobs: readonly string[] = [
|
||||||
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobAmbush",
|
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobAmbush",
|
||||||
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobExcavation",
|
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobExcavation",
|
||||||
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobRecovery",
|
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobRecovery",
|
||||||
@ -150,14 +150,14 @@ const venusJobs = [
|
|||||||
"/Lotus/Types/Gameplay/Venus/Jobs/VenusWetworkJobSpy"
|
"/Lotus/Types/Gameplay/Venus/Jobs/VenusWetworkJobSpy"
|
||||||
];
|
];
|
||||||
|
|
||||||
const venusNarmerJobs = [
|
const venusNarmerJobs: readonly string[] = [
|
||||||
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobAssassinate",
|
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobAssassinate",
|
||||||
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobExterminate",
|
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobExterminate",
|
||||||
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusPreservationJobDefense",
|
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusPreservationJobDefense",
|
||||||
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusTheftJobExcavation"
|
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusTheftJobExcavation"
|
||||||
];
|
];
|
||||||
|
|
||||||
const microplanetJobs = [
|
const microplanetJobs: readonly string[] = [
|
||||||
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAreaDefenseBounty",
|
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAreaDefenseBounty",
|
||||||
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAssassinateBounty",
|
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAssassinateBounty",
|
||||||
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosCrpSurvivorBounty",
|
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosCrpSurvivorBounty",
|
||||||
@ -167,7 +167,7 @@ const microplanetJobs = [
|
|||||||
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosPurifyBounty"
|
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosPurifyBounty"
|
||||||
];
|
];
|
||||||
|
|
||||||
const microplanetEndlessJobs = [
|
const microplanetEndlessJobs: readonly string[] = [
|
||||||
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessAreaDefenseBounty",
|
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessAreaDefenseBounty",
|
||||||
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessExcavateBounty",
|
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessExcavateBounty",
|
||||||
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessPurifyBounty"
|
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessPurifyBounty"
|
||||||
@ -498,6 +498,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
|
|
||||||
{
|
{
|
||||||
const rng = new SRng(seed);
|
const rng = new SRng(seed);
|
||||||
|
const pool = [...eidolonJobs];
|
||||||
syndicateMissions.push({
|
syndicateMissions.push({
|
||||||
_id: {
|
_id: {
|
||||||
$oid: ((bountyCycleStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000008"
|
$oid: ((bountyCycleStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000008"
|
||||||
@ -509,7 +510,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
Nodes: [],
|
Nodes: [],
|
||||||
Jobs: [
|
Jobs: [
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(eidolonJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierATable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierATable${table}Rewards`,
|
||||||
masteryReq: 0,
|
masteryReq: 0,
|
||||||
minEnemyLevel: 5,
|
minEnemyLevel: 5,
|
||||||
@ -517,7 +518,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 3, 1000, 1500)
|
xpAmounts: generateXpAmounts(rng, 3, 1000, 1500)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(eidolonJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierBTable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierBTable${table}Rewards`,
|
||||||
masteryReq: 1,
|
masteryReq: 1,
|
||||||
minEnemyLevel: 10,
|
minEnemyLevel: 10,
|
||||||
@ -525,7 +526,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 3, 1750, 2250)
|
xpAmounts: generateXpAmounts(rng, 3, 1750, 2250)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(eidolonJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierCTable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierCTable${table}Rewards`,
|
||||||
masteryReq: 2,
|
masteryReq: 2,
|
||||||
minEnemyLevel: 20,
|
minEnemyLevel: 20,
|
||||||
@ -533,7 +534,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 4, 2500, 3000)
|
xpAmounts: generateXpAmounts(rng, 4, 2500, 3000)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(eidolonJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierDTable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierDTable${table}Rewards`,
|
||||||
masteryReq: 3,
|
masteryReq: 3,
|
||||||
minEnemyLevel: 30,
|
minEnemyLevel: 30,
|
||||||
@ -541,7 +542,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 5, 3250, 3750)
|
xpAmounts: generateXpAmounts(rng, 5, 3250, 3750)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(eidolonJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETable${table}Rewards`,
|
||||||
masteryReq: 5,
|
masteryReq: 5,
|
||||||
minEnemyLevel: 40,
|
minEnemyLevel: 40,
|
||||||
@ -549,7 +550,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 5, 4000, 4500)
|
xpAmounts: generateXpAmounts(rng, 5, 4000, 4500)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(eidolonJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETable${table}Rewards`,
|
||||||
masteryReq: 10,
|
masteryReq: 10,
|
||||||
minEnemyLevel: 100,
|
minEnemyLevel: 100,
|
||||||
@ -570,6 +571,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
|
|
||||||
{
|
{
|
||||||
const rng = new SRng(seed);
|
const rng = new SRng(seed);
|
||||||
|
const pool = [...venusJobs];
|
||||||
syndicateMissions.push({
|
syndicateMissions.push({
|
||||||
_id: {
|
_id: {
|
||||||
$oid: ((bountyCycleStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000025"
|
$oid: ((bountyCycleStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000025"
|
||||||
@ -581,7 +583,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
Nodes: [],
|
Nodes: [],
|
||||||
Jobs: [
|
Jobs: [
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(venusJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierATable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierATable${table}Rewards`,
|
||||||
masteryReq: 0,
|
masteryReq: 0,
|
||||||
minEnemyLevel: 5,
|
minEnemyLevel: 5,
|
||||||
@ -589,7 +591,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 3, 1000, 1500)
|
xpAmounts: generateXpAmounts(rng, 3, 1000, 1500)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(venusJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierBTable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierBTable${table}Rewards`,
|
||||||
masteryReq: 1,
|
masteryReq: 1,
|
||||||
minEnemyLevel: 10,
|
minEnemyLevel: 10,
|
||||||
@ -597,7 +599,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 3, 1750, 2250)
|
xpAmounts: generateXpAmounts(rng, 3, 1750, 2250)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(venusJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierCTable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierCTable${table}Rewards`,
|
||||||
masteryReq: 2,
|
masteryReq: 2,
|
||||||
minEnemyLevel: 20,
|
minEnemyLevel: 20,
|
||||||
@ -605,7 +607,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 4, 2500, 3000)
|
xpAmounts: generateXpAmounts(rng, 4, 2500, 3000)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(venusJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierDTable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierDTable${table}Rewards`,
|
||||||
masteryReq: 3,
|
masteryReq: 3,
|
||||||
minEnemyLevel: 30,
|
minEnemyLevel: 30,
|
||||||
@ -613,7 +615,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 5, 3250, 3750)
|
xpAmounts: generateXpAmounts(rng, 5, 3250, 3750)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(venusJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETable${table}Rewards`,
|
||||||
masteryReq: 5,
|
masteryReq: 5,
|
||||||
minEnemyLevel: 40,
|
minEnemyLevel: 40,
|
||||||
@ -621,7 +623,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 5, 4000, 4500)
|
xpAmounts: generateXpAmounts(rng, 5, 4000, 4500)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(venusJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETable${table}Rewards`,
|
||||||
masteryReq: 10,
|
masteryReq: 10,
|
||||||
minEnemyLevel: 100,
|
minEnemyLevel: 100,
|
||||||
@ -642,6 +644,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
|
|
||||||
{
|
{
|
||||||
const rng = new SRng(seed);
|
const rng = new SRng(seed);
|
||||||
|
const pool = [...microplanetJobs];
|
||||||
syndicateMissions.push({
|
syndicateMissions.push({
|
||||||
_id: {
|
_id: {
|
||||||
$oid: ((bountyCycleStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000002"
|
$oid: ((bountyCycleStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000002"
|
||||||
@ -653,7 +656,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
Nodes: [],
|
Nodes: [],
|
||||||
Jobs: [
|
Jobs: [
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(microplanetJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierATable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierATable${table}Rewards`,
|
||||||
masteryReq: 0,
|
masteryReq: 0,
|
||||||
minEnemyLevel: 5,
|
minEnemyLevel: 5,
|
||||||
@ -661,7 +664,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 3, 12, 18)
|
xpAmounts: generateXpAmounts(rng, 3, 12, 18)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(microplanetJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierCTable${table}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierCTable${table}Rewards`,
|
||||||
masteryReq: 1,
|
masteryReq: 1,
|
||||||
minEnemyLevel: 15,
|
minEnemyLevel: 15,
|
||||||
@ -678,7 +681,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: [14, 14, 14]
|
xpAmounts: [14, 14, 14]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(microplanetJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierDTable${deimosDTable}Rewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierDTable${deimosDTable}Rewards`,
|
||||||
masteryReq: 2,
|
masteryReq: 2,
|
||||||
minEnemyLevel: 30,
|
minEnemyLevel: 30,
|
||||||
@ -686,7 +689,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 4, 72, 88)
|
xpAmounts: generateXpAmounts(rng, 4, 72, 88)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(microplanetJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETableARewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETableARewards`,
|
||||||
masteryReq: 3,
|
masteryReq: 3,
|
||||||
minEnemyLevel: 40,
|
minEnemyLevel: 40,
|
||||||
@ -694,7 +697,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
|
|||||||
xpAmounts: generateXpAmounts(rng, 5, 115, 135)
|
xpAmounts: generateXpAmounts(rng, 5, 115, 135)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jobType: rng.randomElement(microplanetJobs),
|
jobType: rng.randomElementPop(pool),
|
||||||
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETableARewards`,
|
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETableARewards`,
|
||||||
masteryReq: 10,
|
masteryReq: 10,
|
||||||
minEnemyLevel: 100,
|
minEnemyLevel: 100,
|
||||||
@ -1146,6 +1149,77 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
Node: "SolarisUnitedHub1"
|
Node: "SolarisUnitedHub1"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// The client gets kinda confused when multiple goals have the same tag, so considering these mutually exclusive.
|
||||||
|
if (config.worldState?.galleonOfGhouls == 1) {
|
||||||
|
worldState.Goals.push({
|
||||||
|
_id: { $oid: "6814ddf00000000000000000" },
|
||||||
|
Activation: { $date: { $numberLong: "1746198000000" } },
|
||||||
|
Expiry: { $date: { $numberLong: "2000000000000" } },
|
||||||
|
Count: 0,
|
||||||
|
Goal: 1,
|
||||||
|
Success: 0,
|
||||||
|
Personal: true,
|
||||||
|
Bounty: true,
|
||||||
|
ClampNodeScores: true,
|
||||||
|
Node: "EventNode19",
|
||||||
|
MissionKeyName: "/Lotus/Types/Keys/GalleonRobberyAlert",
|
||||||
|
Desc: "/Lotus/Language/Events/GalleonRobberyEventMissionTitle",
|
||||||
|
Icon: "/Lotus/Interface/Icons/Player/GalleonRobberiesEvent.png",
|
||||||
|
Tag: "GalleonRobbery",
|
||||||
|
Reward: {
|
||||||
|
items: [
|
||||||
|
"/Lotus/StoreItems/Types/Recipes/Weapons/GrnChainSawTonfaBlueprint",
|
||||||
|
"/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (config.worldState?.galleonOfGhouls == 2) {
|
||||||
|
worldState.Goals.push({
|
||||||
|
_id: { $oid: "681e18700000000000000000" },
|
||||||
|
Activation: { $date: { $numberLong: "1746802800000" } },
|
||||||
|
Expiry: { $date: { $numberLong: "2000000000000" } },
|
||||||
|
Count: 0,
|
||||||
|
Goal: 1,
|
||||||
|
Success: 0,
|
||||||
|
Personal: true,
|
||||||
|
Bounty: true,
|
||||||
|
ClampNodeScores: true,
|
||||||
|
Node: "EventNode28",
|
||||||
|
MissionKeyName: "/Lotus/Types/Keys/GalleonRobberyAlertB",
|
||||||
|
Desc: "/Lotus/Language/Events/GalleonRobberyEventMissionTitle",
|
||||||
|
Icon: "/Lotus/Interface/Icons/Player/GalleonRobberiesEvent.png",
|
||||||
|
Tag: "GalleonRobbery",
|
||||||
|
Reward: {
|
||||||
|
items: [
|
||||||
|
"/Lotus/StoreItems/Types/Recipes/Weapons/MortiforShieldAndSwordBlueprint",
|
||||||
|
"/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (config.worldState?.galleonOfGhouls == 3) {
|
||||||
|
worldState.Goals.push({
|
||||||
|
_id: { $oid: "682752f00000000000000000" },
|
||||||
|
Activation: { $date: { $numberLong: "1747407600000" } },
|
||||||
|
Expiry: { $date: { $numberLong: "2000000000000" } },
|
||||||
|
Count: 0,
|
||||||
|
Goal: 1,
|
||||||
|
Success: 0,
|
||||||
|
Personal: true,
|
||||||
|
Bounty: true,
|
||||||
|
ClampNodeScores: true,
|
||||||
|
Node: "EventNode19",
|
||||||
|
MissionKeyName: "/Lotus/Types/Keys/GalleonRobberyAlertC",
|
||||||
|
Desc: "/Lotus/Language/Events/GalleonRobberyEventMissionTitle",
|
||||||
|
Icon: "/Lotus/Interface/Icons/Player/GalleonRobberiesEvent.png",
|
||||||
|
Tag: "GalleonRobbery",
|
||||||
|
Reward: {
|
||||||
|
items: [
|
||||||
|
"/Lotus/Types/StoreItems/Packages/EventCatalystReactorBundle",
|
||||||
|
"/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Nightwave Challenges
|
// Nightwave Challenges
|
||||||
const nightwaveSyndicateTag = getNightwaveSyndicateTag(buildLabel);
|
const nightwaveSyndicateTag = getNightwaveSyndicateTag(buildLabel);
|
||||||
|
@ -56,6 +56,7 @@ export interface IInventoryDatabase
|
|||||||
| "QualifyingInvasions"
|
| "QualifyingInvasions"
|
||||||
| "LastInventorySync"
|
| "LastInventorySync"
|
||||||
| "EndlessXP"
|
| "EndlessXP"
|
||||||
|
| "PersonalGoalProgress"
|
||||||
| TEquipmentKey
|
| TEquipmentKey
|
||||||
>,
|
>,
|
||||||
InventoryDatabaseEquipment {
|
InventoryDatabaseEquipment {
|
||||||
@ -63,7 +64,7 @@ export interface IInventoryDatabase
|
|||||||
Created: Date;
|
Created: Date;
|
||||||
TrainingDate: Date;
|
TrainingDate: Date;
|
||||||
LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population
|
LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population
|
||||||
Mailbox?: IMailboxDatabase;
|
//Mailbox?: IMailboxDatabase;
|
||||||
GuildId?: Types.ObjectId;
|
GuildId?: Types.ObjectId;
|
||||||
PendingRecipes: IPendingRecipeDatabase[];
|
PendingRecipes: IPendingRecipeDatabase[];
|
||||||
QuestKeys: IQuestKeyDatabase[];
|
QuestKeys: IQuestKeyDatabase[];
|
||||||
@ -95,6 +96,7 @@ export interface IInventoryDatabase
|
|||||||
QualifyingInvasions: IInvasionProgressDatabase[];
|
QualifyingInvasions: IInvasionProgressDatabase[];
|
||||||
LastInventorySync?: Types.ObjectId;
|
LastInventorySync?: Types.ObjectId;
|
||||||
EndlessXP?: IEndlessXpProgressDatabase[];
|
EndlessXP?: IEndlessXpProgressDatabase[];
|
||||||
|
PersonalGoalProgress?: IPersonalGoalProgressDatabase[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IQuestKeyDatabase {
|
export interface IQuestKeyDatabase {
|
||||||
@ -150,9 +152,9 @@ export interface IMailboxClient {
|
|||||||
LastInboxId: IOid;
|
LastInboxId: IOid;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMailboxDatabase {
|
/*export interface IMailboxDatabase {
|
||||||
LastInboxId: Types.ObjectId;
|
LastInboxId: Types.ObjectId;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
export type TSolarMapRegion =
|
export type TSolarMapRegion =
|
||||||
| "Earth"
|
| "Earth"
|
||||||
@ -306,7 +308,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
HWIDProtectEnabled?: boolean;
|
HWIDProtectEnabled?: boolean;
|
||||||
//KubrowPetPrints: IKubrowPetPrint[];
|
//KubrowPetPrints: IKubrowPetPrint[];
|
||||||
AlignmentReplay?: IAlignment;
|
AlignmentReplay?: IAlignment;
|
||||||
//PersonalGoalProgress: IPersonalGoalProgress[];
|
PersonalGoalProgress?: IPersonalGoalProgressClient[];
|
||||||
ThemeStyle: string;
|
ThemeStyle: string;
|
||||||
ThemeBackground: string;
|
ThemeBackground: string;
|
||||||
ThemeSounds: string;
|
ThemeSounds: string;
|
||||||
@ -378,6 +380,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
LockedWeaponGroup?: ILockedWeaponGroupClient;
|
LockedWeaponGroup?: ILockedWeaponGroupClient;
|
||||||
HubNpcCustomizations?: IHubNpcCustomization[];
|
HubNpcCustomizations?: IHubNpcCustomization[];
|
||||||
Ship?: IOrbiter; // U22 and below, response only
|
Ship?: IOrbiter; // U22 and below, response only
|
||||||
|
ClaimedJunctionChallengeRewards?: string[]; // U39
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAffiliation {
|
export interface IAffiliation {
|
||||||
@ -446,8 +449,9 @@ export interface IVendorPurchaseHistoryEntryDatabase {
|
|||||||
|
|
||||||
export interface IChallengeProgress {
|
export interface IChallengeProgress {
|
||||||
Progress: number;
|
Progress: number;
|
||||||
Name: string;
|
|
||||||
Completed?: string[];
|
Completed?: string[];
|
||||||
|
ReceivedJunctionReward?: boolean; // U39
|
||||||
|
Name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICollectibleEntry {
|
export interface ICollectibleEntry {
|
||||||
@ -1015,13 +1019,17 @@ export interface IPeriodicMissionCompletionResponse extends Omit<IPeriodicMissio
|
|||||||
date: IMongoDate;
|
date: IMongoDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPersonalGoalProgress {
|
export interface IPersonalGoalProgressClient {
|
||||||
|
Best: number;
|
||||||
Count: number;
|
Count: number;
|
||||||
Tag: string;
|
Tag: string;
|
||||||
Best?: number;
|
|
||||||
_id: IOid;
|
_id: IOid;
|
||||||
ReceivedClanReward0?: boolean;
|
//ReceivedClanReward0?: boolean;
|
||||||
ReceivedClanReward1?: boolean;
|
//ReceivedClanReward1?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPersonalGoalProgressDatabase extends Omit<IPersonalGoalProgressClient, "_id"> {
|
||||||
|
goalId: Types.ObjectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPersonalTechProjectDatabase {
|
export interface IPersonalTechProjectDatabase {
|
||||||
|
@ -139,6 +139,14 @@ export type IMissionInventoryUpdateRequest = {
|
|||||||
};
|
};
|
||||||
wagerTier?: number; // the index
|
wagerTier?: number; // the index
|
||||||
creditsFee?: number; // the index
|
creditsFee?: number; // the index
|
||||||
|
GoalProgress?: {
|
||||||
|
_id: IOid;
|
||||||
|
Count: number;
|
||||||
|
Best: number;
|
||||||
|
Tag: string;
|
||||||
|
IsMultiProgress: boolean;
|
||||||
|
MultiProgress: unknown[];
|
||||||
|
}[];
|
||||||
InvasionProgress?: IInvasionProgressClient[];
|
InvasionProgress?: IInvasionProgressClient[];
|
||||||
ConquestMissionsCompleted?: number;
|
ConquestMissionsCompleted?: number;
|
||||||
duviriSuitSelection?: string;
|
duviriSuitSelection?: string;
|
||||||
@ -156,6 +164,8 @@ export type IMissionInventoryUpdateRequest = {
|
|||||||
|
|
||||||
export interface IRewardInfo {
|
export interface IRewardInfo {
|
||||||
node: string;
|
node: string;
|
||||||
|
goalId?: string;
|
||||||
|
goalManifest?: string;
|
||||||
invasionId?: string;
|
invasionId?: string;
|
||||||
invasionAllyFaction?: "FC_GRINEER" | "FC_CORPUS";
|
invasionAllyFaction?: "FC_GRINEER" | "FC_CORPUS";
|
||||||
sortieId?: string;
|
sortieId?: string;
|
||||||
|
@ -96,6 +96,7 @@ export interface IPlacedDecosDatabase {
|
|||||||
Pos: [number, number, number];
|
Pos: [number, number, number];
|
||||||
Rot: [number, number, number];
|
Rot: [number, number, number];
|
||||||
Scale?: number;
|
Scale?: number;
|
||||||
|
Sockets?: number;
|
||||||
PictureFrameInfo?: IPictureFrameInfo;
|
PictureFrameInfo?: IPictureFrameInfo;
|
||||||
_id: Types.ObjectId;
|
_id: Types.ObjectId;
|
||||||
}
|
}
|
||||||
@ -136,6 +137,7 @@ export interface IShipDecorationsRequest {
|
|||||||
MoveId?: string;
|
MoveId?: string;
|
||||||
OldRoom?: string;
|
OldRoom?: string;
|
||||||
Scale?: number;
|
Scale?: number;
|
||||||
|
Sockets?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IShipDecorationsResponse {
|
export interface IShipDecorationsResponse {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { IMissionReward } from "warframe-public-export-plus";
|
||||||
import { IMongoDate, IOid } from "./commonTypes";
|
import { IMongoDate, IOid } from "./commonTypes";
|
||||||
|
|
||||||
export interface IWorldState {
|
export interface IWorldState {
|
||||||
@ -37,11 +38,15 @@ export interface IGoal {
|
|||||||
Goal: number;
|
Goal: number;
|
||||||
Success: number;
|
Success: number;
|
||||||
Personal: boolean;
|
Personal: boolean;
|
||||||
|
Bounty?: boolean;
|
||||||
|
ClampNodeScores?: boolean;
|
||||||
Desc: string;
|
Desc: string;
|
||||||
ToolTip: string;
|
ToolTip?: string;
|
||||||
Icon: string;
|
Icon: string;
|
||||||
Tag: string;
|
Tag: string;
|
||||||
Node: string;
|
Node: string;
|
||||||
|
MissionKeyName?: string;
|
||||||
|
Reward?: IMissionReward;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISyndicateMissionInfo {
|
export interface ISyndicateMissionInfo {
|
||||||
|
@ -794,6 +794,7 @@
|
|||||||
<button class="btn btn-primary" onclick="debounce(doUnlockAllMissions);" data-loc="cheats_unlockAllMissions"></button>
|
<button class="btn btn-primary" onclick="debounce(doUnlockAllMissions);" data-loc="cheats_unlockAllMissions"></button>
|
||||||
<button class="btn btn-primary" onclick="doUnlockAllFocusSchools();" data-loc="cheats_unlockAllFocusSchools"></button>
|
<button class="btn btn-primary" onclick="doUnlockAllFocusSchools();" data-loc="cheats_unlockAllFocusSchools"></button>
|
||||||
<button class="btn btn-primary" onclick="doHelminthUnlockAll();" data-loc="cheats_helminthUnlockAll"></button>
|
<button class="btn btn-primary" onclick="doHelminthUnlockAll();" data-loc="cheats_helminthUnlockAll"></button>
|
||||||
|
<button class="btn btn-primary" onclick="debounce(addMissingHelminthRecipes);" data-loc="cheats_addMissingSubsumedAbilities"></button>
|
||||||
<button class="btn btn-primary" onclick="doIntrinsicsUnlockAll();" data-loc="cheats_intrinsicsUnlockAll"></button>
|
<button class="btn btn-primary" onclick="doIntrinsicsUnlockAll();" data-loc="cheats_intrinsicsUnlockAll"></button>
|
||||||
<button class="btn btn-primary" onclick="debounce(doMaxPlexus);" data-loc="inventory_maxPlexus"></button>
|
<button class="btn btn-primary" onclick="debounce(doMaxPlexus);" data-loc="inventory_maxPlexus"></button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1449,6 +1449,11 @@ function addMissingEquipment(categories) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addMissingHelminthRecipes() {
|
||||||
|
await revalidateAuthz();
|
||||||
|
await fetch("/custom/addMissingHelminthBlueprints?" + window.authz);
|
||||||
|
}
|
||||||
|
|
||||||
function addMissingEvolutionProgress() {
|
function addMissingEvolutionProgress() {
|
||||||
const requests = [];
|
const requests = [];
|
||||||
document.querySelectorAll("#datalist-EvolutionProgress option").forEach(elm => {
|
document.querySelectorAll("#datalist-EvolutionProgress option").forEach(elm => {
|
||||||
|
@ -181,6 +181,7 @@ dict = {
|
|||||||
cheats_account: `Account`,
|
cheats_account: `Account`,
|
||||||
cheats_unlockAllFocusSchools: `Alle Fokus-Schulen freischalten`,
|
cheats_unlockAllFocusSchools: `Alle Fokus-Schulen freischalten`,
|
||||||
cheats_helminthUnlockAll: `Helminth vollständig aufleveln`,
|
cheats_helminthUnlockAll: `Helminth vollständig aufleveln`,
|
||||||
|
cheats_addMissingSubsumedAbilities: `[UNTRANSLATED] Add Missing Subsumed Abilities`,
|
||||||
cheats_intrinsicsUnlockAll: `Alle Inhärenzen auf Max. Rang`,
|
cheats_intrinsicsUnlockAll: `Alle Inhärenzen auf Max. Rang`,
|
||||||
cheats_changeSupportedSyndicate: `Unterstütztes Syndikat`,
|
cheats_changeSupportedSyndicate: `Unterstütztes Syndikat`,
|
||||||
cheats_changeButton: `Ändern`,
|
cheats_changeButton: `Ändern`,
|
||||||
|
@ -180,6 +180,7 @@ dict = {
|
|||||||
cheats_account: `Account`,
|
cheats_account: `Account`,
|
||||||
cheats_unlockAllFocusSchools: `Unlock All Focus Schools`,
|
cheats_unlockAllFocusSchools: `Unlock All Focus Schools`,
|
||||||
cheats_helminthUnlockAll: `Fully Level Up Helminth`,
|
cheats_helminthUnlockAll: `Fully Level Up Helminth`,
|
||||||
|
cheats_addMissingSubsumedAbilities: `Add Missing Subsumed Abilities`,
|
||||||
cheats_intrinsicsUnlockAll: `Max Rank All Intrinsics`,
|
cheats_intrinsicsUnlockAll: `Max Rank All Intrinsics`,
|
||||||
cheats_changeSupportedSyndicate: `Supported syndicate`,
|
cheats_changeSupportedSyndicate: `Supported syndicate`,
|
||||||
cheats_changeButton: `Change`,
|
cheats_changeButton: `Change`,
|
||||||
|
@ -181,6 +181,7 @@ dict = {
|
|||||||
cheats_account: `Cuenta`,
|
cheats_account: `Cuenta`,
|
||||||
cheats_unlockAllFocusSchools: `Desbloquear todas las escuelas de enfoque`,
|
cheats_unlockAllFocusSchools: `Desbloquear todas las escuelas de enfoque`,
|
||||||
cheats_helminthUnlockAll: `Subir al máximo el Helminto`,
|
cheats_helminthUnlockAll: `Subir al máximo el Helminto`,
|
||||||
|
cheats_addMissingSubsumedAbilities: `[UNTRANSLATED] Add Missing Subsumed Abilities`,
|
||||||
cheats_intrinsicsUnlockAll: `Maximizar todos los intrínsecos`,
|
cheats_intrinsicsUnlockAll: `Maximizar todos los intrínsecos`,
|
||||||
cheats_changeSupportedSyndicate: `Sindicatos disponibles`,
|
cheats_changeSupportedSyndicate: `Sindicatos disponibles`,
|
||||||
cheats_changeButton: `Cambiar`,
|
cheats_changeButton: `Cambiar`,
|
||||||
|
@ -3,8 +3,8 @@ dict = {
|
|||||||
general_inventoryUpdateNote: `Note : Les changements effectués ici seront appliqués lors de la syncrhonisation. Visiter la navigation appliquera les changements apportés à l'inventaire.`,
|
general_inventoryUpdateNote: `Note : Les changements effectués ici seront appliqués lors de la syncrhonisation. Visiter la navigation appliquera les changements apportés à l'inventaire.`,
|
||||||
general_addButton: `Ajouter`,
|
general_addButton: `Ajouter`,
|
||||||
general_bulkActions: `Action groupée`,
|
general_bulkActions: `Action groupée`,
|
||||||
code_loginFail: `[UNTRANSLATED] Login failed. Double-check the email and password.`,
|
code_loginFail: `Connexion échouée. Vérifiez le mot de passe.`,
|
||||||
code_regFail: `[UNTRANSLATED] Registration failed. Account already exists?`,
|
code_regFail: `Enregistrement impossible. Compte existant?`,
|
||||||
code_changeNameConfirm: `Nouveau nom du compte :`,
|
code_changeNameConfirm: `Nouveau nom du compte :`,
|
||||||
code_deleteAccountConfirm: `Supprimer |DISPLAYNAME| (|EMAIL|) ? Cette action est irreversible.`,
|
code_deleteAccountConfirm: `Supprimer |DISPLAYNAME| (|EMAIL|) ? Cette action est irreversible.`,
|
||||||
code_archgun: `Archgun`,
|
code_archgun: `Archgun`,
|
||||||
@ -85,7 +85,7 @@ dict = {
|
|||||||
inventory_moaPets: `Moas`,
|
inventory_moaPets: `Moas`,
|
||||||
inventory_kubrowPets: `Bêtes`,
|
inventory_kubrowPets: `Bêtes`,
|
||||||
inventory_evolutionProgress: `Progrès de l'évolution Incarnon`,
|
inventory_evolutionProgress: `Progrès de l'évolution Incarnon`,
|
||||||
inventory_Boosters: `[UNTRANSLATED] Boosters`,
|
inventory_Boosters: `Boosters`,
|
||||||
inventory_bulkAddSuits: `Ajouter les Warframes manquantes`,
|
inventory_bulkAddSuits: `Ajouter les Warframes manquantes`,
|
||||||
inventory_bulkAddWeapons: `Ajouter les armes manquantes`,
|
inventory_bulkAddWeapons: `Ajouter les armes manquantes`,
|
||||||
inventory_bulkAddSpaceSuits: `Ajouter les Archwings manquants`,
|
inventory_bulkAddSpaceSuits: `Ajouter les Archwings manquants`,
|
||||||
@ -100,7 +100,7 @@ dict = {
|
|||||||
inventory_bulkRankUpSentinels: `Toutes les Sentinelles au rang max`,
|
inventory_bulkRankUpSentinels: `Toutes les Sentinelles au rang max`,
|
||||||
inventory_bulkRankUpSentinelWeapons: `Toutes les armes de Sentinelles au rang max`,
|
inventory_bulkRankUpSentinelWeapons: `Toutes les armes de Sentinelles au rang max`,
|
||||||
inventory_bulkRankUpEvolutionProgress: `Toutes les évolutions Incarnon au rang max`,
|
inventory_bulkRankUpEvolutionProgress: `Toutes les évolutions Incarnon au rang max`,
|
||||||
inventory_maxPlexus: `[UNTRANSLATED] Max Rank Plexus`,
|
inventory_maxPlexus: `Plexus au rang max`,
|
||||||
|
|
||||||
quests_list: `Quêtes`,
|
quests_list: `Quêtes`,
|
||||||
quests_completeAll: `Compléter toutes les quêtes`,
|
quests_completeAll: `Compléter toutes les quêtes`,
|
||||||
@ -135,10 +135,10 @@ dict = {
|
|||||||
cheats_infiniteRegalAya: `Aya Raffiné infini`,
|
cheats_infiniteRegalAya: `Aya Raffiné infini`,
|
||||||
cheats_infiniteHelminthMaterials: `Ressources d'Helminth infinies`,
|
cheats_infiniteHelminthMaterials: `Ressources d'Helminth infinies`,
|
||||||
cheats_claimingBlueprintRefundsIngredients: `Récupérer les items rend les ressources`,
|
cheats_claimingBlueprintRefundsIngredients: `Récupérer les items rend les ressources`,
|
||||||
cheats_dontSubtractPurchaseCreditCost: `[UNTRANSLATED] Don't Subtract Purchase Credit Cost`,
|
cheats_dontSubtractPurchaseCreditCost: `Ne pas retirer le coût en crédits`,
|
||||||
cheats_dontSubtractPurchasePlatinumCost: `[UNTRANSLATED] Don't Subtract Purchase Platinum Cost`,
|
cheats_dontSubtractPurchasePlatinumCost: `Ne pas retirer le coût en platines`,
|
||||||
cheats_dontSubtractPurchaseItemCost: `[UNTRANSLATED] Don't Subtract Purchase Item Cost`,
|
cheats_dontSubtractPurchaseItemCost: `Ne pas retirer le coût d'achat`,
|
||||||
cheats_dontSubtractPurchaseStandingCost: `[UNTRANSLATED] Don't Subtract Purchase Standing Cost`,
|
cheats_dontSubtractPurchaseStandingCost: `Ne pas retirer le coût en réputation`,
|
||||||
cheats_dontSubtractVoidTraces: `Ne pas consommer de Void Traces`,
|
cheats_dontSubtractVoidTraces: `Ne pas consommer de Void Traces`,
|
||||||
cheats_dontSubtractConsumables: `Ne pas retirer de consommables`,
|
cheats_dontSubtractConsumables: `Ne pas retirer de consommables`,
|
||||||
cheats_unlockAllShipFeatures: `Débloquer tous les segments du vaisseau`,
|
cheats_unlockAllShipFeatures: `Débloquer tous les segments du vaisseau`,
|
||||||
@ -158,11 +158,11 @@ dict = {
|
|||||||
cheats_noVendorPurchaseLimits: `Aucune limite d'achat chez les PNJ`,
|
cheats_noVendorPurchaseLimits: `Aucune limite d'achat chez les PNJ`,
|
||||||
cheats_noDeathMarks: `Aucune marque d'assassin`,
|
cheats_noDeathMarks: `Aucune marque d'assassin`,
|
||||||
cheats_noKimCooldowns: `Aucun cooldown sur le KIM`,
|
cheats_noKimCooldowns: `Aucun cooldown sur le KIM`,
|
||||||
cheats_fullyStockedVendors: `[UNTRANSLATED] Fully Stocked Vendors`,
|
cheats_fullyStockedVendors: `Les vendeurs ont un stock à 100%`,
|
||||||
cheats_baroAlwaysAvailable: `[UNTRANSLATED] Baro Always Available`,
|
cheats_baroAlwaysAvailable: `[UNTRANSLATED] Baro Always Available`,
|
||||||
cheats_baroFullyStocked: `[UNTRANSLATED] Baro Fully Stocked`,
|
cheats_baroFullyStocked: `[UNTRANSLATED] Baro Fully Stocked`,
|
||||||
cheats_syndicateMissionsRepeatable: `Mission syndicat répétables`,
|
cheats_syndicateMissionsRepeatable: `Mission syndicat répétables`,
|
||||||
cheats_unlockAllProfitTakerStages: `[UNTRANSLATED] Unlock All Profit Taker Stages`,
|
cheats_unlockAllProfitTakerStages: `Débloquer toutes les étapes du Preneur de Profit`,
|
||||||
cheats_instantFinishRivenChallenge: `Débloquer le challenge Riven instantanément`,
|
cheats_instantFinishRivenChallenge: `Débloquer le challenge Riven instantanément`,
|
||||||
cheats_instantResourceExtractorDrones: `Ressources de drones d'extraction instantannées`,
|
cheats_instantResourceExtractorDrones: `Ressources de drones d'extraction instantannées`,
|
||||||
cheats_noResourceExtractorDronesDamage: `Aucun dégâts aux drones d'extraction de resources`,
|
cheats_noResourceExtractorDronesDamage: `Aucun dégâts aux drones d'extraction de resources`,
|
||||||
@ -173,73 +173,74 @@ dict = {
|
|||||||
cheats_noDojoResearchCosts: `Aucun coût de recherche (Dojo)`,
|
cheats_noDojoResearchCosts: `Aucun coût de recherche (Dojo)`,
|
||||||
cheats_noDojoResearchTime: `Aucun temps de recherche (Dojo)`,
|
cheats_noDojoResearchTime: `Aucun temps de recherche (Dojo)`,
|
||||||
cheats_fastClanAscension: `Ascension de clan rapide`,
|
cheats_fastClanAscension: `Ascension de clan rapide`,
|
||||||
cheats_missionsCanGiveAllRelics: `[UNTRANSLATED] Missions Can Give All Relics`,
|
cheats_missionsCanGiveAllRelics: `Les missions donnent toutes les reliques`,
|
||||||
cheats_unlockAllSimarisResearchEntries: `[UNTRANSLATED] Unlock All Simaris Research Entries`,
|
cheats_unlockAllSimarisResearchEntries: `Débloquer toute les recherches chez Simaris`,
|
||||||
cheats_spoofMasteryRank: `Rang de maîtrise personnalisé (-1 pour désactiver)`,
|
cheats_spoofMasteryRank: `Rang de maîtrise personnalisé (-1 pour désactiver)`,
|
||||||
cheats_nightwaveStandingMultiplier: `[UNTRANSLATED] Nightwave Standing Multiplier`,
|
cheats_nightwaveStandingMultiplier: `Multiplicateur de réputation d'Ondes Nocturnes`,
|
||||||
cheats_save: `[UNTRANSLATED] Save`,
|
cheats_save: `Sauvegarder`,
|
||||||
cheats_account: `Compte`,
|
cheats_account: `Compte`,
|
||||||
cheats_unlockAllFocusSchools: `Débloquer toutes les écoles de focus`,
|
cheats_unlockAllFocusSchools: `Débloquer toutes les écoles de focus`,
|
||||||
cheats_helminthUnlockAll: `Helminth niveau max`,
|
cheats_helminthUnlockAll: `Helminth niveau max`,
|
||||||
|
cheats_addMissingSubsumedAbilities: `[UNTRANSLATED] Add Missing Subsumed Abilities`,
|
||||||
cheats_intrinsicsUnlockAll: `Inhérences niveau max`,
|
cheats_intrinsicsUnlockAll: `Inhérences niveau max`,
|
||||||
cheats_changeSupportedSyndicate: `Allégeance`,
|
cheats_changeSupportedSyndicate: `Allégeance`,
|
||||||
cheats_changeButton: `Changer`,
|
cheats_changeButton: `Changer`,
|
||||||
cheats_none: `Aucun`,
|
cheats_none: `Aucun`,
|
||||||
import_importNote: `Import manuel. Toutes les modifcations supportées par l'inventaire <b>écraseront celles présentes dans la base de données</b>.`,
|
import_importNote: `Import manuel. Toutes les modifcations supportées par l'inventaire <b>écraseront celles présentes dans la base de données</b>.`,
|
||||||
import_submit: `Soumettre`,
|
import_submit: `Soumettre`,
|
||||||
import_samples: `[UNTRANSLATED] Samples:`,
|
import_samples: `Echantillons :`,
|
||||||
import_samples_maxFocus: `[UNTRANSLATED] All Focus Schools Maxed Out`,
|
import_samples_maxFocus: `Toutes les écoles de focus au rang max`,
|
||||||
|
|
||||||
upgrade_Equilibrium: `[UNTRANSLATED] +|VAL|% Energy from Health pickups, +|VAL|% Health from Energy pickups`,
|
upgrade_Equilibrium: `Ramasser de la santé donne +|VAL|% d'énergie supplémentaire. Ramasser de l'énergie donne +|VAL|% de santé supplémentaire.`,
|
||||||
upgrade_MeleeCritDamage: `[UNTRANSLATED] +|VAL|% Melee Critical Damage`,
|
upgrade_MeleeCritDamage: `+|VAL|% de dégâts critique en mêlée`,
|
||||||
upgrade_PrimaryStatusChance: `[UNTRANSLATED] +|VAL|% Primary Status Chance`,
|
upgrade_PrimaryStatusChance: `+|VAL|% de chance de statut sur arme primaire`,
|
||||||
upgrade_SecondaryCritChance: `[UNTRANSLATED] +|VAL|% Secondary Critical Chance`,
|
upgrade_SecondaryCritChance: `+|VAL|% de chance critique sur arme secondaire`,
|
||||||
upgrade_WarframeAbilityDuration: `[UNTRANSLATED] +|VAL|% Ability Duration`,
|
upgrade_WarframeAbilityDuration: `+|VAL|% de durée de pouvoir`,
|
||||||
upgrade_WarframeAbilityStrength: `[UNTRANSLATED] +|VAL|% Ability Strength`,
|
upgrade_WarframeAbilityStrength: `+|VAL|% de puissance de pouvoir`,
|
||||||
upgrade_WarframeArmourMax: `[UNTRANSLATED] +|VAL| Armor`,
|
upgrade_WarframeArmourMax: `+|VAL| d'armure`,
|
||||||
upgrade_WarframeBlastProc: `[UNTRANSLATED] +|VAL| Shields on kill with Blast Damage`,
|
upgrade_WarframeBlastProc: `+|VAL| de boucliers sur élimination avec des dégats d'explosion`,
|
||||||
upgrade_WarframeCastingSpeed: `[UNTRANSLATED] +|VAL|% Casting Speed`,
|
upgrade_WarframeCastingSpeed: `+|VAL|% de vitesse de lancement de pouvoir`,
|
||||||
upgrade_WarframeCorrosiveDamageBoost: `[UNTRANSLATED] +|VAL|% Ability Damage on enemies affected by Corrosion Status`,
|
upgrade_WarframeCorrosiveDamageBoost: `+|VAL|% de dégâts de pouvoir sur les ennemis affectés par du statut corrosif`,
|
||||||
upgrade_WarframeCorrosiveStack: `[UNTRANSLATED] Increase max stacks of Corrosion Status by +|VAL|`,
|
upgrade_WarframeCorrosiveStack: `+|VAL| de cumuls maximum de Statut Corrosif`,
|
||||||
upgrade_WarframeCritDamageBoost: `[UNTRANSLATED] +|VAL|% Melee Critical Damage (Doubles over 500 Energy)`,
|
upgrade_WarframeCritDamageBoost: `+|VAL|% de dégâts critique en mêlée (Doublé si l'énergie dépasse 500)`,
|
||||||
upgrade_WarframeElectricDamage: `[UNTRANSLATED] +|VAL1|% Primary Electricity Damage (+|VAL2|% per additional Shard)`,
|
upgrade_WarframeElectricDamage: `+|VAL1|% de dégâts électrique sur arme primaire (+|VAL2|% par fragment supplémentaire)`,
|
||||||
upgrade_WarframeElectricDamageBoost: `[UNTRANSLATED] +|VAL|% Ability Damage on enemies affected by Electricity Status`,
|
upgrade_WarframeElectricDamageBoost: `+|VAL|% de dégâts de pouvoir sur les ennemis affectés par du statut électrique`,
|
||||||
upgrade_WarframeEnergyMax: `[UNTRANSLATED] +|VAL| Energy Max`,
|
upgrade_WarframeEnergyMax: `+|VAL| d'énergie max`,
|
||||||
upgrade_WarframeGlobeEffectEnergy: `[UNTRANSLATED] +|VAL|% Energy Orb Effectiveness`,
|
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% d'efficacité d'orbe d'énergie`,
|
||||||
upgrade_WarframeGlobeEffectHealth: `[UNTRANSLATED] +|VAL|% Health Orb Effectiveness`,
|
upgrade_WarframeGlobeEffectHealth: `+|VAL|% d'efficacité d'orbe de santé`,
|
||||||
upgrade_WarframeHealthMax: `[UNTRANSLATED] +|VAL| Health`,
|
upgrade_WarframeHealthMax: `+|VAL| de santé`,
|
||||||
upgrade_WarframeHPBoostFromImpact: `[UNTRANSLATED] +|VAL1| Health per enemy killed with Blast Damage (Max |VAL2| Health)`,
|
upgrade_WarframeHPBoostFromImpact: `+|VAL1| de santé par ennemi tué avec des dégâts explosifs (Max |VAL2| de santé)`,
|
||||||
upgrade_WarframeParkourVelocity: `[UNTRANSLATED] +|VAL|% Parkour Velocity`,
|
upgrade_WarframeParkourVelocity: `+|VAL|% de vélocité de parkour`,
|
||||||
upgrade_WarframeRadiationDamageBoost: `[UNTRANSLATED] +|VAL|% Ability Damage on enemies affected by Radiation Status`,
|
upgrade_WarframeRadiationDamageBoost: `+|VAL|% de dégâts de pouvoir sur les ennemis affectés par du statut radiation`,
|
||||||
upgrade_WarframeRegen: `[UNTRANSLATED] +|VAL| Health Regen/s`,
|
upgrade_WarframeRegen: `+|VAL| régénération de santé/s`,
|
||||||
upgrade_WarframeShieldMax: `[UNTRANSLATED] +|VAL| Shield`,
|
upgrade_WarframeShieldMax: `+|VAL| de boucliers`,
|
||||||
upgrade_WarframeStartingEnergy: `[UNTRANSLATED] +|VAL|% Energy on Spawn`,
|
upgrade_WarframeStartingEnergy: `+|VAL|% d'énergie sur apparition`,
|
||||||
upgrade_WarframeToxinDamage: `[UNTRANSLATED] +|VAL|% Toxin Status Effect Damage`,
|
upgrade_WarframeToxinDamage: `+|VAL|% de dégâts sur le statut poison`,
|
||||||
upgrade_WarframeToxinHeal: `[UNTRANSLATED] +|VAL| Health on damaging enemies with Toxin Status`,
|
upgrade_WarframeToxinHeal: `+|VAL| de santé récupérée à chaque dégât de statut poison`,
|
||||||
upgrade_WeaponCritBoostFromHeat: `[UNTRANSLATED] +|VAL1|% Secondary Critical Chance per Heat-affected enemy killed (Max |VAL2|%)`,
|
upgrade_WeaponCritBoostFromHeat: `+|VAL1|% de chance critique sur arme secondaire pour chaque ennemi affecté puis tué par du feu (Max |VAL2|%)`,
|
||||||
upgrade_AvatarAbilityRange: `[UNTRANSLATED] +7.5% Ability Range`,
|
upgrade_AvatarAbilityRange: `+7.5% de portée de pouvoir`,
|
||||||
upgrade_AvatarAbilityEfficiency: `[UNTRANSLATED] +5% Ability Efficiency`,
|
upgrade_AvatarAbilityEfficiency: `+5% d'efficacité de pouvoir`,
|
||||||
upgrade_AvatarEnergyRegen: `[UNTRANSLATED] +0.5 Energy Regen/s`,
|
upgrade_AvatarEnergyRegen: `+0.5 de régénération d'énergie/s`,
|
||||||
upgrade_AvatarEnemyRadar: `[UNTRANSLATED] +5m Enemy Radar`,
|
upgrade_AvatarEnemyRadar: `+5m de radar ennemi`,
|
||||||
upgrade_AvatarLootRadar: `[UNTRANSLATED] +7m Loot Radar`,
|
upgrade_AvatarLootRadar: `+7m de radar à butin`,
|
||||||
upgrade_WeaponAmmoMax: `[UNTRANSLATED] +15% Ammo Max`,
|
upgrade_WeaponAmmoMax: `+15% de munitions max`,
|
||||||
upgrade_EnemyArmorReductionAura: `[UNTRANSLATED] -3% Enemy Armor`,
|
upgrade_EnemyArmorReductionAura: `-3% d'armure ennemi`,
|
||||||
upgrade_OnExecutionAmmo: `[UNTRANSLATED] 100% Primary and Secondary Magazine Refill on Mercy`,
|
upgrade_OnExecutionAmmo: `100% de rechargement des armes primaires et secondaires sur une une miséricorde`,
|
||||||
upgrade_OnExecutionHealthDrop: `[UNTRANSLATED] 100% chance to drop a Health Orb on Mercy`,
|
upgrade_OnExecutionHealthDrop: `100% de chance de drop une orbe de santé sur une miséricorde`,
|
||||||
upgrade_OnExecutionEnergyDrop: `[UNTRANSLATED] 50% chance to drop an Energy Orb on Mercy`,
|
upgrade_OnExecutionEnergyDrop: `50% de chance de drop une orbe d'énergie sur une miséricorde`,
|
||||||
upgrade_OnFailHackReset: `[UNTRANSLATED] +50% to retry on Hacking failure`,
|
upgrade_OnFailHackReset: `[UNTRANSLATED] +50% to retry on Hacking failure`,
|
||||||
upgrade_DamageReductionOnHack: `[UNTRANSLATED] 75% Damage Reduction while Hacking`,
|
upgrade_DamageReductionOnHack: `75% de réduction de dégâts pendant un piratage`,
|
||||||
upgrade_OnExecutionReviveCompanion: `[UNTRANSLATED] Mercy Kills reduce Companion Recovery by 15s`,
|
upgrade_OnExecutionReviveCompanion: `Les miséricordes réduisent le temps de récupération du compagnon de 15s`,
|
||||||
upgrade_OnExecutionParkourSpeed: `[UNTRANSLATED] +60% Parkour Speed after a Mercy for 15s`,
|
upgrade_OnExecutionParkourSpeed: `+60% de vitesse de parkour pendant 15s après une miséricorde`,
|
||||||
upgrade_AvatarTimeLimitIncrease: `[UNTRANSLATED] +8s to Hacking`,
|
upgrade_AvatarTimeLimitIncrease: `+8s de temps de piratage`,
|
||||||
upgrade_ElectrifyOnHack: `[UNTRANSLATED] Shock enemies within 20m while Hacking`,
|
upgrade_ElectrifyOnHack: `Electrifie les ennemis dans un rayon de 20m pendant un piratage`,
|
||||||
upgrade_OnExecutionTerrify: `[UNTRANSLATED] 50% chance for enemies within 15m to cower in fear for 8 seconds on Mercy`,
|
upgrade_OnExecutionTerrify: `Les ennemis dans un rayon de 15m ont 50% de chance de s'enfuir après une miséricorde`,
|
||||||
upgrade_OnHackLockers: `[UNTRANSLATED] Unlock 5 lockers within 20m after Hacking`,
|
upgrade_OnHackLockers: `5 casiers s'ouvrent dans un rayon de 20m après un piratage`,
|
||||||
upgrade_OnExecutionBlind: `[UNTRANSLATED] Blind enemies within 18m on Mercy`,
|
upgrade_OnExecutionBlind: `Les ennemis sont aveuglés dans un rayon de 18 après une miséricorde`,
|
||||||
upgrade_OnExecutionDrainPower: `[UNTRANSLATED] 100% chance for next ability cast to gain +50% Ability Strength on Mercy`,
|
upgrade_OnExecutionDrainPower: `100% pour le prochain pouvoir de gagner +50% de puissance de pouvoir sur miséricorde`,
|
||||||
upgrade_OnHackSprintSpeed: `[UNTRANSLATED] +75% Sprint Speed for 15s after Hacking`,
|
upgrade_OnHackSprintSpeed: `+75% de vitesse de course pendant 15s après un piratage`,
|
||||||
upgrade_SwiftExecute: `[UNTRANSLATED] Speed of Mercy Kills increased by 50%`,
|
upgrade_SwiftExecute: `Vitesse des miséricordes augmentée de 50%`,
|
||||||
upgrade_OnHackInvis: `[UNTRANSLATED] Invisible for 15 seconds after hacking`,
|
upgrade_OnHackInvis: `Invisible pendant 15 secondes après un piratage`,
|
||||||
|
|
||||||
prettier_sucks_ass: ``
|
prettier_sucks_ass: ``
|
||||||
};
|
};
|
||||||
|
@ -181,6 +181,7 @@ dict = {
|
|||||||
cheats_account: `Аккаунт`,
|
cheats_account: `Аккаунт`,
|
||||||
cheats_unlockAllFocusSchools: `Разблокировать все школы фокуса`,
|
cheats_unlockAllFocusSchools: `Разблокировать все школы фокуса`,
|
||||||
cheats_helminthUnlockAll: `Полностью улучшить Гельминта`,
|
cheats_helminthUnlockAll: `Полностью улучшить Гельминта`,
|
||||||
|
cheats_addMissingSubsumedAbilities: `Добавить отсутствующие поглощённые способности`,
|
||||||
cheats_intrinsicsUnlockAll: `Полностью улучшить Модуляры`,
|
cheats_intrinsicsUnlockAll: `Полностью улучшить Модуляры`,
|
||||||
cheats_changeSupportedSyndicate: `Поддерживаемый синдикат`,
|
cheats_changeSupportedSyndicate: `Поддерживаемый синдикат`,
|
||||||
cheats_changeButton: `Изменить`,
|
cheats_changeButton: `Изменить`,
|
||||||
|
@ -181,6 +181,7 @@ dict = {
|
|||||||
cheats_account: `账户`,
|
cheats_account: `账户`,
|
||||||
cheats_unlockAllFocusSchools: `解锁所有专精学派`,
|
cheats_unlockAllFocusSchools: `解锁所有专精学派`,
|
||||||
cheats_helminthUnlockAll: `完全升级Helminth`,
|
cheats_helminthUnlockAll: `完全升级Helminth`,
|
||||||
|
cheats_addMissingSubsumedAbilities: `[UNTRANSLATED] Add Missing Subsumed Abilities`,
|
||||||
cheats_intrinsicsUnlockAll: `所有内源之力最大等级`,
|
cheats_intrinsicsUnlockAll: `所有内源之力最大等级`,
|
||||||
cheats_changeSupportedSyndicate: `支持的集团`,
|
cheats_changeSupportedSyndicate: `支持的集团`,
|
||||||
cheats_changeButton: `更改`,
|
cheats_changeButton: `更改`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user