forked from OpenWF/SpaceNinjaServer
chore: cleanup missionInventoryUpdateService (#349)
Co-authored-by: Sainan <Sainan@users.noreply.github.com>
This commit is contained in:
parent
56f9be9725
commit
079d67807a
8
package-lock.json
generated
8
package-lock.json
generated
@ -13,7 +13,7 @@
|
||||
"express": "^5.0.0-beta.3",
|
||||
"mongoose": "^8.1.1",
|
||||
"warframe-items": "^1.1262.74",
|
||||
"warframe-public-export-plus": "^0.2.5",
|
||||
"warframe-public-export-plus": "^0.3.0",
|
||||
"warframe-riven-info": "^0.1.0",
|
||||
"winston": "^3.11.0",
|
||||
"winston-daily-rotate-file": "^4.7.1"
|
||||
@ -3678,9 +3678,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/warframe-public-export-plus": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.2.5.tgz",
|
||||
"integrity": "sha512-IsS2Z14CeTpGSpfeUxqTi8wAQjQ6qjh2kV8RC9St5hcDmII3NpwEFXmStEqz7r+JPfea72D3cZMMl+4QLHqvXw=="
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.3.0.tgz",
|
||||
"integrity": "sha512-BYkTkCq9jsA8NzSiWsTW48ezK7kI/op2NrLf+j4j3bJi2cNjoSLf/D4bMEui6yCADjcoV89ramRTFbPjn6UpLA=="
|
||||
},
|
||||
"node_modules/warframe-riven-info": {
|
||||
"version": "0.1.0",
|
||||
|
@ -17,7 +17,7 @@
|
||||
"express": "^5.0.0-beta.3",
|
||||
"mongoose": "^8.1.1",
|
||||
"warframe-items": "^1.1262.74",
|
||||
"warframe-public-export-plus": "^0.2.5",
|
||||
"warframe-public-export-plus": "^0.3.0",
|
||||
"warframe-riven-info": "^0.1.0",
|
||||
"winston": "^3.11.0",
|
||||
"winston-daily-rotate-file": "^4.7.1"
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { getIndexAfter } from "@/src/helpers/stringHelpers";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
import Items, { Category, MinimalItem, Warframe, Weapon } from "warframe-items";
|
||||
import badItems from "@/static/json/exclude-mods.json";
|
||||
import Items, { MinimalItem, Warframe, Weapon } from "warframe-items";
|
||||
import {
|
||||
dict_en,
|
||||
ExportRecipes,
|
||||
@ -53,23 +52,6 @@ export const getWeaponType = (weaponName: string): WeaponTypeInternal => {
|
||||
return weaponType;
|
||||
};
|
||||
|
||||
const getNamesObj = (category: Category) =>
|
||||
new Items({ category: [category] }).reduce<{ [index: string]: string }>((acc, item) => {
|
||||
if (!(item.uniqueName! in badItems)) {
|
||||
acc[item.name!.replace("'S", "'s")] = item.uniqueName!;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
export const modNames = getNamesObj("Mods");
|
||||
export const resourceNames = getNamesObj("Resources");
|
||||
export const miscNames = getNamesObj("Misc");
|
||||
export const relicNames = getNamesObj("Relics");
|
||||
export const skinNames = getNamesObj("Skins");
|
||||
export const arcaneNames = getNamesObj("Arcanes");
|
||||
export const gearNames = getNamesObj("Gear");
|
||||
//logger.debug(`gear names`, { gearNames });
|
||||
|
||||
export const craftNames = Object.fromEntries(
|
||||
(
|
||||
new Items({
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { IMissionRewardResponse, IReward, IInventoryFieldType, inventoryFields } from "@/src/types/missionTypes";
|
||||
import { IMissionRewardResponse, IInventoryFieldType, inventoryFields } from "@/src/types/missionTypes";
|
||||
|
||||
import missionsDropTable from "@/static/json/missions-drop-table.json";
|
||||
import {
|
||||
modNames,
|
||||
relicNames,
|
||||
miscNames,
|
||||
resourceNames,
|
||||
gearNames,
|
||||
blueprintNames
|
||||
} from "@/src/services/itemDataService";
|
||||
ExportRegions,
|
||||
ExportRewards,
|
||||
ExportUpgrades,
|
||||
ExportGear,
|
||||
ExportRecipes,
|
||||
ExportRelics,
|
||||
IReward
|
||||
} from "warframe-public-export-plus";
|
||||
import { IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
||||
import { logger } from "@/src/utils/logger";
|
||||
|
||||
@ -23,49 +23,25 @@ const getRewards = ({
|
||||
return { InventoryChanges: {}, MissionRewards: [] };
|
||||
}
|
||||
|
||||
const rewards = (missionsDropTable as { [key: string]: IReward[] })[RewardInfo.node];
|
||||
if (!rewards) {
|
||||
const rewardManifests = ExportRegions[RewardInfo.node]?.rewardManifests ?? [];
|
||||
if (rewardManifests.length == 0) {
|
||||
return { InventoryChanges: {}, MissionRewards: [] };
|
||||
}
|
||||
|
||||
const rotationCount = RewardInfo.rewardQualifications?.length || 0;
|
||||
const rotations = getRotations(rotationCount);
|
||||
const drops: IReward[] = [];
|
||||
for (const rotation of rotations) {
|
||||
const rotationRewards = rewards.filter(reward => reward.rotation === rotation);
|
||||
|
||||
// Separate guaranteed and chance drops
|
||||
const guaranteedDrops: IReward[] = [];
|
||||
const chanceDrops: IReward[] = [];
|
||||
for (const reward of rotationRewards) {
|
||||
if (reward.chance === 100) {
|
||||
guaranteedDrops.push(reward);
|
||||
} else {
|
||||
chanceDrops.push(reward);
|
||||
rewardManifests
|
||||
.map(name => ExportRewards[name])
|
||||
.forEach(table => {
|
||||
for (const rotation of rotations) {
|
||||
const rotationRewards = table[rotation];
|
||||
const drop = getRandomRewardByChance(rotationRewards);
|
||||
if (drop) {
|
||||
drops.push(drop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const randomDrop = getRandomRewardByChance(chanceDrops);
|
||||
if (randomDrop) {
|
||||
guaranteedDrops.push(randomDrop);
|
||||
}
|
||||
|
||||
drops.push(...guaranteedDrops);
|
||||
}
|
||||
|
||||
// const testDrops = [
|
||||
// { chance: 7.69, name: "Lith W3 Relic", rotation: "B" },
|
||||
// { chance: 7.69, name: "Lith W3 Relic", rotation: "B" },
|
||||
// { chance: 10.82, name: "2X Orokin Cell", rotation: "C" },
|
||||
// { chance: 10.82, name: "Arrow Mutation", rotation: "C" },
|
||||
// { chance: 10.82, name: "200 Endo", rotation: "C" },
|
||||
// { chance: 10.82, name: "200 Endo", rotation: "C" },
|
||||
// { chance: 10.82, name: "2,000,000 Credits Cache", rotation: "C" },
|
||||
// { chance: 7.69, name: "Health Restore (Large)", rotation: "C" },
|
||||
// { chance: 7.69, name: "Vapor Specter Blueprint", rotation: "C" }
|
||||
// ];
|
||||
// logger.debug("Mission rewards:", testDrops);
|
||||
// return formatRewardsToInventoryType(testDrops);
|
||||
});
|
||||
|
||||
logger.debug("Mission rewards:", drops);
|
||||
return formatRewardsToInventoryType(drops);
|
||||
@ -100,10 +76,10 @@ const combineRewardAndLootInventory = (
|
||||
};
|
||||
};
|
||||
|
||||
const getRotations = (rotationCount: number): (string | undefined)[] => {
|
||||
if (rotationCount === 0) return [undefined];
|
||||
const getRotations = (rotationCount: number): number[] => {
|
||||
if (rotationCount === 0) return [0];
|
||||
|
||||
const rotationPattern = ["A", "A", "B", "C"];
|
||||
const rotationPattern = [0, 0, 1, 2]; // A, A, B, C
|
||||
const rotatedValues = [];
|
||||
|
||||
for (let i = 0; i < rotationCount; i++) {
|
||||
@ -113,15 +89,15 @@ const getRotations = (rotationCount: number): (string | undefined)[] => {
|
||||
return rotatedValues;
|
||||
};
|
||||
|
||||
const getRandomRewardByChance = (data: IReward[] | undefined): IReward | undefined => {
|
||||
if (!data || data.length == 0) return;
|
||||
const getRandomRewardByChance = (data: IReward[]): IReward | undefined => {
|
||||
if (data.length == 0) return;
|
||||
|
||||
const totalChance = data.reduce((sum, item) => sum + item.chance, 0);
|
||||
const totalChance = data.reduce((sum, item) => sum + item.probability!, 0);
|
||||
const randomValue = Math.random() * totalChance;
|
||||
|
||||
let cumulativeChance = 0;
|
||||
for (const item of data) {
|
||||
cumulativeChance += item.chance;
|
||||
cumulativeChance += item.probability!;
|
||||
if (randomValue <= cumulativeChance) {
|
||||
return item;
|
||||
}
|
||||
@ -130,68 +106,62 @@ const getRandomRewardByChance = (data: IReward[] | undefined): IReward | undefin
|
||||
return;
|
||||
};
|
||||
|
||||
const creditBundles: Record<string, number> = {
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/1500Credits": 1500,
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/2000Credits": 2000,
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/2500Credits": 2500,
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/3000Credits": 3000,
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/4000Credits": 4000,
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/5000Credits": 5000,
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/7500Credits": 7500,
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/10000Credits": 10000,
|
||||
"/Lotus/StoreItems/Types/StoreItems/CreditBundles/Zariman/TableACreditsCommon": 15000,
|
||||
"/Lotus/StoreItems/Types/StoreItems/CreditBundles/Zariman/TableACreditsUncommon": 30000,
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/CorpusArenaCreditRewards/CorpusArenaRewardOneHard": 105000,
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/CorpusArenaCreditRewards/CorpusArenaRewardTwoHard": 175000,
|
||||
"/Lotus/StoreItems/Types/PickUps/Credits/CorpusArenaCreditRewards/CorpusArenaRewardThreeHard": 25000
|
||||
};
|
||||
|
||||
const fusionBundles: Record<string, number> = {
|
||||
"/Lotus/StoreItems/Upgrades/Mods/FusionBundles/UncommonFusionBundle": 50,
|
||||
"/Lotus/StoreItems/Upgrades/Mods/FusionBundles/RareFusionBundle": 80
|
||||
};
|
||||
|
||||
const formatRewardsToInventoryType = (
|
||||
rewards: IReward[]
|
||||
): { InventoryChanges: IMissionInventoryUpdateRequest; MissionRewards: IMissionRewardResponse[] } => {
|
||||
const InventoryChanges: IMissionInventoryUpdateRequest = {};
|
||||
const MissionRewards: IMissionRewardResponse[] = [];
|
||||
for (const reward of rewards) {
|
||||
if (itemCheck(InventoryChanges, MissionRewards, reward.name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reward.name.includes(" Endo")) {
|
||||
if (!InventoryChanges.FusionPoints) {
|
||||
InventoryChanges.FusionPoints = 0;
|
||||
if (reward.type in creditBundles) {
|
||||
InventoryChanges.RegularCredits ??= 0;
|
||||
InventoryChanges.RegularCredits += creditBundles[reward.type] * reward.itemCount;
|
||||
} else if (reward.type in fusionBundles) {
|
||||
InventoryChanges.FusionPoints ??= 0;
|
||||
InventoryChanges.FusionPoints += fusionBundles[reward.type] * reward.itemCount;
|
||||
} else {
|
||||
const type = reward.type.replace("/Lotus/StoreItems/", "/Lotus/");
|
||||
if (type in ExportUpgrades) {
|
||||
addRewardResponse(InventoryChanges, MissionRewards, type, reward.itemCount, "RawUpgrades");
|
||||
} else if (type in ExportGear) {
|
||||
addRewardResponse(InventoryChanges, MissionRewards, type, reward.itemCount, "Consumables");
|
||||
} else if (type in ExportRecipes) {
|
||||
addRewardResponse(InventoryChanges, MissionRewards, type, reward.itemCount, "Recipes");
|
||||
} else if (type in ExportRelics) {
|
||||
addRewardResponse(InventoryChanges, MissionRewards, type, reward.itemCount, "MiscItems");
|
||||
} else {
|
||||
logger.error(`rolled reward ${reward.itemCount}X ${reward.type} but unsure how to give it`);
|
||||
}
|
||||
InventoryChanges.FusionPoints += getCountFromName(reward.name);
|
||||
} else if (reward.name.includes(" Credits Cache") || reward.name.includes("Return: ")) {
|
||||
if (!InventoryChanges.RegularCredits) {
|
||||
InventoryChanges.RegularCredits = 0;
|
||||
}
|
||||
InventoryChanges.RegularCredits += getCountFromName(reward.name);
|
||||
}
|
||||
}
|
||||
return { InventoryChanges, MissionRewards };
|
||||
};
|
||||
|
||||
const itemCheck = (
|
||||
InventoryChanges: IMissionInventoryUpdateRequest,
|
||||
MissionRewards: IMissionRewardResponse[],
|
||||
name: string
|
||||
) => {
|
||||
const rewardCheck = {
|
||||
RawUpgrades: modNames[name],
|
||||
Consumables: gearNames[name],
|
||||
MiscItems:
|
||||
miscNames[name] ||
|
||||
miscNames[name.replace(/\d+X\s*/, "")] ||
|
||||
resourceNames[name] ||
|
||||
resourceNames[name.replace(/\d+X\s*/, "")] ||
|
||||
relicNames[name.replace("Relic", "Intact")] ||
|
||||
relicNames[name.replace("Relic (Radiant)", "Radiant")],
|
||||
Recipes: blueprintNames[name]
|
||||
};
|
||||
for (const key of Object.keys(rewardCheck) as IInventoryFieldType[]) {
|
||||
if (rewardCheck[key]) {
|
||||
addRewardResponse(InventoryChanges, MissionRewards, name, rewardCheck[key], key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const getCountFromName = (name: string) => {
|
||||
const regex = /(^(?:\d{1,3}(?:,\d{3})*(?:\.\d+)?)(\s|X))|(\s(?:\d{1,3}(?:,\d{3})*(?:\.\d+)?)$)/;
|
||||
const countMatches = name.match(regex);
|
||||
return countMatches ? parseInt(countMatches[0].replace(/,/g, ""), 10) : 1;
|
||||
};
|
||||
|
||||
const addRewardResponse = (
|
||||
InventoryChanges: IMissionInventoryUpdateRequest,
|
||||
MissionRewards: IMissionRewardResponse[],
|
||||
ItemName: string,
|
||||
ItemType: string,
|
||||
ItemCount: number,
|
||||
InventoryCategory: IInventoryFieldType
|
||||
) => {
|
||||
if (!ItemType) return;
|
||||
@ -200,9 +170,6 @@ const addRewardResponse = (
|
||||
InventoryChanges[InventoryCategory] = [];
|
||||
}
|
||||
|
||||
const ItemCount = getCountFromName(ItemName);
|
||||
const TweetText = `${ItemName}`;
|
||||
|
||||
const existReward = InventoryChanges[InventoryCategory]!.find(item => item.ItemType === ItemType);
|
||||
if (existReward) {
|
||||
existReward.ItemCount += ItemCount;
|
||||
@ -214,7 +181,7 @@ const addRewardResponse = (
|
||||
InventoryChanges[InventoryCategory]!.push({ ItemType, ItemCount });
|
||||
MissionRewards.push({
|
||||
ItemCount,
|
||||
TweetText,
|
||||
TweetText: ItemType, // ensure if/how this even still used, or if it's needed at all
|
||||
ProductCategory: InventoryCategory,
|
||||
StoreItem: ItemType.replace("/Lotus/", "/Lotus/StoreItems/"),
|
||||
TypeName: ItemType
|
||||
@ -222,32 +189,4 @@ const addRewardResponse = (
|
||||
}
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const _missionRewardsCheckAllNamings = () => {
|
||||
let tempRewards: IReward[] = [];
|
||||
Object.values(missionsDropTable as { [key: string]: IReward[] }).forEach(rewards => {
|
||||
rewards.forEach(reward => {
|
||||
tempRewards.push(reward);
|
||||
});
|
||||
});
|
||||
tempRewards = tempRewards
|
||||
.filter(reward => !modNames[reward.name])
|
||||
.filter(reward => !miscNames[reward.name])
|
||||
.filter(reward => !miscNames[reward.name.replace(/\d+X\s*/, "")])
|
||||
.filter(reward => !resourceNames[reward.name])
|
||||
.filter(reward => !resourceNames[reward.name.replace(/\d+X\s*/, "")])
|
||||
.filter(reward => !gearNames[reward.name])
|
||||
.filter(reward => {
|
||||
return (
|
||||
!relicNames[reward.name.replace("Relic", "Intact")] &&
|
||||
!relicNames[reward.name.replace("Relic (Radiant)", "Radiant")]
|
||||
);
|
||||
})
|
||||
.filter(reward => !blueprintNames[reward.name])
|
||||
.filter(reward => !reward.name.includes(" Endo"))
|
||||
.filter(reward => !reward.name.includes(" Credits Cache") && !reward.name.includes("Return: "));
|
||||
logger.debug(`temp rewards`, { tempRewards });
|
||||
};
|
||||
// _missionRewardsCheckAllNamings();
|
||||
|
||||
export { getRewards, combineRewardAndLootInventory };
|
||||
|
@ -9,9 +9,3 @@ export interface IMissionRewardResponse {
|
||||
TweetText: string;
|
||||
ProductCategory: string;
|
||||
}
|
||||
|
||||
export interface IReward {
|
||||
name: string;
|
||||
chance: number;
|
||||
rotation?: string;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ export interface IMissionInventoryUpdateRequestRewardInfo {
|
||||
lostTargetWave?: number;
|
||||
defenseTargetCount?: number;
|
||||
EOM_AFK?: number;
|
||||
rewardQualifications?: string;
|
||||
rewardQualifications?: string; // did a Survival for 5 minutes and this was "1"
|
||||
PurgatoryRewardQualifications?: string;
|
||||
rewardSeed?: number;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user