// m32 script test & show-off file
// do "include a" in the console

include names.h

// flag 1: per-block (top-level, event, or state) variable
gamevar i 0 1
gamevar j 0 1
gamevar k 0 1
gamevar l 0 1
gamevar m 0 1
gamevar p 0 1
gamevar q 0 1

gamevar tmp 0 0

gamevar davr 65536 0
gamevar dayx 65536 0

gamevar drawcol 9 0

define TQUOTE 3

definequote 0 OK
definequote 1 DAMN

definequote 2 BU:%d ABS:%d
definequote TQUOTE write on me!

definequote 4 ASPECT: VR=%d, YX=%d
definequote 5 ALPHA KEY: %d (SCANCODE: %d)

definequote 6 time: %d ms

definequote 7 door sector not an island sector!
definequote 8 door sector has no SE sprite!

//light sector     x     y     z   range  r   g   b   radi  fade angle  horiz  mins maxs prio tile
definequote 9 light  %d  %d %d %d  %d  %d %d %d  %d %d %d %d  %d %d  %d %d
definequote 10 --PRLIGHTS--
definequote 11 --ENDPRLIGHTS--

definequote 12 RED: 
definequote 13 GREEN: 
definequote 14 BLUE: 

definequote 15 x/yoffset: %d %d
definequote 16 (r/g/b)color: %d %d %d
definequote 17 PICNUM: 

definequote 18 NUMBER KEY: %d (SCANCODE: %d)

gamearray ar 128
gamearray parm 8

// various tests of m32-script features
defstate tests
// array test
    getarraysize ar tmp
    resizearray ar 65536
    getticks parm[2]
    for j range 65536
        set ar[j] j
    set i 0
    for j range 65536
        add i ar[j]
    getticks parm[3]
    resizearray ar tmp
    ife i 2147450880 quote 0 else quote 1
    sub parm[3] parm[2]
    qsprintf TQUOTE 6 parm[3]
    quote TQUOTE

// iteration and break test
    for i range 10
    {
        addlogvar i
        ife i 5 break
    }
    ife i 5 quote 0 else quote 1
ends

// prints out maphack light definitions based on SE lights in map
defstate printlights
    print 10
    for i allsprites, ifactor SECTOREFFECTOR, ifge .lotag 49, ifle .lotag 50
    {
        ife .lotag 50
        {
            set j 128, sub j .shade, shiftl j 1
            set k j, mul k 3, div k 4
        }
        else
        {
            set j 0, set k 0
        }

        set l 0
        ifand .cstat 2
        {
            ifand .cstat 512
                set l 4
            else
                set l 2
        }
        qsprintf TQUOTE 9 .sectnum .x .y .z .hitag .xvel .yvel .zvel
                   j k .ang .extra .xoffset .yoffset l .owner
        print TQUOTE
    }
    print 11
ends

// convenient polymer SE light manipulation with keypad keys
defstate fiddlewithlights
    ife searchstat 3 ife sprite[searchwall].picnum SECTOREFFECTOR
    ifge sprite[searchwall].lotag 49 ifle sprite[searchwall].lotag 50
    {
        set i searchwall, seti i

        // horiz
        ifeithershift set j 1 else set j 10
        ifhitkey KEY_gUP add .extra j
        else ifhitkey KEY_gKP5 sub .extra j
        clamp .extra -500 500

        // angle
        set j 128
        ifeitherctrl set j 4
        ifeithershift { ifeitherctrl set j 1 else set j 32 }
        ifhitkey KEY_gLEFT sub .ang j
        else ifhitkey KEY_gRIGHT add .ang j

        // range
        ifeithershift set j 10
        else ifeitherctrl set j 1000
        else set j 100
        ifhitkey KEY_gPGUP add .hitag j
        else ifhitkey KEY_gHOME sub .hitag j
        clamp .hitag 0 16000

        // radius
        ifeitherctrl
        {
            ifholdkey KEY_gMINUS add .shade 9
            else ifholdkey KEY_gPLUS sub .shade 9

            clamp .shade -118 117
        }

        // min/max shade
        ifeithershift set j -1 else set j 1
        ifeitherctrl
        {
            ifhitkey KEY_gSLASH
            {
                set .xoffset 0
                set .yoffset 0
            }
        }
        else
        {
            set k 0
            ifhitkey KEY_gSLASH { add .xoffset j, set k 1 }
            else ifhitkey KEY_gSTAR { add .yoffset j, set k 1 }

            ife k 1
            {
                qsprintf TQUOTE 15 .xoffset .yoffset
                quote TQUOTE
            }
        }

        // color/picnum
        ifeitheralt
        {
            ifhitkey KEY_gEND
            {
                getnumber256 .xvel 12 255
                getnumber256 .yvel 13 255
                getnumber256 .zvel 14 255
            }
            else ifhitkey KEY_gDOWN
            {
                getnumber256 .owner 17 -MAXTILES
            }
        }
        else
        {
            ifeitherctrl set j 1 else set j 10
            ifeithershift inv j

            set k 0
            ifhitkey KEY_gEND { add .xvel j, set k 1 }
            ifhitkey KEY_gDOWN { add .yvel j, set k 1 }
            ifhitkey KEY_gPGDN { add .zvel j, set k 1 }

            ife k 1
            {
                clamp .xvel 1 255
                clamp .yvel 1 255
                clamp .zvel 1 255

                qsprintf TQUOTE 16 .xvel .yvel .zvel
                quote TQUOTE
            }
        }
    }
