import { MapLayer , Point } from '../../../models/cross-code-map' ; import * as Phaser from 'phaser' ; import { Helper } from '../helper' ; import Tile = Phaser . Tilemaps . Tile ; export class CCMapLayer { public details ! : MapLayer ; private layer ! : Phaser . Tilemaps . DynamicTilemapLayer ; constructor ( private tilemap ) { } public async init ( details ) { if ( typeof details . level === 'string' ) { if ( ! isNaN ( < any > details . level ) ) { details . level = parseInt ( details . level , 10 ) ; } else { details . levelName = details . level ; if ( details . level . startsWith ( 'first' ) ) { details . level = 0 ; } else { details . level = 10 ; } } } if ( typeof details . distance === 'string' ) { details . distance = parseFloat ( details . distance ) ; } this . details = details ; this . layer = this . tilemap . createBlankDynamicLayer ( details . name + Math . random ( ) , 'stub' ) ; if ( details . data ) { this . layer . putTilesAt ( details . data , 0 , 0 , false ) ; } await this . updateTileset ( details . tilesetName ! ) ; this . updateLevel ( this . details . level ) ; const skip = 'Navigation Collision HeightMap' . split ( ' ' ) ; skip . forEach ( type => { if ( type === details . type ) { this . visible = false ; } } ) ; } get visible ( ) : boolean { return this . layer . visible ; } set visible ( val ) { this . layer . visible = val ; this . layer . active = val ; } get alpha ( ) : number { return this . layer . alpha ; } set alpha ( val ) { this . layer . alpha = val ; } destroy ( ) { this . layer . destroy ( ) ; } offsetLayer ( offset , borderTiles = false ) { const data = this . layer . layer . data ; const newData = [ ] ; for ( let y = 0 ; y < data . length ; y ++ ) { newData [ y ] = [ ] ; for ( let x = 0 ; x < data [ y ] . length ; x ++ ) { let newTile ; let row = data [ y - offset . y ] ; if ( ! row && borderTiles ) { row = offset . y > 0 ? data [ 0 ] : data [ data . length - 1 ] ; } if ( row ) { newTile = row [ x - offset . x ] ; if ( borderTiles && newTile === undefined ) { newTile = offset . x > 0 ? row [ 0 ] : row [ row . length - 1 ] ; } } newData [ y ] [ x ] = newTile ?. index ?? 0 ; } } this . layer . putTilesAt ( newData , 0 , 0 , false ) ; } resize ( width , height ) { const data = this . layer . layer . data ; this . details . width = width ; this . details . height = height ; const newData = [ ] ; for ( let y = 0 ; y < height ; y ++ ) { newData [ y ] = [ ] ; const old = data [ y ] || [ ] ; for ( let x = 0 ; x < width ; x ++ ) { newData [ y ] [ x ] = old [ x ] ?. index ?? 0 ; } } const tilesetName = this . layer . tileset [ 0 ] . name ; const visible = this . layer . visible ; this . layer . destroy ( ) ; this . layer = this . tilemap . createBlankDynamicLayer ( this . details . name + Math . random ( ) , tilesetName , 0 , 0 , width , height ) ; this . layer . putTilesAt ( newData , 0 , 0 , false ) ; this . visible = visible ; } async updateTileset ( tilesetname ) { const details = this . details ; details . tilesetName = tilesetname ; const oldLayer = this . layer ; await Helper . loadTexture ( tilesetname , this . tilemap . scene ) ; const newTileset = this . tilemap . addTilesetImage ( tilesetname , undefined , undefined , undefined , undefined , undefined , 1 ) ; this . layer = this . tilemap . createBlankDynamicLayer ( details . name + Math . random ( ) , newTileset ?? [ ] , 0 , 0 , details . width , details . height ) ; this . layer . putTilesAt ( oldLayer . layer . data , 0 , 0 , false ) ; oldLayer . destroy ( ) ; } updateLevel ( level ) { this . details . level = level ; let zIndex = this . details . level * 10 ; if ( isNaN ( zIndex ) ) { zIndex = 999 ; } this . layer . depth = this . details . level * 10 ; } getPhaserLayer ( ) { return this . layer ; } exportLayer ( ) { const out = Object . assign ( { } , this . details ) ; if ( out . levelName ) { out . level = out . levelName ; delete out . levelName ; } out . data = [ ] ; this . extractLayerData ( out ) ; return out ; } private extractLayerData ( layer ) { this . layer . getTilesWithin ( ) . forEach ( tile => { if ( ! layer . data [ tile . y ] ) { layer . data [ tile . y ] = [ ] ; } layer . data [ tile . y ] [ tile . x ] = tile . index ; } ) ; } }