diff --git a/project/src/helpers/DialogueHelper.ts b/project/src/helpers/DialogueHelper.ts index 585914ea..71e7ff66 100644 --- a/project/src/helpers/DialogueHelper.ts +++ b/project/src/helpers/DialogueHelper.ts @@ -21,7 +21,7 @@ export class DialogueHelper { @inject("NotificationSendHelper") protected notificationSendHelper: NotificationSendHelper, @inject("LocalisationService") protected localisationService: LocalisationService, @inject("ItemHelper") protected itemHelper: ItemHelper, - ) {} + ) { } /** * Get the preview contents of the last message in a dialogue. @@ -102,4 +102,23 @@ export class DialogueHelper { return profile.dialogues; } + + /** + * @param profileId ProfileId to retrieve from + * @param dialogueId The id of the dialogue to find + * @returns Dialogue if found, otherwise undefined + */ + public getDialogueFromProfile(profileId: string, dialogueId: string): IDialogue | undefined { + let returnDialogue: IDialogue | undefined = undefined; + const dialogues = this.getDialogsForProfile(profileId); + + for (const dialogue of Object.values(dialogues)) { + if (dialogue._id === dialogueId) { + returnDialogue = dialogue; + break; + } + } + + return returnDialogue; + } } diff --git a/project/src/helpers/InventoryHelper.ts b/project/src/helpers/InventoryHelper.ts index 801984ab..d4ab439a 100644 --- a/project/src/helpers/InventoryHelper.ts +++ b/project/src/helpers/InventoryHelper.ts @@ -161,8 +161,7 @@ export class InventoryHelper { pmcData.Inventory.items.push(...itemWithModsToAddClone); this.logger.debug( - `Added ${itemWithModsToAddClone[0].upd?.StackObjectsCount ?? 1} item: ${ - itemWithModsToAddClone[0]._tpl + `Added ${itemWithModsToAddClone[0].upd?.StackObjectsCount ?? 1} item: ${itemWithModsToAddClone[0]._tpl } with: ${itemWithModsToAddClone.length - 1} mods to inventory`, ); } diff --git a/project/src/models/spt/dialog/ISendMessageDetails.ts b/project/src/models/spt/dialog/ISendMessageDetails.ts index 0df9673d..6e27edda 100644 --- a/project/src/models/spt/dialog/ISendMessageDetails.ts +++ b/project/src/models/spt/dialog/ISendMessageDetails.ts @@ -30,6 +30,8 @@ export interface ISendMessageDetails { ragfairDetails?: IMessageContentRagfair; /** OPTIONAL - allows modification of profile settings via mail */ profileChangeEvents?: IProfileChangeEvent[]; + /** Optional - the MongoID of the dialogue message to reply to */ + replyTo?: string; } export interface IProfileChangeEvent { diff --git a/project/src/services/MailSendService.ts b/project/src/services/MailSendService.ts index cddf662f..2767373d 100644 --- a/project/src/services/MailSendService.ts +++ b/project/src/services/MailSendService.ts @@ -5,7 +5,7 @@ import { NotifierHelper } from "@spt/helpers/NotifierHelper"; import { TraderHelper } from "@spt/helpers/TraderHelper"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IMessageContentRagfair } from "@spt/models/eft/profile/IMessageContentRagfair"; -import { IDialogue, IMessage, IMessageItems } from "@spt/models/eft/profile/ISptProfile"; +import { IDialogue, IMessage, IMessageItems, IReplyTo } from "@spt/models/eft/profile/ISptProfile"; import { ISystemData } from "@spt/models/eft/profile/ISystemData"; import { IUserDialogInfo } from "@spt/models/eft/profile/IUserDialogInfo"; import { BaseClasses } from "@spt/models/enums/BaseClasses"; @@ -36,7 +36,7 @@ export class MailSendService { @inject("LocalisationService") protected localisationService: LocalisationService, @inject("ItemHelper") protected itemHelper: ItemHelper, @inject("TraderHelper") protected traderHelper: TraderHelper, - ) {} + ) { } /** * Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale @@ -348,6 +348,14 @@ export class MailSendService { messageDetails.profileChangeEvents?.length === 0 ? messageDetails.profileChangeEvents : undefined, // no one knows, its never been used in any dumps }; + // handle replyTo + if (messageDetails.replyTo) { + const replyMessage = this.getMessageToReplyTo(messageDetails.recipientId, messageDetails.replyTo, dialogId); + if (replyMessage) { + message.replyTo = replyMessage; + } + } + // Clean up empty system data if (!message.systemData) { // biome-ignore lint/performance/noDelete: Delete is fine here as we're trying to remove the entire data property. @@ -363,6 +371,37 @@ export class MailSendService { return message; } + /** + * @param recipientId The id of the recipient + * @param replyToId The id of the message to reply to + * @param dialogueId The id of the dialogue (traderId or profileId) + * @returns A new instance with data from the found message, otherwise undefined + */ + private getMessageToReplyTo(recipientId: string, replyToId: string, dialogueId: string): IReplyTo | undefined { + let message: IReplyTo | undefined = undefined; + const currentDialogue = this.dialogueHelper.getDialogueFromProfile(recipientId, dialogueId); + + if (!currentDialogue) { + this.logger.warning(`Could not find dialogue ${dialogueId} from sender`); + return message; + } + + for (const dialogueMessage of currentDialogue.messages) { + if (dialogueMessage._id === replyToId) { + message = { + _id: dialogueMessage._id, + dt: dialogueMessage.dt, + type: dialogueMessage.type, + uid: dialogueMessage.uid, + text: dialogueMessage.text + }; + break; + } + } + + return message; + } + /** * Add items to message and adjust various properties to reflect the items being added * @param message Message to add items to