UNPKG

mdx-m3-viewer

Version:

A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.

301 lines (236 loc) 9.26 kB
import BinaryStream from '../../../common/binarystream'; import Force from './force'; import Player from './player'; import RandomItemTable from './randomitemtable'; import RandomUnitTable from './randomunittable'; import TechAvailabilityChange from './techavailabilitychange'; import UpgradeAvailabilityChange from './upgradeavailabilitychange'; /** * war3map.w3i - the general information file. */ export default class War3MapW3i { version: number = 0; saves: number = 0; editorVersion: number = 0; buildVersion: Uint32Array = new Uint32Array(4); name: string = ''; author: string = ''; description: string = ''; recommendedPlayers: string = ''; cameraBounds: Float32Array = new Float32Array(8); cameraBoundsComplements: Int32Array = new Int32Array(4); playableSize: Int32Array = new Int32Array(2); flags: number = 0; tileset: string = 'A'; campaignBackground: number = 0; loadingScreenModel: string = ''; loadingScreenText: string = ''; loadingScreenTitle: string = ''; loadingScreenSubtitle: string = ''; loadingScreen: number = 0; prologueScreenModel: string = ''; prologueScreenText: string = ''; prologueScreenTitle: string = ''; prologueScreenSubtitle: string = ''; useTerrainFog: number = 0; fogHeight: Float32Array = new Float32Array(2); fogDensity: number = 0; fogColor: Uint8Array = new Uint8Array(4); globalWeather: number = 0; soundEnvironment: string = ''; lightEnvironmentTileset: string = '\0'; waterVertexColor: Uint8Array = new Uint8Array(4); scriptMode: number = 0; graphicsMode: number = 0; players: Player[] = []; forces: Force[] = []; upgradeAvailabilityChanges: UpgradeAvailabilityChange[] = []; techAvailabilityChanges: TechAvailabilityChange[] = []; randomUnitTables: RandomUnitTable[] = []; randomItemTables: RandomItemTable[] = []; unknown1: number = 0; constructor(buffer?: ArrayBuffer) { if (buffer) { this.load(buffer); } } load(buffer: ArrayBuffer) { let stream = new BinaryStream(buffer); this.version = stream.readInt32(); this.saves = stream.readInt32(); this.editorVersion = stream.readInt32(); if (this.version > 27) { stream.readUint32Array(this.buildVersion); } this.name = stream.readUntilNull(); this.author = stream.readUntilNull(); this.description = stream.readUntilNull(); this.recommendedPlayers = stream.readUntilNull(); stream.readFloat32Array(this.cameraBounds); stream.readInt32Array(this.cameraBoundsComplements); stream.readInt32Array(this.playableSize); this.flags = stream.readUint32(); this.tileset = stream.read(1); this.campaignBackground = stream.readInt32(); if (this.version > 24) { this.loadingScreenModel = stream.readUntilNull(); } this.loadingScreenText = stream.readUntilNull(); this.loadingScreenTitle = stream.readUntilNull(); this.loadingScreenSubtitle = stream.readUntilNull(); this.loadingScreen = stream.readInt32(); if (this.version > 24) { this.prologueScreenModel = stream.readUntilNull(); } this.prologueScreenText = stream.readUntilNull(); this.prologueScreenTitle = stream.readUntilNull(); this.prologueScreenSubtitle = stream.readUntilNull(); if (this.version > 24) { this.useTerrainFog = stream.readInt32(); stream.readFloat32Array(this.fogHeight); this.fogDensity = stream.readFloat32(); stream.readUint8Array(this.fogColor); this.globalWeather = stream.readInt32(); this.soundEnvironment = stream.readUntilNull(); this.lightEnvironmentTileset = stream.read(1, true); stream.readUint8Array(this.waterVertexColor); } if (this.version > 27) { this.scriptMode = stream.readUint32(); } if (this.version > 30) { this.graphicsMode = stream.readUint32(); this.unknown1 = stream.readUint32(); } for (let i = 0, l = stream.readInt32(); i < l; i++) { let player = new Player(); player.load(stream, this.version); this.players[i] = player; } for (let i = 0, l = stream.readInt32(); i < l; i++) { let force = new Force(); force.load(stream); this.forces[i] = force; } for (let i = 0, l = stream.readInt32(); i < l; i++) { let upgradeAvailabilityChange = new UpgradeAvailabilityChange(); upgradeAvailabilityChange.load(stream); this.upgradeAvailabilityChanges[i] = upgradeAvailabilityChange; } for (let i = 0, l = stream.readInt32(); i < l; i++) { let techAvailabilityChange = new TechAvailabilityChange(); techAvailabilityChange.load(stream); this.techAvailabilityChanges[i] = techAvailabilityChange; } for (let i = 0, l = stream.readInt32(); i < l; i++) { let randomUnitTable = new RandomUnitTable(); randomUnitTable.load(stream); this.randomUnitTables[i] = randomUnitTable; } if (this.version > 24) { for (let i = 0, l = stream.readInt32(); i < l; i++) { let randomItemTable = new RandomItemTable(); randomItemTable.load(stream); this.randomItemTables[i] = randomItemTable; } } } save() { let buffer = new ArrayBuffer(this.getByteLength()); let stream = new BinaryStream(buffer); stream.writeInt32(this.version); stream.writeInt32(this.saves); stream.writeInt32(this.editorVersion); if (this.version > 27) { stream.writeUint32Array(this.buildVersion); } stream.write(`${this.name}\0`); stream.write(`${this.author}\0`); stream.write(`${this.description}\0`); stream.write(`${this.recommendedPlayers}\0`); stream.writeFloat32Array(this.cameraBounds); stream.writeInt32Array(this.cameraBoundsComplements); stream.writeInt32Array(this.playableSize); stream.writeUint32(this.flags); stream.write(this.tileset); stream.writeInt32(this.campaignBackground); if (this.version > 24) { stream.write(`${this.loadingScreenModel}\0`); } stream.write(`${this.loadingScreenText}\0`); stream.write(`${this.loadingScreenTitle}\0`); stream.write(`${this.loadingScreenSubtitle}\0`); stream.writeInt32(this.loadingScreen); if (this.version > 24) { stream.write(`${this.prologueScreenModel}\0`); } stream.write(`${this.prologueScreenText}\0`); stream.write(`${this.prologueScreenTitle}\0`); stream.write(`${this.prologueScreenSubtitle}\0`); if (this.version > 24) { stream.writeInt32(this.useTerrainFog); stream.writeFloat32Array(this.fogHeight); stream.writeFloat32(this.fogDensity); stream.writeUint8Array(this.fogColor); stream.writeInt32(this.globalWeather); stream.write(`${this.soundEnvironment}\0`); stream.write(this.lightEnvironmentTileset); stream.writeUint8Array(this.waterVertexColor); } if (this.version > 27) { stream.writeUint32(this.scriptMode); } if (this.version > 30) { stream.writeUint32(this.graphicsMode); stream.writeUint32(this.unknown1); } stream.writeUint32(this.players.length); for (let player of this.players) { player.save(stream, this.version); } stream.writeUint32(this.forces.length); for (let force of this.forces) { force.save(stream); } stream.writeUint32(this.upgradeAvailabilityChanges.length); for (let change of this.upgradeAvailabilityChanges) { change.save(stream); } stream.writeUint32(this.techAvailabilityChanges.length); for (let change of this.techAvailabilityChanges) { change.save(stream); } stream.writeUint32(this.randomUnitTables.length); for (let table of this.randomUnitTables) { table.save(stream); } if (this.version > 24) { stream.writeUint32(this.randomItemTables.length); for (let table of this.randomItemTables) { table.save(stream); } } return buffer; } getByteLength() { let size = 111 + this.name.length + this.author.length + this.description.length + this.recommendedPlayers.length + this.loadingScreenText.length + this.loadingScreenTitle.length + this.loadingScreenSubtitle.length + this.prologueScreenText.length + this.prologueScreenTitle.length + this.prologueScreenSubtitle.length; for (let player of this.players) { size += player.getByteLength(this.version); } for (let force of this.forces) { size += force.getByteLength(); } size += this.upgradeAvailabilityChanges.length * 16; size += this.techAvailabilityChanges.length * 8; for (let table of this.randomUnitTables) { size += table.getByteLength(); } if (this.version > 24) { size += 36 + this.loadingScreenModel.length + this.prologueScreenModel.length + this.soundEnvironment.length; for (let table of this.randomItemTables) { size += table.getByteLength(); } } return size; } }