Merge branch '310-dev' of https://dev.sp-tarkov.com/SPT/Server into 310-dev

This commit is contained in:
Dev 2024-07-06 09:21:14 +01:00
commit 61da90f33d
6 changed files with 87 additions and 35 deletions

View File

@ -36,7 +36,7 @@ export class LocationCallbacks
return this.httpResponse.getBody(this.locationController.get(sessionID, info)); return this.httpResponse.getBody(this.locationController.get(sessionID, info));
} }
/** Handle client/location/getAirdropLoot */ /** Handle client/airdrop/loot */
public getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): any public getAirdropLoot(url: string, info: IEmptyRequestData, sessionID: string): any
{ {
return this.httpResponse.getBody(this.locationController.getAirdropLoot()); return this.httpResponse.getBody(this.locationController.getAirdropLoot());

View File

@ -11,7 +11,7 @@ import { IAirdropLootResult } from "@spt/models/eft/location/IAirdropLootResult"
import { IGetLocationRequestData } from "@spt/models/eft/location/IGetLocationRequestData"; import { IGetLocationRequestData } from "@spt/models/eft/location/IGetLocationRequestData";
import { AirdropTypeEnum } from "@spt/models/enums/AirdropType"; import { AirdropTypeEnum } from "@spt/models/enums/AirdropType";
import { ConfigTypes } from "@spt/models/enums/ConfigTypes"; import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
import { IAirdropConfig } from "@spt/models/spt/config/IAirdropConfig"; import { AirdropLoot, IAirdropConfig } from "@spt/models/spt/config/IAirdropConfig";
import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig"; import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig";
import { IRaidChanges } from "@spt/models/spt/location/IRaidChanges"; import { IRaidChanges } from "@spt/models/spt/location/IRaidChanges";
import { ILocations } from "@spt/models/spt/server/ILocations"; import { ILocations } from "@spt/models/spt/server/ILocations";
@ -171,15 +171,14 @@ export class LocationController
* Generates it randomly based on config/airdrop.json values * Generates it randomly based on config/airdrop.json values
* @returns Array of LootItem objects * @returns Array of LootItem objects
*/ */
public getAirdropLoot(): IAirdropLootResult public getAirdropLoot(): any // TODO: need to fix
{ {
const airdropType = this.chooseAirdropType(); const airdropType = this.chooseAirdropType();
this.logger.debug(`Chose ${airdropType} for airdrop loot`); this.logger.debug(`Chose ${airdropType} for airdrop loot`);
const airdropConfig = this.getAirdropLootConfigByType(airdropType); const airdropConfig = this.getAirdropLootConfigByType(airdropType);
return { dropType: airdropType, loot: this.lootGenerator.createRandomLoot(airdropConfig) }; return { icon: airdropType, container: this.lootGenerator.createRandomLoot(airdropConfig) };
} }
/** /**
@ -200,16 +199,17 @@ export class LocationController
*/ */
protected getAirdropLootConfigByType(airdropType: AirdropTypeEnum): LootRequest protected getAirdropLootConfigByType(airdropType: AirdropTypeEnum): LootRequest
{ {
let lootSettingsByType = this.airdropConfig.loot[airdropType]; let lootSettingsByType: AirdropLoot = this.airdropConfig.loot[airdropType];
if (!lootSettingsByType) if (!lootSettingsByType)
{ {
this.logger.error( this.logger.error(
this.localisationService.getText("location-unable_to_find_airdrop_drop_config_of_type", airdropType), this.localisationService.getText("location-unable_to_find_airdrop_drop_config_of_type", airdropType),
); );
lootSettingsByType = this.airdropConfig.loot[AirdropTypeEnum.MIXED]; lootSettingsByType = this.airdropConfig.loot[AirdropTypeEnum.COMMON];
} }
return { return {
airdropLoot: airdropType,
weaponPresetCount: lootSettingsByType.weaponPresetCount, weaponPresetCount: lootSettingsByType.weaponPresetCount,
armorPresetCount: lootSettingsByType.armorPresetCount, armorPresetCount: lootSettingsByType.armorPresetCount,
itemCount: lootSettingsByType.itemCount, itemCount: lootSettingsByType.itemCount,

View File

@ -228,13 +228,8 @@ export class MatchController
const parentId = this.hashUtil.generate(); const parentId = this.hashUtil.generate();
for (const item of loot) for (const item of loot)
{ {
mailableLoot.push({ item.parentId = parentId;
_id: item.id, mailableLoot.push(item);
_tpl: item.tpl,
slotId: "main",
parentId: parentId,
upd: { StackObjectsCount: item.stackCount, SpawnedInSession: true },
});
} }
// Send message from fence giving player reward generated above // Send message from fence giving player reward generated above

View File

@ -17,6 +17,8 @@ import { LocalisationService } from "@spt/services/LocalisationService";
import { RagfairLinkedItemService } from "@spt/services/RagfairLinkedItemService"; import { RagfairLinkedItemService } from "@spt/services/RagfairLinkedItemService";
import { HashUtil } from "@spt/utils/HashUtil"; import { HashUtil } from "@spt/utils/HashUtil";
import { RandomUtil } from "@spt/utils/RandomUtil"; import { RandomUtil } from "@spt/utils/RandomUtil";
import { AirdropTypeEnum } from "@spt/models/enums/AirdropType";
import { ItemTpl } from "@spt/models/enums/ItemTpl";
type ItemLimit = { current: number, max: number }; type ItemLimit = { current: number, max: number };
@ -43,9 +45,41 @@ export class LootGenerator
* @param options parameters to adjust how loot is generated * @param options parameters to adjust how loot is generated
* @returns An array of loot items * @returns An array of loot items
*/ */
public createRandomLoot(options: LootRequest): LootItem[] public createRandomLoot(options: LootRequest): Item[]
{ {
const result: LootItem[] = []; const result: Item[] = [];
let airdropContainerParentID = "";
if (options.airdropLoot)
{
airdropContainerParentID = this.hashUtil.generate();
let airdropContainer = {
_id: airdropContainerParentID,
_tpl: "",
upd: {
SpawnedInSession: true,
StackObjectsCount: 1
}
}
switch (options.airdropLoot) {
case AirdropTypeEnum.MEDICAL:
airdropContainer._tpl = ItemTpl.LOOTCONTAINER_AIRDROP_MEDICAL_CRATE
break;
case AirdropTypeEnum.SUPPLY:
airdropContainer._tpl = ItemTpl.LOOTCONTAINER_AIRDROP_SUPPLY_CRATE
break;
case AirdropTypeEnum.WEAPON:
airdropContainer._tpl = ItemTpl.LOOTCONTAINER_AIRDROP_WEAPON_CRATE
break;
case AirdropTypeEnum.COMMON:
default:
airdropContainer._tpl = ItemTpl.LOOTCONTAINER_AIRDROP_COMMON_SUPPLY_CRATE
break;
}
result.push(airdropContainer);
}
const itemTypeCounts = this.initItemLimitCounter(options.itemLimits); const itemTypeCounts = this.initItemLimitCounter(options.itemLimits);
@ -86,10 +120,12 @@ export class LootGenerator
// Choose one at random + add to results array // Choose one at random + add to results array
const chosenSealedContainer = this.randomUtil.getArrayValue(sealedWeaponContainerPool); const chosenSealedContainer = this.randomUtil.getArrayValue(sealedWeaponContainerPool);
result.push({ result.push({
id: this.hashUtil.generate(), _id: this.hashUtil.generate(),
tpl: chosenSealedContainer._id, _tpl: chosenSealedContainer._id,
isPreset: false, upd: {
stackCount: 1, StackObjectsCount: 1,
SpawnedInSession: true
}
}); });
} }
} }
@ -185,6 +221,19 @@ export class LootGenerator
} }
} }
for (const item of result) {
if (item._id == airdropContainerParentID)
{
continue;
}
if (!item.parentId)
{
item.parentId = airdropContainerParentID;
item.slotId = "main"
}
}
return result; return result;
} }
@ -242,7 +291,7 @@ export class LootGenerator
items: [string, ITemplateItem][], items: [string, ITemplateItem][],
itemTypeCounts: Record<string, { current: number, max: number }>, itemTypeCounts: Record<string, { current: number, max: number }>,
options: LootRequest, options: LootRequest,
result: LootItem[], result: Item[],
): boolean ): boolean
{ {
const randomItem = this.randomUtil.getArrayValue(items)[1]; const randomItem = this.randomUtil.getArrayValue(items)[1];
@ -259,20 +308,22 @@ export class LootGenerator
return false; return false;
} }
const newLootItem: LootItem = { const newLootItem: Item = {
id: this.hashUtil.generate(), _id: this.hashUtil.generate(),
tpl: randomItem._id, _tpl: randomItem._id,
isPreset: false, upd: {
stackCount: 1, StackObjectsCount: 1,
SpawnedInSession: true
}
}; };
// Special case - handle items that need a stackcount > 1 // Special case - handle items that need a stackcount > 1
if (randomItem._props.StackMaxSize > 1) if (randomItem._props.StackMaxSize > 1)
{ {
newLootItem.stackCount = this.getRandomisedStackCount(randomItem, options); newLootItem.upd.StackObjectsCount = this.getRandomisedStackCount(randomItem, options);
} }
newLootItem.tpl = randomItem._id; newLootItem._tpl = randomItem._id;
result.push(newLootItem); result.push(newLootItem);
if (itemLimitCount) if (itemLimitCount)
@ -317,7 +368,7 @@ export class LootGenerator
presetPool: IPreset[], presetPool: IPreset[],
itemTypeCounts: Record<string, { current: number, max: number }>, itemTypeCounts: Record<string, { current: number, max: number }>,
itemBlacklist: string[], itemBlacklist: string[],
result: LootItem[], result: Item[],
): boolean ): boolean
{ {
// Choose random preset and get details from item db using encyclopedia value (encyclopedia === tplId) // Choose random preset and get details from item db using encyclopedia value (encyclopedia === tplId)
@ -367,8 +418,12 @@ export class LootGenerator
return false; return false;
} }
const presetAndMods: Item[] = this.itemHelper.replaceIDs(chosenPreset._items);
this.itemHelper.remapRootItemId(presetAndMods);
// Add chosen preset tpl to result array // Add chosen preset tpl to result array
result.push({ tpl: chosenPreset._items[0]._tpl, isPreset: true, stackCount: 1 }); presetAndMods.forEach(item => {
result.push(item)
});
if (itemLimitCount) if (itemLimitCount)
{ {

View File

@ -1,7 +1,7 @@
export enum AirdropTypeEnum export enum AirdropTypeEnum
{ {
MIXED = "mixed", COMMON = "common",
WEAPONARMOR = "weaponarmor", SUPPLY = "supply",
FOODMEDICAL = "foodmedical", MEDICAL = "medical",
BARTER = "barter", WEAPON = "weapon"
} }

View File

@ -1,7 +1,9 @@
import { MinMax } from "@spt/models/common/MinMax"; import { MinMax } from "@spt/models/common/MinMax";
import { AirdropTypeEnum } from "@spt/models/enums/AirdropType";
export interface LootRequest export interface LootRequest
{ {
airdropLoot?: AirdropTypeEnum
weaponPresetCount: MinMax weaponPresetCount: MinMax
armorPresetCount: MinMax armorPresetCount: MinMax
itemCount: MinMax itemCount: MinMax