mirror of
https://github.com/sp-tarkov/server.git
synced 2025-02-13 09:50:43 -05:00
Added new command to hydrate customisationStorage data
This commit is contained in:
parent
19fae7ead2
commit
7681d07ab9
@ -32,7 +32,8 @@
|
|||||||
"gen:types": "tsc -p tsconfig.types.json",
|
"gen:types": "tsc -p tsconfig.types.json",
|
||||||
"gen:docs": "typedoc --options ./typedoc.json --entryPointStrategy expand ./src",
|
"gen:docs": "typedoc --options ./typedoc.json --entryPointStrategy expand ./src",
|
||||||
"gen:items": "tsx ./src/tools/ItemTplGenerator/ItemTplGeneratorProgram.ts",
|
"gen:items": "tsx ./src/tools/ItemTplGenerator/ItemTplGeneratorProgram.ts",
|
||||||
"gen:productionquests": "tsx ./src/tools/ProductionQuestsGen/ProductionQuestsGenProgram.ts"
|
"gen:productionquests": "tsx ./src/tools/ProductionQuestsGen/ProductionQuestsGenProgram.ts",
|
||||||
|
"gen:customisationstorage": "tsx ./src/tools/HideoutCustomisation/HideoutCustomisationProgram.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"atomically": "~1.7",
|
"atomically": "~1.7",
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* Hydrate customisationStorage.json with data scraped together from other sources
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* - Run this script using npm: `npm run gen:customisationstorage`
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import { writeFileSync } from "node:fs";
|
||||||
|
import { dirname, join, resolve } from "node:path";
|
||||||
|
import { OnLoad } from "@spt/di/OnLoad";
|
||||||
|
import { IQuestReward } from "@spt/models/eft/common/tables/IQuest";
|
||||||
|
import type { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||||
|
import { DatabaseServer } from "@spt/servers/DatabaseServer";
|
||||||
|
import { inject, injectAll, injectable } from "tsyringe";
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export class HideoutCustomisationGen {
|
||||||
|
private questCustomisationReward: Record<string, IQuestReward[]> = {};
|
||||||
|
private achievementCustomisationReward: Record<string, IQuestReward[]> = {};
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@injectAll("OnLoad") protected onLoadComponents: OnLoad[],
|
||||||
|
@inject("DatabaseServer") protected databaseServer: DatabaseServer,
|
||||||
|
@inject("PrimaryLogger") protected logger: ILogger,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async run(): Promise<void> {
|
||||||
|
// Load all of the onload components, this gives us access to most of SPTs injections
|
||||||
|
for (const onLoad of this.onLoadComponents) {
|
||||||
|
await onLoad.onLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build up our dataset
|
||||||
|
this.buildQuestCustomisationList();
|
||||||
|
this.buildAchievementRewardCustomisationList();
|
||||||
|
this.updateCustomisationStorage();
|
||||||
|
|
||||||
|
// Dump the new data to disk
|
||||||
|
const currentDir = dirname(__filename);
|
||||||
|
const projectDir = resolve(currentDir, "..", "..", "..");
|
||||||
|
const templatesDir = join(projectDir, "assets", "database", "templates");
|
||||||
|
const customisationStorageOutPath = join(templatesDir, "customisationStorage.json");
|
||||||
|
writeFileSync(
|
||||||
|
customisationStorageOutPath,
|
||||||
|
JSON.stringify(this.databaseServer.getTables().templates?.customisationStorage, null, 2),
|
||||||
|
"utf-8",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateCustomisationStorage(): void {
|
||||||
|
const customisationStoageDb = this.databaseServer.getTables().templates?.customisationStorage;
|
||||||
|
if (!customisationStoageDb) {
|
||||||
|
// no customisation storage in templates, nothing to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const globalCustomisationDb of this.databaseServer.getTables().hideout?.customisation.globals) {
|
||||||
|
// Look for customisations that have a quest unlock condition
|
||||||
|
const questOrAchievementRequirement = globalCustomisationDb.conditions.find((condition) =>
|
||||||
|
["Quest", "Block"].includes(condition.conditionType),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!questOrAchievementRequirement) {
|
||||||
|
// Customisation doesnt have a requirement, skip
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customisationStoageDb.some((custStorageItem) => custStorageItem.id === globalCustomisationDb.id)) {
|
||||||
|
// Exists already in output destination file, skip
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const matchingQuest = this.questCustomisationReward[questOrAchievementRequirement.target];
|
||||||
|
const matchingAchievement = this.achievementCustomisationReward[questOrAchievementRequirement.target];
|
||||||
|
|
||||||
|
let source = null;
|
||||||
|
if (matchingQuest) {
|
||||||
|
source = "unlockedInGame";
|
||||||
|
} else if (matchingAchievement) {
|
||||||
|
source = "achievement";
|
||||||
|
}
|
||||||
|
if (!source) {
|
||||||
|
this.logger.error(
|
||||||
|
`Found customisation to add but unable to establish source. Id: ${globalCustomisationDb.id} type: ${globalCustomisationDb.type}`,
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.success(
|
||||||
|
`Adding Id: ${globalCustomisationDb.id} Source: ${source} type: ${globalCustomisationDb.type}`,
|
||||||
|
);
|
||||||
|
customisationStoageDb.push({
|
||||||
|
id: globalCustomisationDb.id,
|
||||||
|
source: source,
|
||||||
|
type: globalCustomisationDb.type,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a dictionary of all quests with a `CustomizationDirect` reward
|
||||||
|
private buildQuestCustomisationList(): void {
|
||||||
|
for (const quest of Object.values(this.databaseServer.getTables().templates.quests)) {
|
||||||
|
const allRewards: IQuestReward[] = Object.values(quest.rewards);
|
||||||
|
const customisationDirectRewards = allRewards.filter((reward) => reward.type === "CustomizationDirect");
|
||||||
|
for (const directReward of customisationDirectRewards) {
|
||||||
|
if (!this.questCustomisationReward[quest._id]) {
|
||||||
|
this.questCustomisationReward[quest._id] = [];
|
||||||
|
}
|
||||||
|
this.questCustomisationReward[quest._id].push(directReward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a dictionary of all achievements with a `CustomizationDirect` reward
|
||||||
|
private buildAchievementRewardCustomisationList(): void {
|
||||||
|
for (const achievement of Object.values(this.databaseServer.getTables().templates?.achievements)) {
|
||||||
|
const allRewards: IQuestReward[] = Object.values(achievement.rewards);
|
||||||
|
const customisationDirectRewards = allRewards.filter((reward) => reward.type === "CustomizationDirect");
|
||||||
|
for (const directReward of customisationDirectRewards) {
|
||||||
|
if (!this.achievementCustomisationReward[achievement.id]) {
|
||||||
|
this.achievementCustomisationReward[achievement.id] = [];
|
||||||
|
}
|
||||||
|
this.achievementCustomisationReward[achievement.id].push(directReward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
import "reflect-metadata";
|
||||||
|
import "source-map-support/register";
|
||||||
|
|
||||||
|
import { ErrorHandler } from "@spt/ErrorHandler";
|
||||||
|
import { Container } from "@spt/di/Container";
|
||||||
|
import { HideoutCustomisationGen } from "@spt/tools/HideoutCustomisation/HideoutCustomisationGen";
|
||||||
|
import { Lifecycle, container } from "tsyringe";
|
||||||
|
|
||||||
|
export class HideoutCustomisationProgram {
|
||||||
|
constructor() {
|
||||||
|
// set window properties
|
||||||
|
process.stdout.setEncoding("utf8");
|
||||||
|
process.title = "SPT hideoutCustomisationProgram";
|
||||||
|
}
|
||||||
|
|
||||||
|
public async start(): Promise<void> {
|
||||||
|
try {
|
||||||
|
Container.registerTypes(container);
|
||||||
|
const childContainer = container.createChildContainer();
|
||||||
|
|
||||||
|
Container.registerListTypes(childContainer);
|
||||||
|
container.register<HideoutCustomisationGen>("HideoutCustomisationGen", HideoutCustomisationGen, {
|
||||||
|
lifecycle: Lifecycle.Singleton,
|
||||||
|
});
|
||||||
|
|
||||||
|
Container.registerListTypes(childContainer);
|
||||||
|
Container.registerPostLoadTypes(container, childContainer);
|
||||||
|
|
||||||
|
childContainer.resolve<HideoutCustomisationGen>("HideoutCustomisationGen").run();
|
||||||
|
} catch (err: unknown) {
|
||||||
|
new ErrorHandler().handleCriticalError(err instanceof Error ? err : new Error(String(err)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kill the process, something holds it open so we need to manually kill it
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const program = new HideoutCustomisationProgram();
|
||||||
|
program.start();
|
Loading…
x
Reference in New Issue
Block a user