@name 14-segment sign maker
@inputs String:string Master:entity Scale Start Parent FX
@inputs Colour:vector
@persist Chardefs:table Defaultpos:array Holos:array 
@persist Spawning Index RemainingSpawns Nextburst Nextspawn
#by Magos Mechanicus

if(Start&~Start&Master&Scale){
    holoDeleteAll()
    Holos=array()
    Spawning=1 Index=0
    }

if(Spawning){
    #Remaining spawns tracking
    Curtime=curtime()
    if(Curtime >= Nextspawn){
        Nextspawn=Curtime+1
        if(Curtime >= Nextburst){
            RemainingSpawns=30
            Nextburst=Curtime+10
        }elseif(RemainingSpawns<10){
            RemainingSpawns=10}
    }
    Nextburst=Curtime+10
    
    #If we have the spawns to spare:
    Decoded=Chardefs[String:upper():index(Index+1), string]
    if(Decoded:replace("0",""):length() <= RemainingSpawns){
            Index++
            Origin=Master:toWorld( vec( 0,3*(Index-String:length()/2)*Scale,5+Master:boxSize():z() ) )
            Frame=matrix(Master)*Scale Roll=Master:angles():pitch()
            Find=Decoded:find("1")
            while(Find){
                #Spawn and track
                Holoindex=Holos:count()+1
                holoCreate(Holoindex)
                Holos[Holoindex, vector2] = vec2(Find, Index) 
                RemainingSpawns--
                Matrix=Defaultpos[Find,matrix]
                
                #Positioning/orientation
                holoPos(Holoindex,Origin + Frame*Matrix:column(1))
                holoAng(Holoindex,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
                holoScaleUnits(Holoindex,Matrix:column(3)*Scale)
                
                #Rendering/parenting
                holoShadow(Holoindex,0)
                holoColor(Holoindex,Colour,255)
                if(Parent){holoParent(Holoindex,Master)}
                if(FX){holoRenderFX(Holoindex,3)
                    holoColor(Holoindex,Colour,200)}
                
                Find=Decoded:find("1",Find+1)
                }
            timer("Spawning",10)
        }
        else{timer("Waittospawn",1001)}

    if(Index==String:length()){Spawning=0}
}

if(first()){
     #Local definitions for positions, directions and scales of different segments
    Hscale=vec(2,0.25,0.25)
    Half=vec(Hscale:x()/2,0.25,0.25)
    Small=vec(2.1,0.2,0.2)
    Angle=67.5
    Temp=matrix(vec(0,0,4),vec(0,1,0),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,1,3),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,1,1),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0,0),vec(0,1,0),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,-1,1),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,-1,3),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,-0.5,2),vec(0,1,0),Half)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0.5,2),vec(0,1,0),Half)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0,1),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0,3),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,-0.5,3),vec(0,cos(Angle),-sin(Angle)),Small)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0.5,3),vec(0,cos(Angle),sin(Angle)),Small)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,-0.5,1),vec(0,cos(Angle),sin(Angle)),Small)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0.5,1),vec(0,cos(Angle),-sin(Angle)),Small)
    Defaultpos:pushMatrix(Temp)
    
    #Character definitions
    #Characters follow the ABCDEF of the Wire 7-seg indicator
#but the F is split into two consecutive segments, counting from the left.
#Then follows the middle vertical segments, counting from the bottom and 
#then the crossbars, counting clockwise from the top left.
    #Each character's definition is indexed by the character itself
    Chardefs:setString("0","11111100000000")
    Chardefs:setString("1","01100000000000")
    Chardefs:setString("2","11011011000000")
    Chardefs:setString("3","11110011000000")
    Chardefs:setString("4","01100111000000")
    Chardefs:setString("5","10110111000000")
    Chardefs:setString("6","10111111000000")
    Chardefs:setString("7","11100000000000")
    Chardefs:setString("8","11111111000000")
    Chardefs:setString("9","11110111000000")
    Chardefs:setString("A","11101111000000")
    Chardefs:setString("B","11110001110000")
    Chardefs:setString("C","10011100000000")
    Chardefs:setString("D","11110000110000")
    Chardefs:setString("E","10011111000000")
    Chardefs:setString("F","10001111000000")
    Chardefs:setString("G","10111101000000")
    Chardefs:setString("H","01101111000000")
    Chardefs:setString("I","00000000110000")
    Chardefs:setString("J","01111000000000")
    Chardefs:setString("K","00001110000101") 
    Chardefs:setString("L","00011100000000")
    Chardefs:setString("M","01101100001100") 
    Chardefs:setString("N","01101100001001") 
    Chardefs:setString("O","11111100000000")
    Chardefs:setString("P","11001111000000")
    Chardefs:setString("Q","11111100000001")
    Chardefs:setString("R","11001111000001")
    Chardefs:setString("S","10110111000000")
    Chardefs:setString("T","10000000110000")
    Chardefs:setString("U","01111100000000")
    Chardefs:setString("V","00001100000110") 
    Chardefs:setString("W","01101100000011") 
    Chardefs:setString("X","00000000001111") 
    Chardefs:setString("Y","00000000101100")
    Chardefs:setString("Z","10010000000110")
    Chardefs:setString(" ","00000000000000") 
    Chardefs:setString("-","00000011000000")
    Chardefs:setString("'","00000000000100")
    
    RemainingSpawns=30 Nextspawn=Nextburst=curtime() 
    }
