ID:1142372
 
After a really long time of messing with this code off and on, I've come to what I think is the fastest possible auto-join solution in BYOND. Extra special thanks to Jemai1 for helping me get the rest of the way.

This is ONLY for 47 state auto joining. I have never needed anything else, and the standard auto-tile system seen in RPG Maker XP / VX is 47 state joining.

If you need weird state joins, this code isn't for you.

turf
Del()
spawn for(var/auto_tile/a in range(1, src)) a.join()
..()

auto_tile
parent_type = /turf

var
list/matches = null
list/exclude = null

New()
..()
if(!icon_state) src.join()

proc/join()
var/byte = 0
byte = src.match(NORTH, byte, 1)
byte = src.match(EAST, byte, 4)
byte = src.match(SOUTH, byte, 16)
byte = src.match(WEST, byte, 64)
byte = src.match(NORTHEAST, byte, 2, 5)
byte = src.match(SOUTHEAST, byte, 8, 20)
byte = src.match(SOUTHWEST, byte, 32, 80)
byte = src.match(NORTHWEST, byte, 128, 65)
src.icon_state = "[byte]"

proc/match(direction, byte, bit, mask = 0)
if((byte & mask) == mask && src.ismatch(direction)) byte |= bit
else byte &= ~bit
return byte

proc/ismatch(direction)
var/auto_tile/t = get_step(src, direction)
if(!t) return 1
if(istype(t, src.type)) return 1
for(var/v in src.matches)
if(v == direction) return 1
else if(istype(t, v) && !(t.type in src.exclude)) return 1
return 0


To use it, just derive from /auto_tile

environment/cave/floor/auto_tile
parent_type = /auto_tile
icon = 'whatever_auto_tile.dmi'


This allows support for matching via type, and excluding from parent types. It also allows matching to DIRECTION.

floor_to_water
parent_type = /auto_tile

matches = list(/floor, /water)
//this will connect to floors, AND water

floor_base
parent_type = /auto_tile

matches = list(/floor, SOUTH)
//this will connect to floors, and any tile that is SOUTH of this tile

//you can also connect to a whole "type" while excluding a specific part of that parent type

tree_branch
parent_type = /auto_tile
matches = list(/tree) //connect to /tree and all its children
exclude = list(/tree/root) //but don't connect to /tree/root


This expects Lummox JR's state numbering for the icon_states, which can be found in his Icon Cutter utility.
Neato! any chance of a library/demo from this?
I felt the code was too short to make into a library. Just copy and paste that, and you're done.
Quick protip: This can actually get faster. Do autotile detection for all 8-directions, then set up a list to convert it to 47-state fallbacks:

var/state47override = list(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,18,18,16,16,18,18,24,24,26,26,24,24,26,26,32,33,32,33,36,37,36,37,32,33,32,33,36,37,36,37,48,48,48,50,48,48,50,50,48,56,48,58,56,56,58,58,64,64,66,66,68,68,70,70,64,64,66,66,68,68,70,70,80,80,82,82,80,80,82,82,80,88,82,90,88,88,90,90,96,96,96,98,100,100,100,102,96,96,98,98,100,100,102,102,112,112,112,114,112,112,114,114,112,120,114,122,120,120,122,122,128,129,128,129,128,129,128,129,136,137,136,137,136,137,136,137,144,144,144,146,144,144,146,146,152,152,152,154,152,152,154,154,160,161,160,161,160,161,160,161,160,161,168,169,168,169,168,169,176,176,176,178,176,176,178,178,176,184,184,186,184,184,186,186,192,192,192,194,192,196,192,198,192,192,194,194,196,196,198,198,208,208,208,210,208,208,210,210,208,216,210,218,216,216,218,218,224,224,224,226,224,228,224,230,224,224,226,226,228,228,230,230,240,240,240,242,240,240,242,242,240,248,242,250,248,248,250,250)


When using this, just set the icon state to "[state47override[matches+1]]".

This will save you having to process the states through that chain of if-statements. A single list index is going to be faster than several binary operators on each match to ensure that the corners don't overlap the straight directions.