ends

defstate testkeyavail
    for i range 27
    {
        ifholdkey alphakeys[i]
        {
            qsprintf TQUOTE 5 i alphakeys[i]
            quote TQUOTE
        }
    }

    for i range 10
    {
        ifholdkey numberkeys[i]
        {
            qsprintf TQUOTE 18 i numberkeys[i]
            quote TQUOTE
        }
    }
ends

//onevent EVENT_PREKEYS2D
//    state testkeyavail
//endevent

onevent EVENT_PREKEYS3D
//    state testkeyavail
    state fiddlewithlights
endevent

defstate setas
    set j dayx
    mul j ydim  mul j 8
    div j xdim  div j 5
    setaspect davr j
ends

onevent EVENT_ENTER3DMODE
    state setas
endevent

defstate cmp_by_lotag  // comparator subroutine for sorting
    set RETURN sprite[SV2].lotag
    sub RETURN sprite[SV1].lotag
ends

onevent EVENT_DRAW2DSCREEN
    ifl cursectnum 0 return

    // connect LOCATORS in a sector by lines
    getarraysize ar tmp
    set j 0
    for i spritesofsector cursectnum
    {
        ifge j tmp nullop else
        ifactor LOCATORS
        {
            set ar[j] i
            add j 1
        }
    }

    set tmp j
    sort ar tmp cmp_by_lotag

    sub tmp 1
    for i range tmp
    {
        set j ar[i]
        set k i, add k 1, set k ar[k]
        drawline16b sprite[j].x sprite[j].y sprite[k].x sprite[k].y drawcol
    }
/*
    set drawlinepat -1
    for i allsprites
        ifactor LIZTROOP
            drawcircle16b sprite[i].x sprite[i].y 256 drawcol
*/
endevent

// LOCATORS auto-incrementer
onevent EVENT_INSERTSPRITE2D
    set k I
    set j -1
    for i spritesofsector .sectnum
    {
        ifn i k, ifactor LOCATORS, ifg .lotag j
            set j .lotag
    }
    ifg j -1
    {
        add j 1
        set .lotag j
    }
endevent

// rotates and duplicates selected sprites around
// pivot sprite (extra=123, ang:dang, yrepeat<<5:dz (pos. if pal!=0), lo:cnt)
defstate duprot
    ifn searchstat 3 return
    ifn sprite[searchwall].extra 123 return
    ifl sprite[searchwall].shade 1 return
    set k searchwall

    for i range sprite[k].shade
    {
        for j selsprites, ifn j k
        {
            dupsprite j
            set tmp i, add tmp 1, mul tmp sprite[k].ang
            rotatepoint sprite[k].x sprite[k].y .x .y tmp (l m)
            add .ang tmp
            set tmp i, add tmp 1, mul tmp sprite[k].yrepeat, shiftl tmp 5
            ife sprite[k].pal 0 inv tmp
            add tmp .z
            bsetsprite I l m tmp
        }
    }
