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, 4, buf => buf.write(this.magic))
- data = this.add(data, 4, buf => buf.writeInt32LE(this.version))
- data = this.add(data, 1, buf => buf.write(this.tileset))
- data = this.add(data, 4, buf => buf.writeInt32LE(this.custom_tilesets ? 1 : 0))
- data = this.add(data, 4, buf => 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.tiles.reduce(
- (data, tileData) => {
- return this.add(data, 7, buf => {
- buf.writeInt16LE(tileData.height, 0)
- buf.writeInt16LE(tileData.value, 2)
- buf.writeIntLE((tileData.flags << 4) | tileData.texture, 4, 1)
- buf.writeIntLE(tileData.details, 5, 1)
- buf.writeIntLE((tileData.clifftex << 4) | tileData.layerHeight, 6, 1)
- })
- }, data
- )
- stream.write(data[0])
- stream.end()
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement