IntegerLimit 5aecff8b4d
Allow for QB Translations of Normal and Expert Quest Books (#432)
[FEATURE]

/* Description: */
Also moves all nodejs stuff into `tools` package.

Also adds a basic `CONTRIBUTING.md` file. 

Superseeds https://github.com/Nomi-CEu/Nomi-CEu/pull/431, which was closed as the branch needed to be renamed, due to the last two items on this list.

TODO:
- [x] Make it only run on master repo.
- [x] Remove qb-lang-revamp branch from the events
- [x] Allow workflow to run on all branches starting with test_buildscript?

/* Commits: */

* Buildscript Changes

* Make Contributing Docs a .md file

* updateqb.yml v1

* Test QB change

* Add lang file to commit file list

* Another Test Change

* Test with only lang path, + `./` at beginning of path

* Test QB change

* updateqb.yml v3

* Test QB Change

* Add some debug settings

* Remove debug, branch input. Switch to auto-commit action

* Make activate: branches prefix `test_buildscript`, commit author GHA bot

* Add branch prefix note into CONTRIBUTING.md

* Make workflow only run if on master repo
2023-09-17 22:44:48 +10:00

165 lines
5.2 KiB
TypeScript

import fs from "fs";
import gulp from "gulp";
import upath from "upath";
import { overridesFolder, configFolder, configOverridesFolder } from "../../globals";
import buildConfig from "../../buildConfig";
import { Quest, QuestBook, QuestLines as QuestLine } from "../../types/bqQuestBook";
const sharedQBDefaults = upath.join(buildConfig.buildSourceDirectory, configFolder, "betterquesting");
const sharedConfigOverrides = upath.join(buildConfig.buildSourceDirectory, configOverridesFolder);
const langFileLocation = "resources/questbook/lang";
function escapeString(string: string) {
return string.replace(/%/g, "%%").replace(/\n/g, "%n");
}
function transformKeyPairs(
database: { [key: string]: Quest } | { [key: string]: QuestLine },
mode: string,
namespace: string,
lines: string[],
) {
Object.keys(database).forEach((key) => {
const storeKey = key.replace(/:10/g, "");
const item = database[key];
const properties = item["properties:10"]["betterquesting:10"];
if (properties["name:8"] !== "Gap") {
const titleKey = `nomifactory.quest.${mode}.${namespace}.${storeKey}.title`;
const descKey = `nomifactory.quest.${mode}.${namespace}.${storeKey}.desc`;
// Push lang file lines.
lines.push(
`#${namespace} ${storeKey} of mode ${mode}`,
`${titleKey}=${escapeString(properties["name:8"])}`,
`${descKey}=${escapeString(properties["desc:8"])}`,
"",
);
properties["name:8"] = titleKey;
properties["desc:8"] = descKey;
} else {
properties["name:8"] = "";
properties["desc:8"] = "";
}
});
}
/**
* Trimming all that results in almost half the size of the original JSON file.
*
* Interesting, huh?
*/
const uselessProps = {
"simultaneous:1": 0,
"ismain:1": 0,
"repeat_relative:1": 1,
"globalshare:1": 0,
"repeattime:3": -1,
"issilent:1": 0,
"snd_complete:8": "minecraft:entity.player.levelup",
"snd_update:8": "minecraft:entity.player.levelup",
"tasklogic:8": "AND",
"questlogic:8": "AND",
"visibility:8": "NORMAL",
"partysinglereward:1": 0,
"lockedprogress:1": 0,
"OreDict:8": "",
"Damage:2": 0,
"Count:3": 0,
"autoclaim:1": 0,
"autoConsume:1": 0,
"consume:1": 0,
"groupDetect:1": 0,
"ignoreNBT:1": 0,
"index:3": 0,
"partialMatch:1": 1,
"ignoresview:1": 0,
};
function stripUselessMetadata(object: unknown) {
Object.keys(object).forEach((propName) => {
const prop = object[propName];
if (prop === uselessProps[propName]) {
return delete object[propName];
}
if (typeof prop === "object") {
if (Array.isArray(prop) && prop.length === 0) {
return delete object[propName];
}
stripUselessMetadata(prop);
if (Object.keys(prop).length === 0) {
return delete object[propName];
}
}
});
}
/**
* Extract lang entries from the quest book and transform the database.
*/
export async function transformQuestBook(): Promise<void> {
// Source Quest Book File Locations
const questPathNormalDev = upath.join(sharedQBDefaults, "saved_quests", "NormalQuestsDev.json");
const questPathExpertDev = upath.join(sharedQBDefaults, "saved_quests", "ExpertQuestsDev.json");
// Quest Book Objects
const questBookNormal: QuestBook = JSON.parse((await fs.promises.readFile(questPathNormalDev)).toString());
const questBookExpert: QuestBook = JSON.parse((await fs.promises.readFile(questPathExpertDev)).toString());
// Quest Book Paths
const questPathNormalDefault = upath.join(sharedQBDefaults, "DefaultQuests.json");
const questPathNormalOverride = upath.join(sharedConfigOverrides, "normal", "betterquesting", "DefaultQuests.json");
const questPathExpertDefault = upath.join(sharedQBDefaults, "saved_quests", "ExpertQuests.json");
const questPathExpertOverride = upath.join(sharedConfigOverrides, "expert", "betterquesting", "DefaultQuests.json");
// Quest Lang Location
const questLangLocation = upath.join(buildConfig.buildSourceDirectory, overridesFolder, langFileLocation);
// Traverse through the quest book and rewrite titles/descriptions.
// Extract title/desc pairs into a lang file.
const lines: string[] = [];
lines.push("Normal Quest Lang Entries:",
"",
);
// Normal Mode Quest lines.
transformKeyPairs(questBookNormal["questLines:9"], "normal", "line", lines);
// Normal Mode Quests themselves.
transformKeyPairs(questBookNormal["questDatabase:9"], "normal", "db", lines);
lines.push("Expert Quest Lang Entries:",
"",
);
// Expert Mode Quest lines.
transformKeyPairs(questBookExpert["questLines:9"], "expert", "line", lines);
// Expert Mode Quests themselves.
transformKeyPairs(questBookExpert["questDatabase:9"], "expert", "db", lines);
// Write lang file.
await fs.promises.mkdir(questLangLocation, { recursive: true });
await fs.promises.writeFile(upath.join(questLangLocation, "en_us.lang"), lines.join("\n"));
// Strip useless metadata.
stripUselessMetadata(questBookNormal);
stripUselessMetadata(questBookNormal);
// Write QB files.
fs.promises.writeFile(questPathNormalDefault, JSON.stringify(questBookNormal, null, 2));
fs.promises.writeFile(questPathNormalOverride, JSON.stringify(questBookNormal, null, 2));
fs.promises.writeFile(questPathExpertDefault, JSON.stringify(questBookExpert, null, 2));
fs.promises.writeFile(questPathExpertOverride, JSON.stringify(questBookExpert, null, 2));
}