feat: obtaining quest rewards #962

Closed
AMelonInsideLemon wants to merge 1 commits from AMelonInsideLemon:quest-rewards into main
5 changed files with 85 additions and 79 deletions

View File

@ -3,8 +3,7 @@ import { parseString } from "@/src/helpers/general";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { updateQuestKey, IUpdateQuestRequest } from "@/src/services/questService"; import { updateQuestKey, IUpdateQuestRequest } from "@/src/services/questService";
import { getQuestCompletionItems } from "@/src/services/itemDataService"; import { getInventory, handleKeyRewards } from "@/src/services/inventoryService";
import { addItems, getInventory } from "@/src/services/inventoryService";
import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes";
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
@ -27,13 +26,7 @@ export const updateQuestController: RequestHandler = async (req, res) => {
if (updateQuestRequest.QuestKeys[0].Completed) { if (updateQuestRequest.QuestKeys[0].Completed) {
logger.debug(`completed quest ${updateQuestRequest.QuestKeys[0].ItemType} `); logger.debug(`completed quest ${updateQuestRequest.QuestKeys[0].ItemType} `);
const questKeyName = updateQuestRequest.QuestKeys[0].ItemType; const questKeyName = updateQuestRequest.QuestKeys[0].ItemType;
const questCompletionItems = getQuestCompletionItems(questKeyName); updateQuestResponse.InventoryChanges = await handleKeyRewards(inventory, questKeyName);
logger.debug(`quest completion items`, questCompletionItems);
if (questCompletionItems) {
const inventoryChanges = await addItems(inventory, questCompletionItems);
updateQuestResponse.InventoryChanges = inventoryChanges;
}
inventory.ActiveQuest = ""; inventory.ActiveQuest = "";
} }

View File

@ -31,7 +31,7 @@ import {
IUpdateChallengeProgressRequest IUpdateChallengeProgressRequest
} from "../types/requestTypes"; } from "../types/requestTypes";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
import { getExalted, getKeyChainItems } from "@/src/services/itemDataService"; import { getExalted, getKeyChainItems, getKeyRewards } from "@/src/services/itemDataService";
import { IEquipmentClient, IItemConfig } from "../types/inventoryTypes/commonInventoryTypes"; import { IEquipmentClient, IItemConfig } from "../types/inventoryTypes/commonInventoryTypes";
import { import {
ExportArcanes, ExportArcanes,
@ -50,6 +50,7 @@ import { createShip } from "./shipService";
import { creditBundles, fusionBundles } from "@/src/services/missionInventoryUpdateService"; import { creditBundles, fusionBundles } from "@/src/services/missionInventoryUpdateService";
import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController"; import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController";
import { toOid } from "../helpers/inventoryHelpers"; import { toOid } from "../helpers/inventoryHelpers";
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
export const createInventory = async ( export const createInventory = async (
accountOwnerId: Types.ObjectId, accountOwnerId: Types.ObjectId,
@ -464,7 +465,8 @@ export const addItem = async (
} }
} }
case "Game": { case "Game": {
if (typeName.substr(1).split("/")[3] == "Projections") { switch (typeName.substr(1).split("/")[3]) {
case "Projections":
// Void Relics, e.g. /Lotus/Types/Game/Projections/T2VoidProjectionGaussPrimeDBronze // Void Relics, e.g. /Lotus/Types/Game/Projections/T2VoidProjectionGaussPrimeDBronze
const miscItemChanges = [ const miscItemChanges = [
{ {
@ -478,6 +480,14 @@ export const addItem = async (
MiscItems: miscItemChanges MiscItems: miscItemChanges
} }
}; };
case "CrewShip":
// Plexus - /Lotus/Types/Game/CrewShip/RailJack/DefaultHarness
const inventoryChanges = addCrewShipHarness(inventory, typeName);
return {
InventoryChanges: {
...inventoryChanges
}
};
} }
break; break;
} }
@ -1158,3 +1168,45 @@ export const addKeyChainItems = async (
return inventoryChanges; return inventoryChanges;
}; };
export const handleKeyRewards = async (
inventory: TInventoryDatabaseDocument,
keyType: string
): Promise<IInventoryChanges> => {
const keyRewards = getKeyRewards(keyType);
const inventoryChanges: IInventoryChanges = {};
const itemsToAdd: ITypeCount[] = [];
if (keyRewards) {
for (const item of keyRewards) {
let changes: IInventoryChanges = {};
switch (item.rewardType) {
case "RT_CREDITS":
const currencyChanges = updateCurrency(inventory, -item.amount, false);
changes = { ...currencyChanges } as IInventoryChanges;
break;
case "RT_STORE_ITEM":
changes = (await handleStoreItemAcquisition(item.itemType, inventory, 1)).InventoryChanges;
break;
case "RT_RECIPE":
itemsToAdd.push({ ItemType: item.itemType, ItemCount: 1 });
break;
case "RT_RESOURCE":
itemsToAdd.push({ ItemType: item.itemType, ItemCount: item.amount });
break;
}
combineInventoryChanges(inventoryChanges, changes);
}
}
if (itemsToAdd.length > 0) {
const resourceChanges = await addItems(inventory, itemsToAdd);
combineInventoryChanges(inventoryChanges, resourceChanges);
}
return inventoryChanges;
};

View File

@ -1,6 +1,5 @@
import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController"; import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController";
import { getIndexAfter } from "@/src/helpers/stringHelpers"; import { getIndexAfter } from "@/src/helpers/stringHelpers";
import { ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
import { import {
dict_de, dict_de,
@ -32,7 +31,6 @@ import {
IRecipe, IRecipe,
IRegion IRegion
} from "warframe-public-export-plus"; } from "warframe-public-export-plus";
import questCompletionItems from "@/static/fixed_responses/questCompletionRewards.json";
export type WeaponTypeInternal = export type WeaponTypeInternal =
| "LongGuns" | "LongGuns"
@ -162,23 +160,6 @@ export const getKeyChainItems = ({ KeyChain, ChainStage }: IKeyChainRequest): st
return keyChainStage.itemsToGiveWhenTriggered; return keyChainStage.itemsToGiveWhenTriggered;
}; };
export const getLevelKeyRewards = (levelKey: string) => {
const levelKeyData = ExportKeys[levelKey];
if (!levelKeyData) {
const error = `LevelKey ${levelKey} not found`;
logger.error(error);
throw new Error(error);
}
if (!levelKeyData.rewards) {
const error = `LevelKey ${levelKey} does not contain rewards`;
logger.error(error);
throw new Error(error);
}
return levelKeyData.rewards;
};
export const getNode = (nodeName: string): IRegion => { export const getNode = (nodeName: string): IRegion => {
const node = ExportRegions[nodeName]; const node = ExportRegions[nodeName];
if (!node) { if (!node) {
@ -188,15 +169,19 @@ export const getNode = (nodeName: string): IRegion => {
return node; return node;
}; };
export const getQuestCompletionItems = (questKey: string) => { export const getKeyRewards = (key: string) => {
const items = (questCompletionItems as unknown as Record<string, ITypeCount[]> | undefined)?.[questKey]; const keyData = ExportKeys[key];
if (!keyData) {
if (!items) { const error = `Key ${key} not found in ExportKeys`;
logger.error( logger.error(error);
`Quest ${questKey} not found in questCompletionItems, quest completion items have not been given. This is a temporary solution`
);
} }
return items;
if (!keyData.rewards) {
const error = `Key ${key} does not contain rewards`;
logger.debug(error);
}
return keyData.rewards;
}; };
export const getKeyChainMessage = ({ KeyChain, ChainStage }: IKeyChainRequest) => { export const getKeyChainMessage = ({ KeyChain, ChainStage }: IKeyChainRequest) => {

View File

@ -17,12 +17,13 @@ import {
addMods, addMods,
addRecipes, addRecipes,
combineInventoryChanges, combineInventoryChanges,
handleKeyRewards,
updateSyndicate updateSyndicate
} from "@/src/services/inventoryService"; } from "@/src/services/inventoryService";
import { updateQuestKey } from "@/src/services/questService"; import { updateQuestKey } from "@/src/services/questService";
import { HydratedDocument } from "mongoose"; import { HydratedDocument } from "mongoose";
import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes";
import { getLevelKeyRewards, getNode } from "@/src/services/itemDataService"; import { getNode } from "@/src/services/itemDataService";
import { InventoryDocumentProps, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { InventoryDocumentProps, 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";
@ -252,20 +253,8 @@ 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 (levelKeyName) { if (levelKeyName) {
const fixedLevelRewards = getLevelKeyRewards(levelKeyName); const levelFixedRewards = await handleKeyRewards(inventory, levelKeyName);
//logger.debug(`fixedLevelRewards ${fixedLevelRewards}`); combineInventoryChanges(inventoryChanges, levelFixedRewards);
for (const reward of fixedLevelRewards) {
//quest stage completion credit rewards
if (reward.rewardType == "RT_CREDITS") {
inventory.RegularCredits += reward.amount;
missionCompletionCredits += reward.amount;
continue;
}
MissionRewards.push({
StoreItem: reward.itemType,
ItemCount: reward.rewardType === "RT_RESOURCE" ? reward.amount : 1
});
}
} }
for (const reward of MissionRewards) { for (const reward of MissionRewards) {

View File

@ -1,13 +0,0 @@
{
"/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain": [
{
"ItemType": "/Lotus/Types/Keys/DuviriQuest/DuviriQuestKeyChain",
"ItemCount": 1
},
{
"ItemType": "/Lotus/Types/NeutralCreatures/ErsatzHorse/ErsatzHorsePowerSuit",
"ItemCount": 1
}
],
"/Lotus/Types/Keys/InfestedMicroplanetQuest/InfestedMicroplanetQuestKeyChain": [{ "ItemType": "/Lotus/Types/Recipes/WarframeRecipes/BrokenFrameBlueprint", "ItemCount": 1 }]
}