Improve handling of a mail profileChangeEvents
property
This commit is contained in:
parent
7c2d93e87b
commit
c015882eac
@ -19,6 +19,7 @@ import { IInventoryTagRequestData } from "@spt-aki/models/eft/inventory/IInvento
|
|||||||
import { IInventoryToggleRequestData } from "@spt-aki/models/eft/inventory/IInventoryToggleRequestData";
|
import { IInventoryToggleRequestData } from "@spt-aki/models/eft/inventory/IInventoryToggleRequestData";
|
||||||
import { IInventoryTransferRequestData } from "@spt-aki/models/eft/inventory/IInventoryTransferRequestData";
|
import { IInventoryTransferRequestData } from "@spt-aki/models/eft/inventory/IInventoryTransferRequestData";
|
||||||
import { IOpenRandomLootContainerRequestData } from "@spt-aki/models/eft/inventory/IOpenRandomLootContainerRequestData";
|
import { IOpenRandomLootContainerRequestData } from "@spt-aki/models/eft/inventory/IOpenRandomLootContainerRequestData";
|
||||||
|
import { IRedeemProfileRequestData } from "@spt-aki/models/eft/inventory/IRedeemProfileRequestData";
|
||||||
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
@ -156,4 +157,12 @@ export class InventoryCallbacks
|
|||||||
{
|
{
|
||||||
return this.inventoryController.openRandomLootContainer(pmcData, body, sessionID);
|
return this.inventoryController.openRandomLootContainer(pmcData, body, sessionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public redeemProfileReward(pmcData: IPmcData,
|
||||||
|
body: IRedeemProfileRequestData,
|
||||||
|
sessionId: string
|
||||||
|
): IItemEventRouterResponse
|
||||||
|
{
|
||||||
|
return this.inventoryController.redeemProfileReward(pmcData, body, sessionId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import { IInventoryTagRequestData } from "@spt-aki/models/eft/inventory/IInvento
|
|||||||
import { IInventoryToggleRequestData } from "@spt-aki/models/eft/inventory/IInventoryToggleRequestData";
|
import { IInventoryToggleRequestData } from "@spt-aki/models/eft/inventory/IInventoryToggleRequestData";
|
||||||
import { IInventoryTransferRequestData } from "@spt-aki/models/eft/inventory/IInventoryTransferRequestData";
|
import { IInventoryTransferRequestData } from "@spt-aki/models/eft/inventory/IInventoryTransferRequestData";
|
||||||
import { IOpenRandomLootContainerRequestData } from "@spt-aki/models/eft/inventory/IOpenRandomLootContainerRequestData";
|
import { IOpenRandomLootContainerRequestData } from "@spt-aki/models/eft/inventory/IOpenRandomLootContainerRequestData";
|
||||||
|
import { IRedeemProfileRequestData } from "@spt-aki/models/eft/inventory/IRedeemProfileRequestData";
|
||||||
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
||||||
import { BackendErrorCodes } from "@spt-aki/models/enums/BackendErrorCodes";
|
import { BackendErrorCodes } from "@spt-aki/models/enums/BackendErrorCodes";
|
||||||
import { SkillTypes } from "@spt-aki/models/enums/SkillTypes";
|
import { SkillTypes } from "@spt-aki/models/enums/SkillTypes";
|
||||||
@ -36,6 +37,7 @@ import { EventOutputHolder } from "@spt-aki/routers/EventOutputHolder";
|
|||||||
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
||||||
import { FenceService } from "@spt-aki/services/FenceService";
|
import { FenceService } from "@spt-aki/services/FenceService";
|
||||||
import { LocalisationService } from "@spt-aki/services/LocalisationService";
|
import { LocalisationService } from "@spt-aki/services/LocalisationService";
|
||||||
|
import { PlayerService } from "@spt-aki/services/PlayerService";
|
||||||
import { RagfairOfferService } from "@spt-aki/services/RagfairOfferService";
|
import { RagfairOfferService } from "@spt-aki/services/RagfairOfferService";
|
||||||
import { HashUtil } from "@spt-aki/utils/HashUtil";
|
import { HashUtil } from "@spt-aki/utils/HashUtil";
|
||||||
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
|
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
|
||||||
@ -60,6 +62,7 @@ export class InventoryController
|
|||||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
||||||
@inject("PaymentHelper") protected paymentHelper: PaymentHelper,
|
@inject("PaymentHelper") protected paymentHelper: PaymentHelper,
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||||
|
@inject("PlayerService") protected playerService: PlayerService,
|
||||||
@inject("LootGenerator") protected lootGenerator: LootGenerator,
|
@inject("LootGenerator") protected lootGenerator: LootGenerator,
|
||||||
@inject("EventOutputHolder") protected eventOutputHolder: EventOutputHolder,
|
@inject("EventOutputHolder") protected eventOutputHolder: EventOutputHolder,
|
||||||
@inject("HttpResponseUtil") protected httpResponseUtil: HttpResponseUtil,
|
@inject("HttpResponseUtil") protected httpResponseUtil: HttpResponseUtil,
|
||||||
@ -649,19 +652,32 @@ export class InventoryController
|
|||||||
|
|
||||||
if (itemId)
|
if (itemId)
|
||||||
{
|
{
|
||||||
// item found
|
this.flagItemsAsInspectedAndRewardXp([itemId], pmcData);
|
||||||
const item = this.databaseServer.getTables().templates.items[itemId];
|
|
||||||
|
|
||||||
pmcData.Info.Experience += item._props.ExamineExperience;
|
|
||||||
pmcData.Encyclopedia[itemId] = true;
|
|
||||||
|
|
||||||
// TODO: update this with correct calculation using values from globals json
|
|
||||||
this.profileHelper.addSkillPointsToPlayer(pmcData, SkillTypes.INTELLECT, 0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.eventOutputHolder.getOutput(sessionID);
|
return this.eventOutputHolder.getOutput(sessionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected flagItemsAsInspectedAndRewardXp(itemTpls: string[], pmcProfile: IPmcData): void
|
||||||
|
{
|
||||||
|
for (const itemTpl of itemTpls)
|
||||||
|
{
|
||||||
|
// item found
|
||||||
|
const item = this.databaseServer.getTables().templates.items[itemTpl];
|
||||||
|
if (!item)
|
||||||
|
{
|
||||||
|
this.logger.warning(`Unable to find item with id ${itemTpl}, skipping inspection`)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pmcProfile.Info.Experience += item._props.ExamineExperience;
|
||||||
|
pmcProfile.Encyclopedia[itemTpl] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: update this with correct calculation using values from globals json
|
||||||
|
this.profileHelper.addSkillPointsToPlayer(pmcProfile, SkillTypes.INTELLECT, 0.05 * itemTpls.length);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the tplid of an item from the examine request object
|
* Get the tplid of an item from the examine request object
|
||||||
* @param body response request
|
* @param body response request
|
||||||
@ -910,4 +926,59 @@ export class InventoryController
|
|||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public redeemProfileReward(pmcData: IPmcData, request: IRedeemProfileRequestData, sessionId: string): IItemEventRouterResponse
|
||||||
|
{
|
||||||
|
const output = this.eventOutputHolder.getOutput(sessionId);
|
||||||
|
|
||||||
|
const fullprofile = this.profileHelper.getFullProfile(sessionId);
|
||||||
|
for (const event of request.events)
|
||||||
|
{
|
||||||
|
// Hard coded to `SYSTEM` for now
|
||||||
|
// TODO: make this dynamic
|
||||||
|
const dialog = fullprofile.dialogues["59e7125688a45068a6249071"];
|
||||||
|
const mail = dialog.messages.find(x => x._id === event.MessageId);
|
||||||
|
const mailEvent = mail.profileChangeEvents.find(x => x._id === event.EventId);
|
||||||
|
|
||||||
|
switch (mailEvent.Type)
|
||||||
|
{
|
||||||
|
case "TraderSalesSum":
|
||||||
|
pmcData.TradersInfo[mailEvent.entity].salesSum = mailEvent.value;
|
||||||
|
this.logger.success(`Set trader ${mailEvent.entity}: Sales Sum to: ${mailEvent.value}`);
|
||||||
|
break;
|
||||||
|
case "TraderStanding":
|
||||||
|
pmcData.TradersInfo[mailEvent.entity].standing = mailEvent.value;
|
||||||
|
this.logger.success(`Set trader ${mailEvent.entity}: Standing to: ${mailEvent.value}`);
|
||||||
|
break;
|
||||||
|
case "ProfileLevel":
|
||||||
|
pmcData.Info.Experience = mailEvent.value;
|
||||||
|
pmcData.Info.Level = this.playerService.calculateLevel(pmcData);
|
||||||
|
this.logger.success(`Set profile xp to: ${mailEvent.value}`);
|
||||||
|
break;
|
||||||
|
case "SkillPoints":
|
||||||
|
{
|
||||||
|
const profileSkill = pmcData.Skills.Common.find(x => x.Id === mailEvent.entity);
|
||||||
|
profileSkill.Progress = mailEvent.value;
|
||||||
|
this.logger.success(`Set profile skill: ${mailEvent.entity} to: ${mailEvent.value}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "ExamineAllItems":
|
||||||
|
{
|
||||||
|
const itemsToInspect = this.itemHelper.getItems().filter(x => x._type !== "Node");
|
||||||
|
this.flagItemsAsInspectedAndRewardXp(itemsToInspect.map(x => x._id), pmcData);
|
||||||
|
this.logger.success(`Flagged ${itemsToInspect.length} items as examined`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "UnlockTrader":
|
||||||
|
pmcData.TradersInfo[mailEvent.entity].unlocked = true;
|
||||||
|
this.logger.success(`Trader ${mailEvent.entity} Unlocked`);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.logger.success(`Unhandled profile reward event: ${mailEvent.Type}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
import { IInventoryBaseActionRequestData } from "./IInventoryBaseActionRequestData";
|
||||||
|
|
||||||
|
export interface IRedeemProfileRequestData extends IInventoryBaseActionRequestData
|
||||||
|
{
|
||||||
|
Action: "RedeemProfileReward";
|
||||||
|
events: IRedeemProfileRequestEvent[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IRedeemProfileRequestEvent
|
||||||
|
{
|
||||||
|
MessageId: string
|
||||||
|
EventId: string
|
||||||
|
}
|
@ -3,6 +3,7 @@ import { Item } from "@spt-aki/models/eft/common/tables/IItem";
|
|||||||
import { EquipmentBuildType } from "@spt-aki/models/enums/EquipmentBuildType";
|
import { EquipmentBuildType } from "@spt-aki/models/enums/EquipmentBuildType";
|
||||||
import { MemberCategory } from "@spt-aki/models/enums/MemberCategory";
|
import { MemberCategory } from "@spt-aki/models/enums/MemberCategory";
|
||||||
import { MessageType } from "@spt-aki/models/enums/MessageType";
|
import { MessageType } from "@spt-aki/models/enums/MessageType";
|
||||||
|
import { IProfileChangeEvent } from "@spt-aki/models/spt/dialog/ISendMessageDetails";
|
||||||
|
|
||||||
export interface IAkiProfile
|
export interface IAkiProfile
|
||||||
{
|
{
|
||||||
@ -120,7 +121,7 @@ export interface Message
|
|||||||
items?: MessageItems;
|
items?: MessageItems;
|
||||||
maxStorageTime?: number;
|
maxStorageTime?: number;
|
||||||
systemData?: ISystemData;
|
systemData?: ISystemData;
|
||||||
profileChangeEvents?: any[];
|
profileChangeEvents?: IProfileChangeEvent[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MessagePreview
|
export interface MessagePreview
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
export enum ItemEventActions
|
export enum ItemEventActions {
|
||||||
{
|
|
||||||
MOVE = "Move",
|
MOVE = "Move",
|
||||||
REMOVE = "Remove",
|
REMOVE = "Remove",
|
||||||
SPLIT = "Split",
|
SPLIT = "Split",
|
||||||
@ -24,4 +23,5 @@ export enum ItemEventActions
|
|||||||
REMOVE_BUILD = "RemoveBuild",
|
REMOVE_BUILD = "RemoveBuild",
|
||||||
SAVE_EQUIPMENT_BUILD = "SaveEquipmentBuild",
|
SAVE_EQUIPMENT_BUILD = "SaveEquipmentBuild",
|
||||||
REMOVE_EQUIPMENT_BUILD = "RemoveEquipmentBuild",
|
REMOVE_EQUIPMENT_BUILD = "RemoveEquipmentBuild",
|
||||||
|
REDEEM_PROFILE_REWARD = "RedeemProfileReward"
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { GiftSenderType } from "@spt-aki/models/enums/GiftSenderType";
|
|||||||
import { SeasonalEventType } from "@spt-aki/models/enums/SeasonalEventType";
|
import { SeasonalEventType } from "@spt-aki/models/enums/SeasonalEventType";
|
||||||
import { Traders } from "@spt-aki/models/enums/Traders";
|
import { Traders } from "@spt-aki/models/enums/Traders";
|
||||||
import { IBaseConfig } from "@spt-aki/models/spt/config/IBaseConfig";
|
import { IBaseConfig } from "@spt-aki/models/spt/config/IBaseConfig";
|
||||||
|
import { IProfileChangeEvent } from "../dialog/ISendMessageDetails";
|
||||||
|
|
||||||
export interface IGiftsConfig extends IBaseConfig
|
export interface IGiftsConfig extends IBaseConfig
|
||||||
{
|
{
|
||||||
@ -29,4 +30,6 @@ export interface Gift
|
|||||||
timestampToSend?: number;
|
timestampToSend?: number;
|
||||||
associatedEvent: SeasonalEventType;
|
associatedEvent: SeasonalEventType;
|
||||||
collectionTimeHours: number;
|
collectionTimeHours: number;
|
||||||
|
/** Optional, can be used to change profile settings like level/skills */
|
||||||
|
profileChangeEvents?: IProfileChangeEvent[];
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,14 @@ export interface ISendMessageDetails
|
|||||||
systemData?: ISystemData;
|
systemData?: ISystemData;
|
||||||
/** Optional - Used by ragfair messages */
|
/** Optional - Used by ragfair messages */
|
||||||
ragfairDetails?: MessageContentRagfair;
|
ragfairDetails?: MessageContentRagfair;
|
||||||
/** Optional - Usage not known, unsure of purpose, even dumps dont have it */
|
/** OPTIONAL - allows modification of profile settings via mail */
|
||||||
profileChangeEvents?: any[];
|
profileChangeEvents?: IProfileChangeEvent[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IProfileChangeEvent
|
||||||
|
{
|
||||||
|
_id: string
|
||||||
|
Type: "TraderSalesSum" | "TraderStanding" | "ProfileLevel" | "SkillPoints" | "ExamineAllItems" | "UnlockTrader"
|
||||||
|
value: number
|
||||||
|
entity?: string
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ export class InventoryItemEventRouter extends ItemEventRouterDefinition
|
|||||||
new HandledRoute(ItemEventActions.EDIT_MAP_MARKER, false),
|
new HandledRoute(ItemEventActions.EDIT_MAP_MARKER, false),
|
||||||
new HandledRoute(ItemEventActions.OPEN_RANDOM_LOOT_CONTAINER, false),
|
new HandledRoute(ItemEventActions.OPEN_RANDOM_LOOT_CONTAINER, false),
|
||||||
new HandledRoute(ItemEventActions.HIDEOUT_QTE_EVENT, false),
|
new HandledRoute(ItemEventActions.HIDEOUT_QTE_EVENT, false),
|
||||||
|
new HandledRoute(ItemEventActions.REDEEM_PROFILE_REWARD, false),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +91,8 @@ export class InventoryItemEventRouter extends ItemEventRouterDefinition
|
|||||||
return this.inventoryCallbacks.openRandomLootContainer(pmcData, body, sessionID);
|
return this.inventoryCallbacks.openRandomLootContainer(pmcData, body, sessionID);
|
||||||
case ItemEventActions.HIDEOUT_QTE_EVENT:
|
case ItemEventActions.HIDEOUT_QTE_EVENT:
|
||||||
return this.hideoutCallbacks.handleQTEEvent(pmcData, body, sessionID);
|
return this.hideoutCallbacks.handleQTEEvent(pmcData, body, sessionID);
|
||||||
|
case ItemEventActions.REDEEM_PROFILE_REWARD:
|
||||||
|
return this.inventoryCallbacks.redeemProfileReward(pmcData, body, sessionID);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unhandled event ${url}`);
|
throw new Error(`Unhandled event ${url}`);
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,7 @@ export class GiftService
|
|||||||
playerId,
|
playerId,
|
||||||
giftData.localeTextId,
|
giftData.localeTextId,
|
||||||
giftData.items,
|
giftData.items,
|
||||||
|
giftData.profileChangeEvents,
|
||||||
this.timeUtil.getHoursAsSeconds(giftData.collectionTimeHours),
|
this.timeUtil.getHoursAsSeconds(giftData.collectionTimeHours),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,7 @@ export class MailSendService
|
|||||||
sessionId: string,
|
sessionId: string,
|
||||||
messageLocaleId: string,
|
messageLocaleId: string,
|
||||||
items: Item[] = [],
|
items: Item[] = [],
|
||||||
|
profileChangeEvents = [],
|
||||||
maxStorageTimeSeconds = null,
|
maxStorageTimeSeconds = null,
|
||||||
): void
|
): void
|
||||||
{
|
{
|
||||||
@ -214,6 +215,11 @@ export class MailSendService
|
|||||||
details.itemsMaxStorageLifetimeSeconds = maxStorageTimeSeconds ?? 172800; // 48 hours if no value supplied
|
details.itemsMaxStorageLifetimeSeconds = maxStorageTimeSeconds ?? 172800; // 48 hours if no value supplied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (profileChangeEvents.length > 0)
|
||||||
|
{
|
||||||
|
details.profileChangeEvents = profileChangeEvents;
|
||||||
|
}
|
||||||
|
|
||||||
this.sendMessageToPlayer(details);
|
this.sendMessageToPlayer(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +285,11 @@ export class MailSendService
|
|||||||
// Store reward items inside message and set appropriate flags inside message
|
// Store reward items inside message and set appropriate flags inside message
|
||||||
this.addRewardItemsToMessage(message, itemsToSendToPlayer, messageDetails.itemsMaxStorageLifetimeSeconds);
|
this.addRewardItemsToMessage(message, itemsToSendToPlayer, messageDetails.itemsMaxStorageLifetimeSeconds);
|
||||||
|
|
||||||
|
if (messageDetails.profileChangeEvents)
|
||||||
|
{
|
||||||
|
message.profileChangeEvents = messageDetails.profileChangeEvents;
|
||||||
|
}
|
||||||
|
|
||||||
// Add message to dialog
|
// Add message to dialog
|
||||||
senderDialog.messages.push(message);
|
senderDialog.messages.push(message);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user