sc4
Version:
A command line utility for automating SimCity 4 modding tasks & modifying savegames
74 lines (73 loc) • 2.46 kB
JavaScript
export default class TractInfo {
// Tracts always start with an offset of 0x40 (64). Might be related to the
// fact that the item index is actually a quadtree where objects are only
// stored at the 4x4 level. Note sure if we'll abstract this away, we should
// probably remain as close as possible to the raw data structures.
minX = 0x40;
minZ = 0x40;
maxX = 0x40;
maxZ = 0x40;
// Tracts are always 4x4 tiles, which means the *exponent* is given as 2
// (2² = 4). This is likely constant in all game objects, but for some
// reason it is still stored in the savegame structures.
xTractSize = 0x0002;
zTractSize = 0x0002;
// ## constructor(min, max)
constructor(min = [0x40, 0x40], max = [0x40, 0x40]) {
[this.minX, this.minZ] = min;
[this.maxX, this.maxZ] = max;
}
// ## get min()
get min() {
return { x: this.minX, z: this.minZ };
}
get max() {
return { x: this.maxX, z: this.maxZ };
}
// ## parse(rs)
parse(rs) {
this.minX = rs.byte();
this.minZ = rs.byte();
this.maxX = rs.byte();
this.maxZ = rs.byte();
this.xTractSize = rs.word();
this.zTractSize = rs.word();
return this;
}
// ## write(ws)
write(ws) {
ws.byte(this.minX);
ws.byte(this.minZ);
ws.byte(this.maxX);
ws.byte(this.maxZ);
ws.word(this.xTractSize);
ws.word(this.zTractSize);
return this;
}
update(from) {
if ('bbox' in from) {
return this.update(from.bbox);
}
const xSize = 16 * 2 ** this.xTractSize;
const zSize = 16 * 2 ** this.zTractSize;
if (isBbox(from)) {
this.minX = 0x40 + Math.floor(from.minX / xSize);
this.minZ = 0x40 + Math.floor(from.minZ / zSize);
this.maxX = 0x40 + Math.floor(from.maxX / xSize);
this.maxZ = 0x40 + Math.floor(from.maxZ / zSize);
}
else {
this.minX = this.maxX = 0x40 + Math.floor(from[0] / xSize);
this.minZ = this.maxZ = 0x40 + Math.floor(from[2] / zSize);
}
return this;
}
// ## [Symbol.for('nodejs.util.inspect.custom')]
[Symbol.for('nodejs.util.inspect.custom')]() {
let { minX, minZ, maxX, maxZ } = this;
return { minX, minZ, maxX, maxZ };
}
}
function isBbox(object) {
return Array.isArray(object[0]);
}