ID:143868
 
The following code is the most recent incarnation of the 13-state autojoining process that I've come up with. Its still pretty slow compared to something like 16-state autojoining though, so I'd like to know if there's anyone out there who can come up with a way to make this faster. Any takers?

#define N  1
#define E 2
#define S 4
#define W 8
#define NE 16
#define NW 32
#define SE 64
#define SW 128

atom/proc/GetState13()
var/byte = 0

// Determine which neighboring tiles this atom can join to.
if(src.JoinTo(get_step(src, NORTH))) byte |= N
if(src.JoinTo(get_step(src, EAST))) byte |= E
if(src.JoinTo(get_step(src, SOUTH))) byte |= S
if(src.JoinTo(get_step(src, WEST))) byte |= W
if(src.JoinTo(get_step(src, NORTHEAST))) byte |= NE
if(src.JoinTo(get_step(src, SOUTHEAST))) byte |= SE
if(src.JoinTo(get_step(src, SOUTHWEST))) byte |= SW
if(src.JoinTo(get_step(src, NORTHWEST))) byte |= NW

// Check to see which directions are and aren't joinable in order to determine
// which icon should be displayed.
if(byte&N && byte&E && byte&S && byte&W && byte&NE && byte&SE && byte&SW && !(byte&NW))
return 12
if(byte&N && byte&E && byte&S && byte&W && !(byte&NE) && byte&SE && byte&SW && byte&NW)
return 11
if(byte&N && byte&E && byte&S && byte&W && byte&NE && byte&SE && !(byte&SW) && byte&NW)
return 10
if(byte&N && byte&E && byte&S && byte&W && byte&NE && !(byte&SE) && byte&SW && byte&NW)
return 9
if(byte&N && !(byte&E) && !(byte&S) && byte&W)
return 8
if(byte&N && byte&E && !(byte&S) && byte&W)
return 7
if(byte&N && byte&E && !(byte&S) && !(byte&W))
return 6
if(byte&N && !(byte&E) && byte&S && byte&W)
return 5
if(byte&N && byte&E && byte&S && !(byte&W))
return 4
if(!(byte&N) && !(byte&E) && byte&S && byte&W)
return 3
if(!(byte&N) && byte&E && byte&S && byte&W)
return 2
if(!(byte&N) && byte&E && byte&S && !(byte&W))
return 1
return 13

// This proc is checked to see whether a location can be joined to or not.
atom/proc/JoinTo(atom/A)
if(!A)
return 1
if(istype(A, src.type))
return 1
if(isturf(A))
for(var/atom/movable/M in A)
if(istype(M, src.type))
return 1
return 0
I recomend looking at the source of LummoxJr's IconCutter.
In the TrueState() proc, it has all the bit shifting formulas for the various styles of autojoining.

http://developer.byond.com/hub/LummoxJR/IconCutter
I'm not sure what your states are, but the quickest improvement I can see is naming them so that you don't need a large block of if() statements. Conceptually, the simplest way would be to name as the value of the byte variable would be. So, for example, North and East would be N|E or "3". You can then use that to cut out the if() block, as well as making it slightly more flexible.
In response to Drumersl
Drumersl wrote:
I recomend looking at the source of LummoxJr's IconCutter.
In the TrueState() proc, it has all the bit shifting formulas for the various styles of autojoining.

http://developer.byond.com/hub/LummoxJR/IconCutter

From the docs:

'Foomerian 13-state joining:
This special form of 47-state joins accepts only a solid fill, a single
edge, a single outer corner with a solid corner opposite, or a single
inside corner with the other corners all filled. It requires only 13
icons, but requires a special layout in which 1) all joining tiles must
be part of a 2x2 block, and 2) two such blocks may not join only at the
corner (which would cause the common block to have 2 inside corners).
The main attraction of this join type is that it allows greater
artistic freedom because other edges/corners need not be considered.'

He named it after you after all :P
In response to Flick
Flick wrote:
Drumersl wrote:
I recomend looking at the source of LummoxJr's IconCutter.
In the TrueState() proc, it has all the bit shifting formulas for the various styles of autojoining.

http://developer.byond.com/hub/LummoxJR/IconCutter

From the docs:

'Foomerian 13-state joining:
This special form of 47-state joins accepts only a solid fill, a single
edge, a single outer corner with a solid corner opposite, or a single
inside corner with the other corners all filled. It requires only 13
icons, but requires a special layout in which 1) all joining tiles must
be part of a 2x2 block, and 2) two such blocks may not join only at the
corner (which would cause the common block to have 2 inside corners).
The main attraction of this join type is that it allows greater
artistic freedom because other edges/corners need not be considered.'

He named it after you after all :P

Yeah and if you look up 'Foomerian' around here its usually either talking about monkeys or autojoining tiles.
In response to Garthor
The trouble is that you can't just check which directions to connect to, you have to check which directions not to connect to as well, at least in some of the cases.
In response to Drumersl
Drumersl wrote:
I recomend looking at the source of LummoxJr's IconCutter.
In the TrueState() proc, it has all the bit shifting formulas for the various styles of autojoining.

http://developer.byond.com/hub/LummoxJR/IconCutter

I say if Lummox has a better way to do it he can come post it himself because I'm not going to hurt myself trying to comprehend stuff that looks like this
j=(i^(i&((i>>1)|(i<<1)|(i>>7))))&85
j^=(j&(j-1))