Kiwami-2-Model-Replacer/index.js
Lordmau5 05a3dfb44f Move files to subfolders
Also output the modified files into an `output` directory.
2020-05-21 15:19:26 +02:00

126 lines
3.2 KiB
JavaScript

// https://docs.google.com/spreadsheets/d/1-3E_t-KsFIw2rpM0hZIKOdNdGm5-GnQjvJb3cysOawE/edit#gid=1532331536
const fs = require("fs");
const _ = require("underscore");
const { allTypes, shuffledModels } = require("./models");
if (!fs.existsSync("config.js")) {
fs.writeFileSync("config.js", fs.readFileSync("config.default.js"));
}
if (!fs.existsSync("output")) {
fs.mkdirSync("output");
}
const {
mode,
sameType,
singleModel,
randomModels,
excludedModels,
blacklist,
} = require("./config");
// Check if a model is excluded from modification
function isModelExcluded(fb, sb) {
for (let i = 0; i < excludedModels.length; i++) {
const model = excludedModels[i];
if (
(model[0] === fb && model[1] === -1) ||
(model[0] === -1 && model[1] === sb)
) {
return true;
} else if (model[0] === fb && model[1] === sb) {
return true;
}
}
return false;
}
// Check if a model is blacklisted
function isModelBlacklisted(fb, sb) {
for (let i = 0; i < blacklist.models.length; i++) {
const model = blacklist.models[i];
if (
(model[0] === fb && model[1] === -1) ||
(model[0] === -1 && model[1] === sb)
) {
return !blacklist.isWhitelist;
} else if (model[0] === fb && model[1] === sb) {
return !blacklist.isWhitelist;
}
}
return blacklist.isWhitelist;
}
function replaceModels(doReplace = true) {
const data = fs.readFileSync("original/character_character_data.bin.orig");
if (doReplace) {
// Magic
if (mode === 0) {
for (let i = 0x16194; i < 0x18ea8; i += 4) {
if (isModelExcluded(data[i], data[i + 1])) continue;
data[i] = singleModel[0];
data[i + 1] = singleModel[1];
}
} else if (mode === 1) {
for (let i = 0x16194; i < 0x18ea8; i += 4) {
if (isModelExcluded(data[i], data[i + 1])) continue;
const model = randomModels[_.random(randomModels.length - 1)];
data[i] = model[0];
data[i + 1] = model[1];
}
} else if (mode === 2) {
for (let i = 0x16194; i < 0x18ea8; i += 4) {
const id = data[i];
const type = data[i + 1];
if (isModelExcluded(id, type)) continue;
const modelType = sameType
? type
: allTypes[_.random(allTypes.length - 1)];
const models = shuffledModels[modelType];
let modelId = models[_.random(models.length - 1)];
while (isModelBlacklisted(modelId, type)) {
modelId = models[_.random(models.length - 1)];
}
data[i] = modelId;
data[i + 1] = type;
}
}
// -----
}
fs.writeFileSync("output/character_character_data.bin", data);
}
// TODO: Create a reverse-lookup map of some sort to fit the proper model height with other models?
// Only does scaling, so not that needed apparently...
function replaceHeights(doReplace = true) {
const data = fs.readFileSync("original/character_model_model_data.bin.orig");
if (doReplace) {
// Magic
for (let i = 0x23220; i < 0x24910; i += 2) {
data[i] = 0xb9;
data[i + 1] = 0x00;
}
// -----
}
fs.writeFileSync("output/character_model_model_data.bin", data);
}
replaceModels();
replaceHeights(false);