mirror of
https://github.com/sp-tarkov/server.git
synced 2025-02-13 09:50:43 -05:00
Implement Pickup
quests for scav
It seems like these are scav-only
This commit is contained in:
parent
e10b62a5b1
commit
650a3173c8
@ -11,7 +11,8 @@
|
|||||||
"scav": {
|
"scav": {
|
||||||
"elimination": "62825ef60e88d037dc1eb428",
|
"elimination": "62825ef60e88d037dc1eb428",
|
||||||
"completion": "628f588ebb558574b2260fe5",
|
"completion": "628f588ebb558574b2260fe5",
|
||||||
"exploration": "62825ef60e88d037dc1eb42c"
|
"exploration": "62825ef60e88d037dc1eb42c",
|
||||||
|
"pickup": "628f588ebb558574b2260fe5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"showNonSeasonalEventQuests": false,
|
"showNonSeasonalEventQuests": false,
|
||||||
@ -1297,8 +1298,10 @@
|
|||||||
"name": "Daily_Savage",
|
"name": "Daily_Savage",
|
||||||
"side": "Scav",
|
"side": "Scav",
|
||||||
"types": [
|
"types": [
|
||||||
|
"Exploration",
|
||||||
"Elimination",
|
"Elimination",
|
||||||
"Completion"
|
"Completion",
|
||||||
|
"Pickup"
|
||||||
],
|
],
|
||||||
"resetTime": 86400,
|
"resetTime": 86400,
|
||||||
"numQuests": 1,
|
"numQuests": 1,
|
||||||
@ -1324,7 +1327,7 @@
|
|||||||
},
|
},
|
||||||
"traderWhitelist": [{
|
"traderWhitelist": [{
|
||||||
"traderId": "579dc571d53a0658a154fbec",
|
"traderId": "579dc571d53a0658a154fbec",
|
||||||
"questTypes": ["Completion", "Exploration", "Elimination"]
|
"questTypes": ["Completion", "Exploration", "Elimination", "Pickup"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"questConfig": {
|
"questConfig": {
|
||||||
@ -1341,6 +1344,23 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Pickup": {
|
||||||
|
"ItemTypeToFetchWithMaxCount": [
|
||||||
|
{"itemType": "5b47574386f77428ca22b335", "minPickupCount": 2, "maxPickupCount": 4},
|
||||||
|
{"itemType": "5b47574386f77428ca22b336", "minPickupCount": 2, "maxPickupCount": 4},
|
||||||
|
{"itemType": "5b47574386f77428ca22b2ee", "minPickupCount": 2, "maxPickupCount": 3},
|
||||||
|
{"itemType": "5b47574386f77428ca22b2ef", "minPickupCount": 1, "maxPickupCount": 2},
|
||||||
|
{"itemType": "5b47574386f77428ca22b33a", "minPickupCount": 1, "maxPickupCount": 2},
|
||||||
|
{"itemType": "5b5f701386f774093f2ecf0f", "minPickupCount": 1, "maxPickupCount": 2},
|
||||||
|
{"itemType": "5b5f754a86f774094242f19b", "minPickupCount": 1, "maxPickupCount": 3},
|
||||||
|
{"itemType": "5b5f75c686f774094242f19f", "minPickupCount": 1, "maxPickupCount": 2},
|
||||||
|
{"itemType": "5b5f792486f77447ed5636b3", "minPickupCount": 1, "maxPickupCount": 2},
|
||||||
|
{"itemType": "5b5f73ab86f774094242f195", "minPickupCount": 1, "maxPickupCount": 2},
|
||||||
|
{}
|
||||||
|
],
|
||||||
|
"ItemTypesToFetch": ["5b47574386f77428ca22b335", "5b47574386f77428ca22b336", "5b47574386f77428ca22b2ee"],
|
||||||
|
"maxItemFetchCount": 3
|
||||||
|
},
|
||||||
"Completion": {
|
"Completion": {
|
||||||
"minRequestedAmount": 1,
|
"minRequestedAmount": 1,
|
||||||
"maxRequestedAmount": 5,
|
"maxRequestedAmount": 5,
|
||||||
|
@ -182,7 +182,111 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"changeStandingCost": 0
|
"changeStandingCost": 0
|
||||||
}
|
},
|
||||||
|
"Pickup": {
|
||||||
|
"_id": "64cfb3818db9f48b3f0b0a759",
|
||||||
|
"traderId": "579dc571d53a0658a154fbec",
|
||||||
|
"location": "any",
|
||||||
|
"image": "/files/quest/icon/62bd61b1b818ff064405b827.jpg",
|
||||||
|
"type": "PickUp",
|
||||||
|
"isKey": false,
|
||||||
|
"restartable": false,
|
||||||
|
"instantComplete": false,
|
||||||
|
"secretQuest": false,
|
||||||
|
"canShowNotificationsInGame": true,
|
||||||
|
"rewards": {
|
||||||
|
"Started": [],
|
||||||
|
"Success": [],
|
||||||
|
"Fail": []
|
||||||
|
},
|
||||||
|
"conditions": {
|
||||||
|
"AvailableForStart": [],
|
||||||
|
"AvailableForFinish": [{
|
||||||
|
"_props": {
|
||||||
|
"id": "64cfb3818db9f48b3f0b0a6f",
|
||||||
|
"parentId": "",
|
||||||
|
"dynamicLocale": false,
|
||||||
|
"index": 0,
|
||||||
|
"visibilityConditions": [],
|
||||||
|
"globalQuestCounterId": null,
|
||||||
|
"target": ["5b47574386f77428ca22b336"],
|
||||||
|
"value": 7,
|
||||||
|
"minDurability": 0,
|
||||||
|
"maxDurability": 100,
|
||||||
|
"dogtagLevel": 0,
|
||||||
|
"onlyFoundInRaid": false,
|
||||||
|
"isEncoded": false,
|
||||||
|
"countInRaid": true
|
||||||
|
},
|
||||||
|
"_parent": "FindItem",
|
||||||
|
"dynamicLocale": false
|
||||||
|
}, {
|
||||||
|
"_props": {
|
||||||
|
"id": "64cfb3818db9f48b3f0b0a74",
|
||||||
|
"parentId": "",
|
||||||
|
"dynamicLocale": true,
|
||||||
|
"index": 0,
|
||||||
|
"visibilityConditions": [],
|
||||||
|
"globalQuestCounterId": null,
|
||||||
|
"value": 1,
|
||||||
|
"type": "PickUp",
|
||||||
|
"completeInSeconds": 0,
|
||||||
|
"oneSessionOnly": true,
|
||||||
|
"doNotResetIfCounterCompleted": false,
|
||||||
|
"counter": {
|
||||||
|
"id": "64cfb3818db9f48b3f0b0a73",
|
||||||
|
"conditions": [{
|
||||||
|
"_props": {
|
||||||
|
"target": ["any"],
|
||||||
|
"id": "64cfb3818db9f48b3f0b0a70",
|
||||||
|
"dynamicLocale": true
|
||||||
|
},
|
||||||
|
"_parent": "Location"
|
||||||
|
}, {
|
||||||
|
"_props": {
|
||||||
|
"status": ["Survived"],
|
||||||
|
"id": "64cfb3818db9f48b3f0b0a71",
|
||||||
|
"dynamicLocale": true
|
||||||
|
},
|
||||||
|
"_parent": "ExitStatus"
|
||||||
|
}, {
|
||||||
|
"_props": {
|
||||||
|
"equipmentInclusive": [["5b47574386f77428ca22b336"]],
|
||||||
|
"IncludeNotEquippedItems": true,
|
||||||
|
"id": "64cfb3818db9f48b3f0b0a72",
|
||||||
|
"dynamicLocale": true
|
||||||
|
},
|
||||||
|
"_parent": "Equipment"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"_parent": "CounterCreator",
|
||||||
|
"dynamicLocale": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Fail": []
|
||||||
|
},
|
||||||
|
"side": "Scav",
|
||||||
|
"questStatus": {},
|
||||||
|
"name": "{templateId} name {traderId}",
|
||||||
|
"note": "{templateId} note {traderId}",
|
||||||
|
"description": "{templateId} description {traderId} 0",
|
||||||
|
"successMessageText": "{templateId} successMessageText {traderId} 0",
|
||||||
|
"failMessageText": "{templateId} failMessageText {traderId} 0",
|
||||||
|
"startedMessageText": "{templateId} startedMessageText {traderId} 0",
|
||||||
|
"changeQuestMessageText": "{templateId} changeQuestMessageText {traderId} 0",
|
||||||
|
"acceptPlayerMessage": "{templateId} acceptPlayerMessage {traderId}",
|
||||||
|
"declinePlayerMessage": "{templateId} declinePlayerMessage {traderId}",
|
||||||
|
"completePlayerMessage": "{templateId} completePlayerMessage {traderId}",
|
||||||
|
"templateId": "{templateId}",
|
||||||
|
"changeCost": [{
|
||||||
|
"templateId": "5449016a4bdc2d6f028b456f",
|
||||||
|
"count": 12000
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"changeStandingCost": 0
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"rewards": {
|
"rewards": {
|
||||||
"itemsBlacklist": [
|
"itemsBlacklist": [
|
||||||
|
@ -264,8 +264,13 @@ export class RepeatableQuestController
|
|||||||
if (location !== ELocationName.ANY)
|
if (location !== ELocationName.ANY)
|
||||||
{
|
{
|
||||||
questPool.pool.Exploration.locations[location] = repeatableConfig.locations[location];
|
questPool.pool.Exploration.locations[location] = repeatableConfig.locations[location];
|
||||||
|
questPool.pool.Pickup.locations[location] = repeatableConfig.locations[location];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add "any" to pickup quest pool
|
||||||
|
questPool.pool.Pickup.locations["any"] = ["any"];
|
||||||
|
|
||||||
const eliminationConfig = this.repeatableQuestHelper.getEliminationConfigByPmcLevel(pmcLevel, repeatableConfig);
|
const eliminationConfig = this.repeatableQuestHelper.getEliminationConfigByPmcLevel(pmcLevel, repeatableConfig);
|
||||||
const targetsConfig = this.repeatableQuestHelper.probabilityObjectArray(eliminationConfig.targets);
|
const targetsConfig = this.repeatableQuestHelper.probabilityObjectArray(eliminationConfig.targets);
|
||||||
for (const probabilityObject of targetsConfig)
|
for (const probabilityObject of targetsConfig)
|
||||||
@ -299,6 +304,9 @@ export class RepeatableQuestController
|
|||||||
},
|
},
|
||||||
Elimination: {
|
Elimination: {
|
||||||
targets: {}
|
targets: {}
|
||||||
|
},
|
||||||
|
Pickup: {
|
||||||
|
locations: {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -13,8 +13,10 @@ import {
|
|||||||
ICompletionAvailableFor,
|
ICompletionAvailableFor,
|
||||||
IElimination,
|
IElimination,
|
||||||
IEliminationCondition,
|
IEliminationCondition,
|
||||||
|
IEquipmentConditionProps,
|
||||||
IExploration,
|
IExploration,
|
||||||
IExplorationCondition, IKillConditionProps,
|
IExplorationCondition, IKillConditionProps,
|
||||||
|
IPickup,
|
||||||
IRepeatableQuest, IReward, IRewards
|
IRepeatableQuest, IReward, IRewards
|
||||||
} from "../models/eft/common/tables/IRepeatableQuests";
|
} from "../models/eft/common/tables/IRepeatableQuests";
|
||||||
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
|
import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem";
|
||||||
@ -104,6 +106,8 @@ export class RepeatableQuestGenerator
|
|||||||
return this.generateCompletionQuest(pmcLevel, traderId, repeatableConfig);
|
return this.generateCompletionQuest(pmcLevel, traderId, repeatableConfig);
|
||||||
case "Exploration":
|
case "Exploration":
|
||||||
return this.generateExplorationQuest(pmcLevel, traderId, questTypePool, repeatableConfig);
|
return this.generateExplorationQuest(pmcLevel, traderId, questTypePool, repeatableConfig);
|
||||||
|
case "Pickup":
|
||||||
|
return this.generatePickupQuest(pmcLevel, traderId, questTypePool, repeatableConfig);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown mission type ${questType}. Should never be here!`);
|
throw new Error(`Unknown mission type ${questType}. Should never be here!`);
|
||||||
}
|
}
|
||||||
@ -304,7 +308,7 @@ export class RepeatableQuestGenerator
|
|||||||
// crazy maximum difficulty will lead to a higher difficulty reward gain factor than 1
|
// crazy maximum difficulty will lead to a higher difficulty reward gain factor than 1
|
||||||
const difficulty = this.mathUtil.mapToRange(curDifficulty, minDifficulty, maxDifficulty, 0.5, 2);
|
const difficulty = this.mathUtil.mapToRange(curDifficulty, minDifficulty, maxDifficulty, 0.5, 2);
|
||||||
|
|
||||||
const quest = this.generateRepeatableTemplate("Elimination", traderId,repeatableConfig.side) as IElimination;
|
const quest = this.generateRepeatableTemplate("Elimination", traderId, repeatableConfig.side) as IElimination;
|
||||||
|
|
||||||
// ASSUMPTION: All fence quests are for scavs
|
// ASSUMPTION: All fence quests are for scavs
|
||||||
if (traderId === Traders.FENCE)
|
if (traderId === Traders.FENCE)
|
||||||
@ -312,15 +316,16 @@ export class RepeatableQuestGenerator
|
|||||||
quest.side = "Scav";
|
quest.side = "Scav";
|
||||||
}
|
}
|
||||||
|
|
||||||
quest.conditions.AvailableForFinish[0]._props.counter.id = this.objectId.generate();
|
const availableForFinishCondition = quest.conditions.AvailableForFinish[0];
|
||||||
quest.conditions.AvailableForFinish[0]._props.counter.conditions = [];
|
availableForFinishCondition._props.counter.id = this.objectId.generate();
|
||||||
|
availableForFinishCondition._props.counter.conditions = [];
|
||||||
if (locationKey !== "any")
|
if (locationKey !== "any")
|
||||||
{
|
{
|
||||||
quest.conditions.AvailableForFinish[0]._props.counter.conditions.push(this.generateEliminationLocation(locationsConfig[locationKey], allowedWeapon, allowedWeaponsCategory));
|
availableForFinishCondition._props.counter.conditions.push(this.generateEliminationLocation(locationsConfig[locationKey], allowedWeapon, allowedWeaponsCategory));
|
||||||
}
|
}
|
||||||
quest.conditions.AvailableForFinish[0]._props.counter.conditions.push(this.generateEliminationCondition(targetKey, bodyPartsToClient, distance, allowedWeapon, allowedWeaponsCategory));
|
availableForFinishCondition._props.counter.conditions.push(this.generateEliminationCondition(targetKey, bodyPartsToClient, distance, allowedWeapon, allowedWeaponsCategory));
|
||||||
quest.conditions.AvailableForFinish[0]._props.value = kills;
|
availableForFinishCondition._props.value = kills;
|
||||||
quest.conditions.AvailableForFinish[0]._props.id = this.objectId.generate();
|
availableForFinishCondition._props.id = this.objectId.generate();
|
||||||
quest.location = this.getQuestLocationByMapId(locationKey);
|
quest.location = this.getQuestLocationByMapId(locationKey);
|
||||||
|
|
||||||
quest.rewards = this.generateReward(pmcLevel, Math.min(difficulty, 1), traderId, repeatableConfig);
|
quest.rewards = this.generateReward(pmcLevel, Math.min(difficulty, 1), traderId, repeatableConfig);
|
||||||
@ -660,6 +665,40 @@ export class RepeatableQuestGenerator
|
|||||||
return quest;
|
return quest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected generatePickupQuest(
|
||||||
|
pmcLevel: number,
|
||||||
|
traderId: string,
|
||||||
|
questTypePool: IQuestTypePool,
|
||||||
|
repeatableConfig: IRepeatableQuestConfig
|
||||||
|
): IPickup
|
||||||
|
{
|
||||||
|
const pickupConfig = repeatableConfig.questConfig.Pickup;
|
||||||
|
|
||||||
|
const quest = this.generateRepeatableTemplate("Pickup", traderId, repeatableConfig.side) as IPickup;
|
||||||
|
|
||||||
|
const itemTypeToFetchWithCount = this.randomUtil.getArrayValue(pickupConfig.ItemTypeToFetchWithMaxCount);
|
||||||
|
const itemCountToFetch = this.randomUtil.randInt(itemTypeToFetchWithCount.minPickupCount, itemTypeToFetchWithCount.maxPickupCount + 1);
|
||||||
|
// Choose location - doesnt seem to work for anything other than 'any'
|
||||||
|
//const locationKey: string = this.randomUtil.drawRandomFromDict(questTypePool.pool.Pickup.locations)[0];
|
||||||
|
//const locationTarget = questTypePool.pool.Pickup.locations[locationKey];
|
||||||
|
|
||||||
|
const findCondition = quest.conditions.AvailableForFinish.find(x => x._parent === "FindItem");
|
||||||
|
findCondition._props.target = [itemTypeToFetchWithCount.itemType];
|
||||||
|
findCondition._props.value = itemCountToFetch;
|
||||||
|
|
||||||
|
const counterCreatorCondition = quest.conditions.AvailableForFinish.find(x => x._parent === "CounterCreator");
|
||||||
|
//const locationCondition = counterCreatorCondition._props.counter.conditions.find(x => x._parent === "Location");
|
||||||
|
//(locationCondition._props as ILocationConditionProps).target = [...locationTarget];
|
||||||
|
|
||||||
|
const equipmentCondition = counterCreatorCondition._props.counter.conditions.find(x => x._parent === "Equipment");
|
||||||
|
(equipmentCondition._props as IEquipmentConditionProps).equipmentInclusive = [[itemTypeToFetchWithCount.itemType]];
|
||||||
|
|
||||||
|
// Add rewards
|
||||||
|
quest.rewards = this.generateReward(pmcLevel, 1, traderId, repeatableConfig);
|
||||||
|
|
||||||
|
return quest;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a location into an quest code can read (e.g. factory4_day into 55f2d3fd4bdc2d5f408b4567)
|
* Convert a location into an quest code can read (e.g. factory4_day into 55f2d3fd4bdc2d5f408b4567)
|
||||||
* @param locationKey e.g factory4_day
|
* @param locationKey e.g factory4_day
|
||||||
|
@ -119,7 +119,7 @@ export interface IAvailableForPropsCounter extends IAvailableForProps
|
|||||||
type: string
|
type: string
|
||||||
oneSessionOnly: boolean
|
oneSessionOnly: boolean
|
||||||
doNotResetIfCounterCompleted: boolean
|
doNotResetIfCounterCompleted: boolean
|
||||||
counter: ICounter
|
counter?: ICounter
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICounter
|
export interface ICounter
|
||||||
@ -204,6 +204,38 @@ export interface IExplorationCondition extends ICondition
|
|||||||
_props: ILocationConditionProps | IExitStatusConditionProps | IExitNameConditionProps
|
_props: ILocationConditionProps | IExitStatusConditionProps | IExitNameConditionProps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pickup
|
||||||
|
export interface IPickup extends IRepeatableQuest
|
||||||
|
{
|
||||||
|
conditions: IPickupConditions
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPickupConditions extends IConditions
|
||||||
|
{
|
||||||
|
AvailableForFinish: IPickupAvailableFor[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPickupAvailableFor extends IAvailableFor
|
||||||
|
{
|
||||||
|
_props: IPickupAvailableForProps
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPickupAvailableForProps extends IAvailableForPropsCounter
|
||||||
|
{
|
||||||
|
target: string[]
|
||||||
|
counter?: IPickupCounter
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPickupCounter extends ICounter
|
||||||
|
{
|
||||||
|
conditions: IPickupCondition[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPickupCondition extends ICondition
|
||||||
|
{
|
||||||
|
_props: IEquipmentConditionProps | ILocationConditionProps | IExitStatusConditionProps
|
||||||
|
}
|
||||||
|
|
||||||
// Completion
|
// Completion
|
||||||
export interface ICompletion extends IRepeatableQuest
|
export interface ICompletion extends IRepeatableQuest
|
||||||
{
|
{
|
||||||
@ -238,6 +270,12 @@ export interface ILocationConditionProps extends IConditionProps
|
|||||||
weaponCategories?: string[]
|
weaponCategories?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IEquipmentConditionProps extends IConditionProps
|
||||||
|
{
|
||||||
|
equipmentInclusive: [string[]]
|
||||||
|
IncludeNotEquippedItems: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export interface IKillConditionProps extends IConditionProps
|
export interface IKillConditionProps extends IConditionProps
|
||||||
{
|
{
|
||||||
target: string
|
target: string
|
||||||
|
@ -79,6 +79,7 @@ export interface IRepeatableQuestTypesConfig
|
|||||||
{
|
{
|
||||||
Exploration: IExploration
|
Exploration: IExploration
|
||||||
Completion: ICompletion
|
Completion: ICompletion
|
||||||
|
Pickup: IPickup;
|
||||||
Elimination: IEliminationConfig[]
|
Elimination: IEliminationConfig[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +104,18 @@ export interface ICompletion
|
|||||||
useWhitelist: boolean
|
useWhitelist: boolean
|
||||||
useBlacklist: boolean
|
useBlacklist: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IPickup
|
||||||
|
{
|
||||||
|
ItemTypeToFetchWithMaxCount: IPickupTypeWithMaxCount[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPickupTypeWithMaxCount
|
||||||
|
{
|
||||||
|
itemType: string
|
||||||
|
maxPickupCount: number
|
||||||
|
minPickupCount: number
|
||||||
|
}
|
||||||
|
|
||||||
export interface IEliminationConfig
|
export interface IEliminationConfig
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@ export interface IQuestPool
|
|||||||
{
|
{
|
||||||
Exploration: IExplorationPool
|
Exploration: IExplorationPool
|
||||||
Elimination: IEliminationPool
|
Elimination: IEliminationPool
|
||||||
|
Pickup: IExplorationPool
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IExplorationPool
|
export interface IExplorationPool
|
||||||
|
Loading…
x
Reference in New Issue
Block a user