ends

// same as above but with tsprite[], as a kind of preview
defstate tduprot
    ifn searchstat 3 return
    ifn sprite[searchwall].extra 123 return
    ifl sprite[searchwall].shade 1 return
    set k searchwall

    for i range sprite[k].shade
    {
        for j selsprites, ifn j k
        {
            set p spritesortcnt
            tdupsprite j
            set tmp i, add tmp 1, mul tmp sprite[k].ang
            rotatepoint sprite[k].x sprite[k].y tsprite[p].x tsprite[p].y tmp (l m)
            add tsprite[p].ang tmp
            set tmp i, add tmp 1, mul tmp sprite[k].yrepeat, shiftl tmp 5
            ife sprite[k].pal 0 inv tmp
            add tmp tsprite[p].z
            set tsprite[p].x l
            set tsprite[p].y m
            set tsprite[p].z tmp
            or tsprite[p].cstat 514
//            bsetsprite I l m tmp
        }
    }
ends

onevent EVENT_ANALYZESPRITES
    state tduprot
/*
    for i drawnsprites
    {
        set j tsprite[i].owner
        switch sprite[j].picnum
        case LIZTROOP spritepal 1 break
        case PIGCOP spritepal 2 break
        case BOSS1 spritepal 6 break
        endswitch
    }
*/
endevent

onevent EVENT_KEYS3D
    // door sound tester
    ife searchstat 0
    ifholdkey KEY_SPACE
    {
        set k wall[searchwall].nextsector
        ifl k 0 set k searchsector

        ife sector[k].lotag 0 return

        for i spritesofsector k
        {
            ifactor MUSICANDSFX
            ifge .lotag 0 ifl .lotag MAXSOUNDS
            {
                getsoundflags .lotag m
                ifand m 1 nullop else soundonce .lotag
            }
        }
    }

    // swinging doors tester -- hit space on a door wall
    ife searchstat 0
    ifhitkey KEY_SPACE  // SE11 ST23 up:ccw
    {
        set k wall[searchwall].nextsector
        ifl k 0 return
        ifn sector[k].lotag 23 return
        set tmp 0
        for i loopofwall searchwall
        {
            ifl wall[i].nextsector 0 set tmp 1 else
            ifn wall[i].nextsector k set tmp 1
        }
// a weaker condition
//        for i loopofwall wall[searchwall].nextwall
//        {
//            ifl wall[i].nextsector 0 set tmp 1 else
//            ifn wall[i].nextsector searchsector set tmp 1
//        }
        ifn tmp 0
        {
            quote 7
            return
        }

        set l -1
        for i spritesofsector k
        {
            ifactor SECTOREFFECTOR ife sprite[i].lotag 11
            {
                set l i
                ifn sprite[i].ang 512 ifn sprite[i].ang 1024 ifn sprite[i].ang 1536 set l -1
            }
        }
        ifl l 0
        {
            quote 8
            return
        }

        for tmp wallsofsector k
        {
            rotatepoint (sprite[l].x sprite[l].y) (wall[tmp].x wall[tmp].y) sprite[l].ang (i j)
            dragpoint tmp i j
        }
        for tmp spritesofsector k
        {
            ifn tmp l
            {
                rotatepoint (sprite[l].x sprite[l].y) (sprite[tmp].x sprite[tmp].y) sprite[l].ang (i j)
                bsetsprite tmp i j sprite[tmp].z
            }
        }
        inv sprite[l].ang
    }

    // teleporter -- works on SE7 and SE17 (elevator)
    ife searchstat 3
    ifhitkey KEY_SPACE
    {
        ife sprite[searchwall].picnum SECTOREFFECTOR
        {
            set tmp 0
            ife sprite[searchwall].lotag 7 set tmp 1
            ife sprite[searchwall].lotag 17 set tmp 1
            ife tmp 0 return

            for i allsprites
            {
                ifn i searchwall, ifactor SECTOREFFECTOR, ife sprite[i].lotag sprite[searchwall].lotag
                ife sprite[i].hitag sprite[searchwall].hitag
                {
                    add posx sprite[i].x, sub posx sprite[searchwall].x
                    add posy sprite[i].y, sub posy sprite[searchwall].y
                    add posz sprite[i].z, sub posz sprite[searchwall].z

                    updatecursectnum

                    return
                }
            }
        }
        else ife sprite[searchwall].extra 123
        {
            state duprot
            add sprite[searchwall].extra 1
        }
    }

    ifholdkey KEY_0
    //    ife 0 1
    {
        ifeithershift sub davr 512 else add davr 512
        ifl davr 32768 set davr 32768
        ifg davr 256000 set davr 256000
        setaspect davr yxaspect
        qsprintf TQUOTE 4 davr yxaspect
        quote TQUOTE
    }
