patchwork-mapconverter
Version:
Executable wrapper for https://github.com/ChiefOfGxBxL/WC3MapTranslator
204 lines • 18.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ObjectsTranslator = void 0;
const HexBuffer_1 = require("../HexBuffer");
const W3Buffer_1 = require("../W3Buffer");
const ObjectModificationTable_1 = require("../data/ObjectModificationTable");
class ObjectsTranslator {
constructor(type) {
this.type = type;
}
static getInstance(type) {
let instance = this.instances.get(type);
if (instance == null) {
instance = new this(type);
this.instances.set(type, instance);
}
return instance;
}
static jsonToWar(type, info) {
return this.getInstance(type).jsonToWar(info);
}
static warToJson(type, buffer) {
return this.getInstance(type).warToJson(buffer);
}
jsonToWar(json) {
const outBufferToWar = new HexBuffer_1.HexBuffer();
/*
* Header
*/
outBufferToWar.addInt(2); // file version
const generateTableFromJson = (tableType, tableData) => {
if (!tableData) {
outBufferToWar.addInt(0);
return;
}
const data = Object.entries(tableData);
outBufferToWar.addInt(data.length);
data.forEach(([defKey, obj]) => {
// Original and new object ids
if (tableType === ObjectModificationTable_1.TableType.original) {
outBufferToWar.addChars(defKey);
outBufferToWar.addByte(0);
outBufferToWar.addByte(0);
outBufferToWar.addByte(0);
outBufferToWar.addByte(0); // no new Id is assigned
}
else {
// e.g. "h000:hfoo"
outBufferToWar.addChars(defKey.substring(5, 9)); // original id
outBufferToWar.addChars(defKey.substring(0, 4)); // custom id
}
// Number of modifications made to this object
outBufferToWar.addInt(obj?.length || 0);
obj?.forEach((mod) => {
let modType;
// Modification id (e.g. unam = name; reference MetaData lookups)
outBufferToWar.addChars(mod.id);
// Determine what type of field the mod is (int, real, unreal, string)
if (mod.type != null) { // if a type is specified, use it
modType = ObjectsTranslator.varTypes[mod.type];
}
else { // otherwise we try to infer between int/string (note there is no way to detect unreal or float this way, so user must specify those explicitly)
if (typeof mod.value === 'number') {
modType = ObjectsTranslator.varTypes.int;
}
else if (typeof mod.value === 'string') {
modType = ObjectsTranslator.varTypes.string;
}
else {
throw new Error('No type specified and cannot infer type!');
}
}
outBufferToWar.addInt(modType);
// Addl integers
// Required for: doodads, abilities, upgrades
if (this.type === ObjectModificationTable_1.ObjectType.Doodads || this.type === ObjectModificationTable_1.ObjectType.Abilities || this.type === ObjectModificationTable_1.ObjectType.Upgrades) {
// Level or variation
// We need to check if hasOwnProperty because these could be explititly
// set to 0, but JavaScript's truthiness evaluates to false to it was defaulting
outBufferToWar.addInt((mod.level ?? mod.variation) ?? 0); // defaults to 0
outBufferToWar.addInt(mod.column ?? 0); // E.g DataA1 is 1 because of col A; refer to the xyzData.slk files for Data fields
}
// Write mod value
if (modType === ObjectsTranslator.varTypes.int) {
outBufferToWar.addInt(mod.value);
}
else if (modType === ObjectsTranslator.varTypes.real || modType === ObjectsTranslator.varTypes.unreal) {
// Follow-up: check if unreal values are same hex format as real
outBufferToWar.addFloat(mod.value);
}
else if (modType === ObjectsTranslator.varTypes.string) {
// Note that World Editor normally creates a TRIGSTR_000 for these string
// values - WC3MapTranslator just writes the string directly to file
outBufferToWar.addString(mod.value);
}
// End of struct
if (tableType === ObjectModificationTable_1.TableType.original) {
// Original objects are ended with their base id (e.g. hfoo)
outBufferToWar.addChars(defKey);
}
else {
// Custom objects are ended with 0000 bytes
outBufferToWar.addByte(0);
outBufferToWar.addByte(0);
outBufferToWar.addByte(0);
outBufferToWar.addByte(0);
}
});
});
};
generateTableFromJson(ObjectModificationTable_1.TableType.original, json.original);
generateTableFromJson(ObjectModificationTable_1.TableType.custom, json.custom);
return {
errors: [],
buffer: outBufferToWar.getBuffer()
};
}
warToJson(buffer) {
const result = { original: {}, custom: {} };
const outBufferToJSON = new W3Buffer_1.W3Buffer(buffer);
const fileVersion = outBufferToJSON.readInt();
const readModificationTable = (isOriginalTable) => {
const numTableModifications = outBufferToJSON.readInt();
for (let i = 0; i < numTableModifications; i++) {
const objectDefinition = []; // object definition will store one or more modification objects
const originalId = outBufferToJSON.readChars(4);
const customId = outBufferToJSON.readChars(4);
let sets;
if (fileVersion >= 3) {
sets = outBufferToJSON.readInt();
}
else {
sets = 1;
}
for (let j = 0; j < sets; j++) {
if (fileVersion >= 3) {
const setFlag = outBufferToJSON.readInt();
}
const modificationCount = outBufferToJSON.readInt();
for (let k = 0; k < modificationCount; k++) {
const modification = {
id: '',
type: ObjectModificationTable_1.ModificationType.string,
level: 0,
column: 0,
value: {}
};
modification.id = outBufferToJSON.readChars(4);
modification.type = ObjectsTranslator.varTypes[outBufferToJSON.readInt()]; // 'int' | 'real' | 'unreal' | 'string',
if (this.type === ObjectModificationTable_1.ObjectType.Doodads || this.type === ObjectModificationTable_1.ObjectType.Abilities || this.type === ObjectModificationTable_1.ObjectType.Upgrades) {
modification.level = outBufferToJSON.readInt();
modification.column = outBufferToJSON.readInt();
}
if (modification.type === 'int') {
modification.value = outBufferToJSON.readInt();
}
else if (modification.type === 'real' || modification.type === 'unreal') {
modification.value = outBufferToJSON.readFloat();
}
else { // modification.type === 'string'
modification.value = outBufferToJSON.readString();
}
if (isOriginalTable) {
outBufferToJSON.readInt(); // should be 0 for original objects
}
else {
outBufferToJSON.readChars(4); // should be object ID for custom objects
}
objectDefinition.push(modification);
}
}
if (isOriginalTable) {
result.original[originalId] = objectDefinition;
}
else {
result.custom[customId + ':' + originalId] = objectDefinition;
}
}
};
readModificationTable(true);
readModificationTable(false);
return {
errors: [],
json: result
};
}
}
exports.ObjectsTranslator = ObjectsTranslator;
ObjectsTranslator.instances = new Map();
// Expose the ObjectType enum as part of this abstract class
// The enum could be "export"ed , but it wouldn't be accessible
// via `ObjectsTranslator.ObjectType`, which is preferable.
ObjectsTranslator.ObjectType = ObjectModificationTable_1.ObjectType;
ObjectsTranslator.varTypes = {
int: 0,
real: 1,
unreal: 2,
string: 3,
0: 'int',
1: 'real',
2: 'unreal',
3: 'string'
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT2JqZWN0c1RyYW5zbGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2MzbWFwdHJhbnNsYXRvci90cmFuc2xhdG9ycy9PYmplY3RzVHJhbnNsYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw0Q0FBd0M7QUFDeEMsMENBQXNDO0FBR3RDLDZFQUEwSTtBQUUxSSxNQUFhLGlCQUFpQjtJQUs1QixZQUFxQixJQUFnQjtRQUNuQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQTtJQUNsQixDQUFDO0lBRU0sTUFBTSxDQUFDLFdBQVcsQ0FBRSxJQUFnQjtRQUN6QyxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUN2QyxJQUFJLFFBQVEsSUFBSSxJQUFJLEVBQUU7WUFDcEIsUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ3pCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQTtTQUNuQztRQUNELE9BQU8sUUFBUSxDQUFBO0lBQ2pCLENBQUM7SUFFTSxNQUFNLENBQUMsU0FBUyxDQUFFLElBQWdCLEVBQUUsSUFBNkI7UUFDdEUsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUMvQyxDQUFDO0lBRU0sTUFBTSxDQUFDLFNBQVMsQ0FBRSxJQUFnQixFQUFFLE1BQWM7UUFDdkQsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUNqRCxDQUFDO0lBa0JNLFNBQVMsQ0FBRSxJQUE2QjtRQUM3QyxNQUFNLGNBQWMsR0FBRyxJQUFJLHFCQUFTLEVBQUUsQ0FBQTtRQUV0Qzs7ZUFFTztRQUNQLGNBQWMsQ0FBQyxNQUFNLENB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