Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import fs from 'fs'
- interface Tile {
- height: number
- value: number
- flags: number
- texture: number
- details: number
- clifftex: number
- layerHeight: number
- }
- export default class W3E {
- data: Buffer
- pointer: number
- size: number
- constructor(
- public srcPath: string
- ) {
- this.data = this.getData()
- }
- slice(start, end) {
- return this.data.slice(start, end)
- }
- getData() {
- return fs.readFileSync(this.srcPath, null)
- }
- assureMagic() {
- if(this.magic !== 'W3E!') {
- throw new Error(`INVALID MAGIC NUMBER, "${this.magic}"`)
- }
- }
- magic: string
- version: number
- tileset: string
- custom_tilesets: boolean
- tileset_count: number
- tilesets: Array<string>
- cliff_count: number
- cliffsets: Array<string>
- width: number
- height: number
- center: {
- x: number
- y: number
- }
- tileCount: number
- tiles: Array<Tile>
- parse() {
- const { data } = this
- this.magic = data.slice(0, 4).toString()
- this.assureMagic()
- this.version = data.readInt32LE(4)
- this.tileset = data.slice(8, 9).toString()
- this.custom_tilesets = data.readInt32LE(9) === 1
- this.tileset_count = data.readInt32LE(13)
- this.tilesets = []
- let offset = 17
- for(let i = 0; i < this.tileset_count; i++) {
- this.tilesets.push(data.slice(offset, offset + 4).toString())
- offset += 4
- }
- this.cliff_count = data.readInt32LE(offset)
- offset += 4
- this.cliffsets = []
- for(let i = 0; i < this.cliff_count; i++) {
- this.cliffsets.push(data.slice(offset, offset + 4).toString())
- offset += 4
- }
- this.width = data.readInt32LE(offset)
- offset += 4
- this.height = data.readInt32LE(offset)
- offset += 4
- this.tileCount = this.width * this.height
- this.center = {
- x: data.readFloatLE(offset),
- y: data.readFloatLE(offset + 4),
- }
- offset += 8
- this.tiles = []
- for(let i = 0; i < this.tileCount; i++) {
- let tile: any = {}
- tile.height = data.readInt16LE(offset)
- offset += 2
- tile.value = data.readInt16LE(offset)
- offset += 2
- let tmp = data.readIntLE(offset, 1)
- offset += 1
- tile.flags = tmp >> 4
- tile.texture = tmp & 0x0F
- tile.details = data.readIntLE(offset, 1)
- offset += 1
- tmp = data.readIntLE(offset, 1)
- offset += 1
- tile.clifftex = tmp >> 4
- tile.layerHeight = tmp & 0x0F
- this.tiles.push(tile)
- }
- this.size = offset
- }
- alloc(size, fill = 0, encoding = null): Buffer {
- return Buffer.alloc(size, fill, encoding)
- }
- add(data: [Buffer, number], size, cb): [Buffer, number] {
- let buf = this.alloc(size)
- cb(buf)
- return [Buffer.concat([data[0], buf]), data[1] + size]
- }
- write(path: string) {
- const stream = fs.createWriteStream(path)
- let data: [Buffer, number] = [this.alloc(0), 0]
- data = this.add(data, 17, buf => {
- buf.write(this.magic)
- buf.writeInt32LE(this.version)
- buf.write(this.tileset)
- buf.writeInt32LE(this.custom_tilesets ? 1 : 0)
- buf.writeInt32LE(this.tileset_count)
- })
- data = this.tilesets.reduce(
- (data, tile) => this.add(data, 4, buf => buf.write(tile)), data
- )
- data = this.add(data, 4, buf => buf.writeInt32LE(this.cliff_count))
- data = this.cliffsets.reduce(
- (data, cliff) => this.add(data, 4, buf => buf.write(cliff)), data
- )
- data = this.add(data, 4, buf => buf.writeInt32LE(this.width))
- data = this.add(data, 4, buf => buf.writeInt32LE(this.height))
- data = this.add(data, 4, buf => buf.writeFloatLE(this.center.x))
- data = this.add(data, 4, buf => buf.writeFloatLE(this.center.y))
- data = this.add(data, this.tiles.length * 7, (buf: Buffer) => {
- let offset = 0
- this.tiles.forEach(
- (tileData) => {
- buf.writeInt16LE(tileData.height, offset)
- buf.writeInt16LE(tileData.value, offset + 2)
- buf.writeIntLE((tileData.flags << 4) | tileData.texture, offset + 4, 1)
- buf.writeIntLE(tileData.details, offset + 5, 1)
- buf.writeIntLE((tileData.clifftex << 4) | tileData.layerHeight, offset + 6, 1)
- offset += 7
- }
- )
- })
- stream.write(data[0])
- stream.end()
- }
- }
- // in another file...
- import path, { resolve } from 'path'
- import fs from 'fs'
- import MDX from './binary/mdx'
- import BLP from './binary/blp'
- import W3E from './binary/w3e'
- const PWD = resolve(__dirname, '../')
- const EXAMPLES = resolve(PWD, './examples')
- const we = new W3E(resolve(EXAMPLES, './war3maporig.w3e'))
- we.parse()
- we.tiles = we.tiles.map(
- tile => {
- let height = Math.random() * (16383/12)
- return Object.assign({}, tile, {
- height: height
- // flags: tile.flags | 0x01 // make everything a fuckn ramp
- })
- }
- )
- we.write(resolve(EXAMPLES, './war3map.w3e'))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement