Feature: Allow PMCs that kill the player to message them a positive/negative message (!81)
Store bots spawned in raid inside cache (`MatchBotDetailsCacheService`) Clear cache after raid Co-authored-by: Dev <dev@noreply.dev.sp-tarkov.com> Reviewed-on: https://dev.sp-tarkov.com/SPT-AKI/Server/pulls/81
This commit is contained in:
parent
8749e3a608
commit
d595e26ee6
@ -11,14 +11,14 @@
|
||||
"appendBroToMessageEndChancePercent": 35
|
||||
},
|
||||
"killer": {
|
||||
"responseChancePercent": 20,
|
||||
"responseChancePercent": 16,
|
||||
"responseTypeWeights": {
|
||||
"positive": 5,
|
||||
"negative": 2,
|
||||
"plead": 2
|
||||
},
|
||||
"stripCapitalisationChancePercent": 20,
|
||||
"allCapsChancePercent": 20,
|
||||
"appendBroToMessageEndChancePercent": 35
|
||||
"allCapsChancePercent": 15,
|
||||
"appendBroToMessageEndChancePercent": 15
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +270,7 @@
|
||||
"pmcresponse-victim_negative_8": "I am malding so hard right now",
|
||||
"pmcresponse-victim_negative_9": "Good job sweatlord",
|
||||
"pmcresponse-victim_negative_10": "I was AFK!!",
|
||||
"pmcresponse-victim_negative_11": "Reported you for cheating :)",
|
||||
"pmcresponse-victim_negative_11": "Reported you for cheating",
|
||||
"pmcresponse-victim_negative_12": "You only got me because of lag",
|
||||
"pmcresponse-victim_negative_13": "I need to go play SPT instead to get away from the hackers like you",
|
||||
"pmcresponse-victim_negative_14": "If I knew the map better I'd have won",
|
||||
@ -284,7 +284,7 @@
|
||||
"pmcresponse-victim_negative_22": "Wow hiding in the corner like a rat, amazing",
|
||||
"pmcresponse-victim_negative_23": "I hope you stub your toe on a piece of furniture",
|
||||
"pmcresponse-victim_negative_24": "Wow why did you kill me, i'm telling my mom",
|
||||
"pmcresponse-victim_negative_25": "Reported (:",
|
||||
"pmcresponse-victim_negative_25": "Reported",
|
||||
"pmcresponse-victim_negative_26": "My mom thinks I should have won that fight",
|
||||
"pmcresponse-victim_negative_27": "Wow, killing a noob like me, you must feel so proud",
|
||||
"pmcresponse-victim_negative_28": "I bet you play SPT because you cheat on live",
|
||||
@ -341,6 +341,53 @@
|
||||
"pmcresponse-suffix_16": "amigo",
|
||||
"pmcresponse-suffix_17": "bud",
|
||||
"pmcresponse-suffix_18": "guy",
|
||||
"pmcresponse-suffix_18": "m8",
|
||||
"pmcresponse-suffix_19": ":)",
|
||||
"pmcresponse-suffix_20": "(:",
|
||||
"pmcresponse-suffix_21": ":))))))",
|
||||
"pmcresponse-killer_positive_1": "Good fight",
|
||||
"pmcresponse-killer_positive_2": "You fought well",
|
||||
"pmcresponse-killer_positive_3": "I will stash your gear",
|
||||
"pmcresponse-killer_positive_4": "You nearly got me, great fight",
|
||||
"pmcresponse-killer_positive_5": "Well played, nearly had me",
|
||||
"pmcresponse-killer_positive_6": "You almost had me",
|
||||
"pmcresponse-killer_positive_7": "If I didnt have the drop on you I would be dead",
|
||||
"pmcresponse-killer_positive_8": "Good fite",
|
||||
"pmcresponse-killer_positive_9": "Well fought",
|
||||
"pmcresponse-killer_positive_10": "Whatever you were shooting destroyed my armor, good fight",
|
||||
"pmcresponse-killer_positive_11": "Nothing personal, gotta get these Jaeger quests complete",
|
||||
"pmcresponse-killer_positive_12": "You had me very worried for a bit during that fight",
|
||||
"pmcresponse-killer_positive_13": "Impressive skills",
|
||||
"pmcresponse-killer_positive_14": "Respect, you gave me a good fight",
|
||||
"pmcresponse-killer_positive_15": "Clean fight, respect",
|
||||
"pmcresponse-killer_positive_16": "That was a real cat and mouse fight, awesome",
|
||||
"pmcresponse-killer_negative_1": "ty 4 the free loot",
|
||||
"pmcresponse-killer_negative_2": "Thanks for the new kit",
|
||||
"pmcresponse-killer_negative_3": "No wonder you died, your gun is trash",
|
||||
"pmcresponse-killer_negative_4": "Why are you wearing that armor lmao",
|
||||
"pmcresponse-killer_negative_5": "lmaoooo",
|
||||
"pmcresponse-killer_negative_6": "Dont worry your gear will be on the flea soon",
|
||||
"pmcresponse-killer_negative_7": "No wonder you play SPT with your aim",
|
||||
"pmcresponse-killer_negative_8": "It is what it is",
|
||||
"pmcresponse-killer_negative_9": "Thanks for looting for me",
|
||||
"pmcresponse-killer_negative_10": "At least put up a fight next time",
|
||||
"pmcresponse-killer_negative_11": "I think you need some more practice",
|
||||
"pmcresponse-killer_negative_12": "Try to put up a challenge next time",
|
||||
"pmcresponse-killer_negative_13": "Rip little timmy",
|
||||
"pmcresponse-killer_negative_14": "Another dirty little rat taken care of",
|
||||
"pmcresponse-killer_negative_15": "That was embarassing to watch",
|
||||
"pmcresponse-killer_negative_15": "I expected at least a little resistance, oh well",
|
||||
"pmcresponse-killer_negative_16": "I hope you didnt insure that gear as you wont be getting it back",
|
||||
"pmcresponse-killer_negative_17": "I have a youtube series on how to get better at tarkov if you are interested",
|
||||
"pmcresponse-killer_negative_18": "Another dogtag for my collection",
|
||||
"pmcresponse-killer_plead_1": "I was trying to extract a quest item and you were in my path",
|
||||
"pmcresponse-killer_plead_2": "I was looting barrel caches and you were in the way, sorry",
|
||||
"pmcresponse-killer_plead_3": "I need PMC kills, I am sure you understand",
|
||||
"pmcresponse-killer_plead_4": "See you next time",
|
||||
"pmcresponse-killer_plead_5": "You didnt even have a salewa on you, I am never getting this quest completed",
|
||||
"pmcresponse-killer_plead_6": "I spent ages looking for your body and someone already looted it",
|
||||
"pmcresponse-killer_plead_7": "I finally find your body and all you have is garbage",
|
||||
"pmcresponse-killer_plead_8": "I swear you killed me before",
|
||||
"launcher-profile_standard": "Same as live, basic stash size (10x28), 500,000 roubles",
|
||||
"launcher-profile_leftbehind": "Same as Standard plus; larger stash size (10x38), extra equipment/items, 500 dollars",
|
||||
"launcher-profile_preparetoescape": "Same as Left Behind plus; larger stash size (10x48), extra equipment/items, higher starting reputation with traders, 250 euros",
|
||||
|
@ -21,6 +21,7 @@ import { ConfigServer } from "../servers/ConfigServer";
|
||||
import { DatabaseServer } from "../servers/DatabaseServer";
|
||||
import { BotGenerationCacheService } from "../services/BotGenerationCacheService";
|
||||
import { LocalisationService } from "../services/LocalisationService";
|
||||
import { MatchBotDetailsCacheService } from "../services/MatchBotDetailsCacheService";
|
||||
import { JsonUtil } from "../utils/JsonUtil";
|
||||
|
||||
@injectable()
|
||||
@ -36,6 +37,7 @@ export class BotController
|
||||
@inject("BotHelper") protected botHelper: BotHelper,
|
||||
@inject("BotDifficultyHelper") protected botDifficultyHelper: BotDifficultyHelper,
|
||||
@inject("BotGenerationCacheService") protected botGenerationCacheService: BotGenerationCacheService,
|
||||
@inject("MatchBotDetailsCacheService") protected matchBotDetailsCacheService: MatchBotDetailsCacheService,
|
||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||
@ -173,7 +175,15 @@ export class BotController
|
||||
}
|
||||
}
|
||||
// Get bot from cache, add to return array
|
||||
botsToReturn.push(this.botGenerationCacheService.getBot(cacheKey));
|
||||
const botToReturn = this.botGenerationCacheService.getBot(cacheKey);
|
||||
|
||||
if (info.conditions.length === 1)
|
||||
{
|
||||
// Cache bot when we're returning 1 bot, this indicated the bot is being requested to be spawned
|
||||
this.matchBotDetailsCacheService.cacheBot(botToReturn);
|
||||
}
|
||||
|
||||
botsToReturn.push(botToReturn);
|
||||
}
|
||||
|
||||
return botsToReturn;
|
||||
|
@ -29,6 +29,7 @@ import { DatabaseServer } from "../servers/DatabaseServer";
|
||||
import { SaveServer } from "../servers/SaveServer";
|
||||
import { InsuranceService } from "../services/InsuranceService";
|
||||
import { LocaleService } from "../services/LocaleService";
|
||||
import { MatchBotDetailsCacheService } from "../services/MatchBotDetailsCacheService";
|
||||
import { PmcChatResponseService } from "../services/PmcChatResponseService";
|
||||
import { JsonUtil } from "../utils/JsonUtil";
|
||||
import { TimeUtil } from "../utils/TimeUtil";
|
||||
@ -50,6 +51,7 @@ export class InraidController
|
||||
@inject("DatabaseServer") protected databaseServer: DatabaseServer,
|
||||
@inject("LocaleService") protected localeService: LocaleService,
|
||||
@inject("PmcChatResponseService") protected pmcChatResponseService: PmcChatResponseService,
|
||||
@inject("MatchBotDetailsCacheService") protected matchBotDetailsCacheService: MatchBotDetailsCacheService,
|
||||
@inject("QuestHelper") protected questHelper: QuestHelper,
|
||||
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
||||
@ -145,7 +147,9 @@ export class InraidController
|
||||
|
||||
if (isDead)
|
||||
{
|
||||
//TODO - find way to get killer name //this.pmcChatResponseService.sendKillerResponse(sessionID, pmcData);
|
||||
this.pmcChatResponseService.sendKillerResponse(sessionID, pmcData, offraidData.profile.Stats.Aggressor);
|
||||
this.matchBotDetailsCacheService.clearCache();
|
||||
|
||||
pmcData = this.performPostRaidActionsWhenDead(offraidData, pmcData, insuranceEnabled, preRaidGear, sessionID);
|
||||
}
|
||||
|
||||
|
@ -200,6 +200,7 @@ import { ItemBaseClassService } from "../services/ItemBaseClassService";
|
||||
import { ItemFilterService } from "../services/ItemFilterService";
|
||||
import { LocaleService } from "../services/LocaleService";
|
||||
import { LocalisationService } from "../services/LocalisationService";
|
||||
import { MatchBotDetailsCacheService } from "../services/MatchBotDetailsCacheService";
|
||||
import { MatchLocationService } from "../services/MatchLocationService";
|
||||
import { CustomItemService } from "../services/mod/CustomItemService";
|
||||
import { DynamicRouterModService } from "../services/mod/dynamicRouter/DynamicRouterModService";
|
||||
@ -604,6 +605,7 @@ export class Container
|
||||
depContainer.register<BotEquipmentModPoolService>("BotEquipmentModPoolService", BotEquipmentModPoolService, { lifecycle: Lifecycle.Singleton });
|
||||
depContainer.register<BotWeaponModLimitService>("BotWeaponModLimitService", BotWeaponModLimitService, { lifecycle: Lifecycle.Singleton });
|
||||
depContainer.register<SeasonalEventService>("SeasonalEventService", SeasonalEventService, { lifecycle: Lifecycle.Singleton });
|
||||
depContainer.register<MatchBotDetailsCacheService>("MatchBotDetailsCacheService", MatchBotDetailsCacheService, { lifecycle: Lifecycle.Singleton });
|
||||
depContainer.register<TraderPurchasePersisterService>("TraderPurchasePersisterService", TraderPurchasePersisterService);
|
||||
depContainer.register<PmcChatResponseService>("PmcChatResponseService", PmcChatResponseService);
|
||||
}
|
||||
|
51
project/src/services/MatchBotDetailsCacheService.ts
Normal file
51
project/src/services/MatchBotDetailsCacheService.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { IBotBase } from "../models/eft/common/tables/IBotBase";
|
||||
import { ILogger } from "../models/spt/utils/ILogger";
|
||||
|
||||
/** Cache bots in a dictionary, keyed by the bots name, keying by name isnt idea as its not unique but this is used by the post-raid system which doesnt have any bot ids, only name */
|
||||
|
||||
@injectable()
|
||||
export class MatchBotDetailsCacheService
|
||||
{
|
||||
protected botDetailsCache: Record<string, IBotBase> = {};
|
||||
|
||||
constructor(
|
||||
@inject("WinstonLogger") protected logger: ILogger
|
||||
)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Store a bot in the cache, keyed by its name
|
||||
* @param botToCache Bot details to cache
|
||||
*/
|
||||
public cacheBot(botToCache: IBotBase): void
|
||||
{
|
||||
this.botDetailsCache[botToCache.Info.Nickname.trim()] = botToCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the cache of all bot details
|
||||
*/
|
||||
public clearCache(): void
|
||||
{
|
||||
this.botDetailsCache = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a bot in the cache by its name
|
||||
* @param botName Name of bot to find
|
||||
* @returns Bot details
|
||||
*/
|
||||
public getBotByName(botName: string): IBotBase
|
||||
{
|
||||
const botInCache = this.botDetailsCache[botName];
|
||||
if (!botInCache)
|
||||
{
|
||||
this.logger.warning(`Bot not found in cache with name ${botName}`);
|
||||
}
|
||||
|
||||
return botInCache;
|
||||
}
|
||||
|
||||
}
|
@ -3,15 +3,17 @@ import { inject, injectable } from "tsyringe";
|
||||
import { NotificationSendHelper } from "../helpers/NotificationSendHelper";
|
||||
import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper";
|
||||
import { IPmcData } from "../models/eft/common/IPmcData";
|
||||
import { Victim } from "../models/eft/common/tables/IBotBase";
|
||||
import { Aggressor, Victim } from "../models/eft/common/tables/IBotBase";
|
||||
import { IUserDialogInfo } from "../models/eft/profile/IAkiProfile";
|
||||
import { ConfigTypes } from "../models/enums/ConfigTypes";
|
||||
import { MemberCategory } from "../models/enums/MemberCategory";
|
||||
import { MessageType } from "../models/enums/MessageType";
|
||||
import { IPmcChatResponse } from "../models/spt/config/IPmChatResponse";
|
||||
import { ILogger } from "../models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "../servers/ConfigServer";
|
||||
import { RandomUtil } from "../utils/RandomUtil";
|
||||
import { LocalisationService } from "./LocalisationService";
|
||||
import { MatchBotDetailsCacheService } from "./MatchBotDetailsCacheService";
|
||||
|
||||
@injectable()
|
||||
export class PmcChatResponseService
|
||||
@ -19,8 +21,10 @@ export class PmcChatResponseService
|
||||
protected pmcResponsesConfig: IPmcChatResponse;
|
||||
|
||||
constructor(
|
||||
@inject("WinstonLogger") protected logger: ILogger,
|
||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
||||
@inject("NotificationSendHelper") protected notificationSendHelper: NotificationSendHelper,
|
||||
@inject("MatchBotDetailsCacheService") protected matchBotDetailsCacheService: MatchBotDetailsCacheService,
|
||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
||||
@inject("ConfigServer") protected configServer: ConfigServer
|
||||
@ -56,16 +60,43 @@ export class PmcChatResponseService
|
||||
* @param pmcData Players profile
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public sendKillerResponse(sessionId: string, pmcData: IPmcData): void
|
||||
public sendKillerResponse(sessionId: string, pmcData: IPmcData, killer: Aggressor): void
|
||||
{
|
||||
const killer: IUserDialogInfo = {
|
||||
_id: "",
|
||||
info: undefined
|
||||
if (!this.randomUtil.getChance100(this.pmcResponsesConfig.killer.responseChancePercent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// find bot by name in cache
|
||||
const killerDetailsInCache = this.matchBotDetailsCacheService.getBotByName(killer.Name.trim());
|
||||
if (!killerDetailsInCache)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If kill was not a PMC, skip
|
||||
if (!["sptUsec", "sptBear"].includes(killerDetailsInCache.Info.Settings.Role))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const killerDetails: IUserDialogInfo = {
|
||||
_id: killerDetailsInCache._id,
|
||||
info: {
|
||||
Nickname: killerDetailsInCache.Info.Nickname,
|
||||
Side: killerDetailsInCache.Info.Side,
|
||||
Level: killerDetailsInCache.Info.Level,
|
||||
MemberCategory: killerDetailsInCache.Info.MemberCategory
|
||||
}
|
||||
};
|
||||
|
||||
const message = this.chooseMessage(false);
|
||||
if (!message)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.notificationSendHelper.sendMessageToPlayer(sessionId, killer, message, MessageType.USER_MESSAGE);
|
||||
this.notificationSendHelper.sendMessageToPlayer(sessionId, killerDetails, message, MessageType.USER_MESSAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,6 +111,12 @@ export class PmcChatResponseService
|
||||
|
||||
// Get all locale keys
|
||||
const possibleResponseLocaleKeys = this.getResponseLocaleKeys(responseType, isVictim);
|
||||
if (possibleResponseLocaleKeys.length === 0)
|
||||
{
|
||||
this.logger.warning(`No pmc response keys found for type: ${responseType}`);
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Choose random response from above list and request it from localisation service
|
||||
let responseText = this.localisationService.getText(this.randomUtil.getArrayValue(possibleResponseLocaleKeys));
|
||||
|
Loading…
Reference in New Issue
Block a user