Created
August 6, 2020 15:02
-
-
Save securas/a123280ab1196eac4e13fa062407891c to your computer and use it in GitHub Desktop.
A custom godot autotiler for blocks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
tool | |
extends TileSet | |
const EMPTY_AUTOTILE = Vector2( 4, 0 ) | |
var block_tiles = [ "blocks" ] | |
func _forward_subtile_selection(autotile_id : int, _bitmask : int, tilemap : Object, tile_location : Vector2 ): | |
if block_tiles.find( tile_get_name( autotile_id ) ) < 0: | |
return null#._forward_subtile_selection( autotile_id, bitmask, tilemap, tile_location ) | |
tilemap = tilemap as TileMap | |
var cur_tile_coord = tilemap.get_cell_autotile_coord( tile_location.x, tile_location.y ) | |
#---------------------------------- | |
# check if current tile can be changed | |
#---------------------------------- | |
var cur_tile_bitmask = autotile_get_bitmask( autotile_id, cur_tile_coord ) | |
#---------------------------------- | |
# relevant adjacent tiles | |
#---------------------------------- | |
# top left | |
if tilemap.get_cellv( tile_location - Vector2.ONE ) == autotile_id: | |
var coord = tilemap.get_cell_autotile_coord( tile_location.x - 1, tile_location.y - 1 ) | |
var relbit = autotile_get_bitmask( autotile_id, coord ) | |
var mask_from_top_left : bool = relbit & BIND_BOTTOMRIGHT | |
if mask_from_top_left: | |
return EMPTY_AUTOTILE | |
# top | |
if tilemap.get_cellv( tile_location + Vector2.UP ) == autotile_id: | |
var coord = tilemap.get_cell_autotile_coord( tile_location.x, tile_location.y - 1 ) | |
var relbit = autotile_get_bitmask( autotile_id, coord ) | |
var mask_from_top : bool = relbit & BIND_BOTTOMLEFT | |
if mask_from_top: | |
return EMPTY_AUTOTILE | |
# left | |
if tilemap.get_cellv( tile_location + Vector2.LEFT ) == autotile_id: | |
var coord = tilemap.get_cell_autotile_coord( tile_location.x - 1, tile_location.y ) | |
var relbit = autotile_get_bitmask( autotile_id, coord ) | |
var mask_from_left : bool = relbit & BIND_TOPRIGHT | |
if mask_from_left: | |
return EMPTY_AUTOTILE | |
#---------------------------------- | |
# check possible masks for new tile | |
#---------------------------------- | |
var allowed_mask = [ 1, 0, 0, 0 ] | |
# right | |
if tilemap.get_cellv( tile_location + Vector2.RIGHT ) == autotile_id: | |
var coord = tilemap.get_cell_autotile_coord( tile_location.x + 1, tile_location.y ) | |
var bits = autotile_get_bitmask( autotile_id, coord ) | |
if bits == BIND_TOPLEFT: | |
allowed_mask[1] = 1 | |
elif bits == ( BIND_TOPLEFT + BIND_BOTTOMLEFT ): | |
if tilemap.get_cellv( tile_location + Vector2.DOWN ) == autotile_id: | |
var coord2 = tilemap.get_cell_autotile_coord( tile_location.x, tile_location.y + 1 ) | |
var bits2 = autotile_get_bitmask( autotile_id, coord2 ) | |
if bits2 == BIND_TOPLEFT: | |
allowed_mask[1] = 1 | |
allowed_mask[2] = 1 | |
allowed_mask[3] = 1 | |
# bottom | |
if tilemap.get_cellv( tile_location + Vector2.DOWN ) == autotile_id: | |
var coord = tilemap.get_cell_autotile_coord( tile_location.x, tile_location.y + 1 ) | |
var bits = autotile_get_bitmask( autotile_id, coord ) | |
if bits == BIND_TOPLEFT: | |
allowed_mask[2] = 1 | |
elif bits == ( BIND_TOPLEFT + BIND_TOPRIGHT ): | |
if tilemap.get_cellv( tile_location + Vector2.RIGHT ) == autotile_id: | |
var coord2 = tilemap.get_cell_autotile_coord( tile_location.x + 1, tile_location.y ) | |
var bits2 = autotile_get_bitmask( autotile_id, coord2 ) | |
if bits2 == BIND_TOPLEFT: | |
allowed_mask[1] = 1 | |
allowed_mask[2] = 1 | |
allowed_mask[3] = 1 | |
# remove impossible flags | |
# top right | |
if tilemap.get_cellv( tile_location + Vector2( 1, -1 ) ) == autotile_id: | |
var coord = tilemap.get_cell_autotile_coord( tile_location.x + 1, tile_location.y - 1 ) | |
var bits = autotile_get_bitmask( autotile_id, coord ) | |
if bits & BIND_BOTTOMLEFT: | |
allowed_mask[1] = 0 | |
# bottom left | |
if tilemap.get_cellv( tile_location + Vector2( -1, 1 ) ) == autotile_id: | |
var coord = tilemap.get_cell_autotile_coord( tile_location.x - 1, tile_location.y + 1 ) | |
var bits = autotile_get_bitmask( autotile_id, coord ) | |
if bits & BIND_TOPRIGHT: | |
allowed_mask[2] = 0 | |
var amask = allowed_mask[0] + \ | |
allowed_mask[1] * BIND_TOPRIGHT + \ | |
allowed_mask[2] * BIND_BOTTOMLEFT + \ | |
allowed_mask[3] * BIND_BOTTOMRIGHT | |
# priority to current tile | |
if cur_tile_bitmask != BIND_TOPLEFT and cur_tile_bitmask & ( ~amask ): | |
return cur_tile_coord | |
var compatible_tiles = find_tilecoord_with_mask( autotile_id, amask ) | |
# select random tile | |
return compatible_tiles[ randi() % compatible_tiles.size() ] | |
func find_tilecoord_with_mask( id : int, tmask : int ) -> Array: | |
var tsize = tile_get_region( id ).size / autotile_get_size( id ).round() | |
var compatible_tiles = [] | |
for x in range( tsize.x ): | |
for y in range( tsize.y ): | |
var coord = Vector2( x, y ) | |
var curmask = autotile_get_bitmask( id, coord ) | |
if curmask != 0 and not( curmask & ( ~tmask ) ): | |
compatible_tiles.append( coord ) | |
return compatible_tiles | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment