sc4
Version:
A command line utility for automating SimCity 4 modding tasks & modifying savegames
156 lines (155 loc) • 4.72 kB
JavaScript
// # network-bridge-occupant.ts
import FileType from './file-types.js';
import { kFileType, kFileTypeArray } from './symbols.js';
import Unknown from './unknown.js';
import TractInfo from './tract-info.js';
import Vector3 from './vector-3.js';
import Vertex from './vertex.js';
import Box3 from './box-3.js';
import WriteBuffer from './write-buffer.js';
import TGI from './tgi.js';
// # NetworkBridgeOccupant
// A class that is used for the individual parts of bridges. Apparently the
// structure is exactly the same as the prebuilt network file, which makes sense.
export default class NetworkBridgeOccupant {
static [kFileType] = FileType.NetworkBridgeOccupant;
static [kFileTypeArray] = true;
crc = 0x00000000;
mem = 0x00000000;
version = '4.8.4';
appearance = 0x00000005;
tract = new TractInfo();
sgprops = [];
tgi = new TGI();
matrix3 = null;
position = new Vector3();
vertices = [
new Vertex(),
new Vertex(),
new Vertex(),
new Vertex(),
];
modelId = 0x00000000;
wealthTexture = 0x00;
baseTexture = 0x00000000;
orientation = 0x00;
crossings = [];
walls = [];
bbox = new Box3();
constructionStates = 0x00000000;
pathId = 0x00000000;
demolishingCosts = 0n;
pillar = null;
u = new Unknown()
.dword(0xc772bf98)
.bytes([0, 0])
.repeat(3, u => u.dword(0x00000000))
.repeat(3, u => u.float(0.0))
.bytes([0, 0, 0, 0, 0]);
// # parse(rs)
parse(rs) {
this.u = new Unknown();
const unknown = this.u.reader(rs);
rs.size();
this.crc = rs.dword();
this.mem = rs.dword();
this.version = rs.version(3);
this.appearance = rs.dword();
unknown.dword(0xc772bf98);
this.tract = rs.tract();
this.sgprops = rs.sgprops();
this.tgi = rs.gti();
let hasMatrix = rs.byte() === 0x05;
this.matrix3 = hasMatrix ? rs.matrix3() : null;
this.position = rs.vector3();
this.vertices = [
rs.vertex(),
rs.vertex(),
rs.vertex(),
rs.vertex(),
];
this.modelId = rs.dword();
this.wealthTexture = rs.byte();
this.baseTexture = rs.dword();
this.orientation = rs.byte();
unknown.bytes(2);
this.crossings = rs.crossings();
this.walls = rs.array(() => {
let texture = rs.dword();
let vertex = rs.vertex();
return { texture, vertex };
});
this.bbox = rs.bbox({ range: true });
this.constructionStates = rs.dword();
this.pathId = rs.dword();
unknown.repeat(3, u => u.dword(0x00000000));
this.demolishingCosts = rs.qword();
unknown.repeat(3, u => u.float());
unknown.bytes(5);
let pillar = rs.dword();
if (pillar > 0) {
this.pillar = {
id: pillar,
rotation: rs.float(),
position: rs.vector3(),
};
}
rs.assert();
return this;
}
// # toBuffer()
toBuffer() {
let ws = new WriteBuffer();
const unknown = this.u.writer(ws);
ws.dword(this.mem);
ws.version(this.version);
ws.dword(this.appearance);
unknown.dword();
ws.tract(this.tract);
ws.array(this.sgprops);
ws.gti(this.tgi);
if (this.matrix3) {
ws.byte(0x05);
ws.write(this.matrix3);
}
else {
ws.byte(0x01);
}
ws.vector3(this.position);
this.vertices.forEach(v => ws.vertex(v));
ws.dword(this.modelId);
ws.byte(this.wealthTexture);
ws.dword(this.baseTexture);
ws.byte(this.orientation);
unknown.bytes();
ws.byte(this.crossings.length - 1);
for (let crossing of this.crossings) {
crossing.write(ws);
}
ws.array(this.walls, ({ texture, vertex }) => {
ws.dword(texture);
ws.vertex(vertex);
});
ws.bbox(this.bbox, { range: true });
ws.dword(this.constructionStates);
ws.dword(this.pathId);
unknown.dword();
unknown.dword();
unknown.dword();
ws.qword(this.demolishingCosts);
unknown.float();
unknown.float();
unknown.float();
unknown.bytes();
if (this.pillar) {
ws.dword(this.pillar.id);
ws.float(this.pillar.rotation);
ws.vector3(this.pillar.position);
}
else {
ws.dword(0x00000000);
}
unknown.assert();
return ws.seal();
}
}