endevent

defstate replacestuff
    for i spritesofsector searchsector
//        ife sprite[i].picnum AMMO set sprite[i].picnum BATTERYAMMO
        ifactor parm[0] cactor parm[1]
ends

defstate convlights  // convert (0,0,0) lights to (255,255,255)-ones
	for i allsprites ifactor 1 ifge .lotag 49 ifle .lotag 50 ife .xvel 0 ife .yvel 0 ife .zvel 0
        { set .xvel 255 set .yvel 255 set .zvel 255 }
ends

defstate resetallws  // reset all sprites and walls to default repeat/panning
    for i allsprites
	{
		set .xrepeat 64
        set .yrepeat 64
	}
    for i allwalls
	{
		set wall[i].cstat 0
		set wall[i].xpanning 0
		set wall[i].ypanning 0
		set wall[i].yrepeat 8
		fixrepeats i
	}
ends

defstate jumptosec  // (tmp)
    for i allsectors
    {   
        ife i tmp
        {
            set j sector[i].wallptr
            set posx wall[j].x
            set posy wall[j].y
        }
    }   
ends

// Map corruption checker
definequote 19 PANIC!!! SECTOR OR WALL LIMIT EXCEEDED!!!
definequote 20 SECTOR[%d].WALLPTR=%d out of range: numwalls=%d!!!
definequote 21 SECTOR[%d].WALLPTR=%d inconsistent, expected %d!!!
definequote 22 SECTOR[%d]: wallptr+wallnum=%d out of range: numwalls=%d!!!
definequote 23 WALL[%d].POINT2=%d out of range: sector[%d].wallptr=%d, endwall=%d!!!
definequote 24 WALL[%d].NEXTWALL=%d out of range: numwalls=%d!!!
definequote 25 WALL[%d].NEXTSECTOR=%d out of range: numsectors=%d!!!

gamevar ewall 0 0
gamevar endwall 0 0

defstate corruptchk
    ifle numsectors MAXSECTORS ifle numwalls MAXWALLS nullop else
    { quote 19 printmessage16 19 return }
    set ewall 0  // expected wall index
    for i allsectors
    {
        set k 1
        ifge sector[i].wallptr 0 ifl sector[i].wallptr numwalls nullop else
        {
            qsprintf TQUOTE 20 i sector[i].wallptr numwalls
            quote TQUOTE printmessage16 TQUOTE
            set k 0
        }
        ifn ewall sector[i].wallptr
        {
			qsprintf TQUOTE 21 i sector[i].wallptr ewall
            quote TQUOTE printmessage16 TQUOTE
            set ewall sector[i].wallptr
        }
        add ewall sector[i].wallnum

        set endwall sector[i].wallptr  add endwall sector[i].wallnum
        ifg endwall numwalls
        {
            qsprintf TQUOTE 22 i endwall numwalls
            quote TQUOTE printmessage16 TQUOTE
            set k 0
        }

        ifn k 0
        {
			for j wallsofsector i
			{
				ifge wall[j].point2 sector[i].wallptr  ifl wall[i].point2 endwall nullop else
                {
                    qsprintf TQUOTE 23 j wall[j].point2 i sector[i].wallptr endwall
				    quote TQUOTE printmessage16 TQUOTE
                }

                ifge wall[i].nextwall numwalls
				{
					qsprintf TQUOTE 24 j wall[j].nextwall numwalls
				    quote TQUOTE printmessage16 TQUOTE
				}

                ifge wall[i].nextsector numsectors
				{
					qsprintf TQUOTE 25 j wall[j].nextsector numsectors
				    quote TQUOTE printmessage16 TQUOTE
				}
			}
        }
    }
ends
