UNPKG

sc4

Version:

A command line utility for automating SimCity 4 modding tasks & modifying savegames

131 lines (130 loc) 3.99 kB
// # network.ts import WriteBuffer from './write-buffer.js'; import { FileType } from './enums.js'; import Unknown from './unknown.js'; import Vertex from './vertex.js'; import { kFileType, kFileTypeArray } from './symbols.js'; import Box3 from './box-3.js'; import TractInfo from './tract-info.js'; import { Vector3 } from './vector-3.js'; import NetworkCrossing from './network-crossing.js'; import TGI from './tgi.js'; // # Network // A class for representing a single network tile. export default class Network { static [kFileType] = FileType.Network; static [kFileTypeArray] = true; crc = 0x00000000; version = '8.4'; mem = 0x00000000; appearance = 0x0500000000; tract = new TractInfo(); sgprops = []; tgi = new TGI(); position = new Vector3(); vertices = [ new Vertex(), new Vertex(), new Vertex(), new Vertex(), ]; textureId = 0x00000000; wealthTexture = 0x00; baseTexture = 0x00000000; orientation = 0x00; crossings = []; walls = []; bbox = new Box3(); constructionStates = 0x00000000; alternatePathId = 0x00000000; demolishingCosts = 0n; u = new Unknown() .dword(0xc772bf98) .byte(0) .bytes([0, 0]) .repeat(3, u => u.dword(0x00000000)); constructor(opts = {}) { Object.assign(this, opts); } // ## move() move(offset) { this.bbox = this.bbox.translate(offset); this.tract.update(this); } 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(2); this.appearance = rs.dword(); unknown.dword(0xc772bf98); this.tract = rs.tract(); this.sgprops = rs.sgprops(); this.tgi = rs.gti(); unknown.byte(); this.position = rs.vector3(); this.vertices = [ rs.vertex(), rs.vertex(), rs.vertex(), rs.vertex(), ]; this.textureId = rs.dword(); this.wealthTexture = rs.byte(); this.baseTexture = rs.dword(); this.orientation = rs.byte(); unknown.bytes(2); this.crossings = new Array(rs.byte() + 1); for (let i = 0; i < this.crossings.length; i++) { this.crossings[i] = new NetworkCrossing().parse(rs); } 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.alternatePathId = rs.dword(); unknown.repeat(3, u => u.dword()); this.demolishingCosts = rs.qword(); rs.assert(); return this; } 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); unknown.byte(); ws.vector3(this.position); this.vertices.forEach(v => ws.vertex(v)); ws.dword(this.textureId); 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.alternatePathId); unknown.repeat(3, u => u.dword()); ws.qword(this.demolishingCosts); unknown.assert(); return ws.seal(); } }