script, create unit by id, tile, id, begin variable(x, y, unit) x := x for tile(tile) y := y for tile(tile) switch(id) do( case(unit:player) unit := create player(x, y) case(unit:snow goon) unit := create snow goon(x, y) case(unit:werewolf) unit := create werewolf(x,y) case(unit:ganderer) unit := create ganderer(x,y) case(unit:rustmuncher) unit := create rustmuncher(x,y) else( if(valid tree(id -- unit:trees)) then( create generic tree(x, y, id -- unit:trees) ) ) ) exit returning(unit) end script, free unit, unit, begin free slice(unit) # Remove this unit from any globals if(unit == player) then(player := 0) if(unit == moving unit) then(moving unit := 0) drop(foes, unit) end script, create player, x, y, begin player := create unit(unit:player, x, y) replace hero sprite(player, 10) camera follows slice(player) set move range(player, 3) set move preview callback(player, @simple move preview) exit returning(player) end script, toggle player armor, begin variable(armor) armor := get unit armored(player) armor := not(armor) set unit armored(player, armor) update player armor sprite end script, update player armor sprite, begin variable(armor) armor := get unit armored(player) if(armor) then( set sprite set number(player, sprite:player armored) set animate callback(player, @player armor animate) )else( set sprite set number(player, sprite:player) set animate callback(player, none) ) set unit overheated(player, false) end script, player armor animate, unit, begin variable(pal) if(get unit overheated(unit)) then( pal := pal:armor normal + (ticks ,mod, 3) )else( if((ticks ,mod, (second * 3 / 4)) == 0) then( pal := pal:armor flash )else( pal := pal:armor normal ) ) set sprite palette(unit, pal) end #----------------------------------------------------------------------- script, create snow goon, x, y, begin variable(unit) unit := create unit(unit:snow goon, x, y) set unit team(unit, team:enemy) replace hero sprite(unit, 14) set ai callback(unit, @snow goon ai) set move range(unit, 1) set move preview callback(unit, @simple move preview) exit returning(unit) end script, snow goon ai, unit, begin variable(ftile, ptile) ftile := unit tile(unit) ptile := unit tile(player) find route(ftile, ptile) trim array(route, get move range(unit)) moving unit := unit end script, create werewolf, x, y, begin variable(unit) unit := create unit(unit:werewolf, x, y) set unit team(unit, team:enemy) replace hero sprite(unit, 26) set ai callback(unit, @werewolf ai) set move range(unit, 3) set move preview callback(unit, @dash move preview) exit returning(unit) end script, werewolf ai, unit, begin variable(ftile, ptile, dtile) ftile := unit tile(unit) ptile := unit tile(player) dtile := find best dash(ftile, ptile, get move range(unit)) if(dtile) then( find route(ftile, dtile) moving unit := unit ) end script, create ganderer, x, y, begin variable(unit) unit := create unit(unit:ganderer, x, y) set unit team(unit, team:enemy) replace hero sprite(unit, 29) set ai callback(unit, @ganderer ai) set move range(unit, 1) set attack range(unit, 4) set move preview callback(unit, @simple move preview) set animate callback(unit, @ganderer animate) exit returning(unit) end script, ganderer ai, unit, begin variable(ftile, ptile) ftile := unit tile(unit) ptile := unit tile(player) variable(memory tile) memory tile := get unit memory target(unit) if(memory tile) then( variable(proj) proj := create eyebolt(x for unit(unit), y for unit(unit)) find route(ftile, memory tile, true) moving unit := proj set unit memory target(unit, false) prepend(foes, unit) exit script ) if(can attack line of sight(unit, player)) then( memory tile := max range line of sight target(unit, player) set unit memory target(unit, memory tile) if(memory tile) then( create beam danger shimmers(unit, memory tile) ) exit script ) find route(ftile, ptile) trim array(route, get move range(unit)) moving unit := unit end script, ganderer animate, unit, begin variable(fr) fr := 0 if(can attack line of sight(unit, player)) then( fr := 1 ) set sprite frame(unit, fr) end script, create eyebolt, x, y, begin variable(unit) unit := create unit(unit:eyebolt, x, y) set unit team(unit, team:enemy) replace hero sprite(unit, 30) set move range(unit, 4) set move preview callback(unit, @simple move preview) set animate callback(unit, @eyebolt animate) set unit never saved(unit, true) set unit die after move(unit, true) set unit step speed(unit, second / 8) exit returning(unit) end script, eyebolt animate, unit, begin variable(fr) fr := get sprite frame(unit) fr := loopvar(fr, 0, 3) set sprite frame(unit, fr) end script, create beam danger shimmers, from unit, to tile, begin find route(unit tile(from unit), to tile, true) fetch out(route, 0) for each in array(route, @create danger shimmer) clear array(route) end script, create rustmuncher, x, y, begin variable(unit) unit := create unit(unit:rustmuncher, x, y) set unit team(unit, team:enemy) replace hero sprite(unit, 32) set ai callback(unit, @rustmuncher ai) set move range(unit, 2) set move preview callback(unit, @simple move preview) exit returning(unit) end script, rustmuncher ai, unit, begin variable(ftile, ptile) ftile := unit tile(unit) ptile := unit tile(player) find route(ftile, ptile) trim array(route, get move range(unit)) moving unit := unit end #----------------------------------------------------------------------- script, create random tree, x, y, begin variable(num) num := random(1, 12) exit returning(create generic tree(x, y, num)) end script, valid tree, num, begin if(num >= 1 && num <= 12) then( exit returning(true) ) exit returning(false) end script, create generic tree, x, y, num, begin if(not(valid tree(num))) then( script error(string sprintf(0, $1="create generic tree: %d is not a valid tree id", num)) ) variable(unit) unit := create unit(unit:trees + num, x, y) set unit team(unit, team:decor) replace large enemy sprite(unit, num) set unit inert(unit, true) exit returning(unit) end #----------------------------------------------------------------------- script, simple move preview, unit, begin variable(tile) tile := unit tile(unit) find move range(tile, get move range(unit)) end script, dash move preview, unit, begin variable(tile) tile := unit tile(unit) find dash range(tile, get move range(unit)) end #----------------------------------------------------------------------- script, create unit, id, x, y, begin variable(unit) unit := load hero sprite(0) # sprite set number is changed later variable(tile) tile := get tile at(x, y) if(not(tile)) then( script error(string sprintf(0, $1="Can't create unit at invalid coords %d %d", x, y)) ) set parent(unit, tile) realign slice(unit, edge:center, edge:bottom, edge:center, edge:bottom) set slice lookup(unit, sli:unit) set slice y(unit, unit y offset) add unit metadata(unit) set unit id(unit, id) exit returning(unit) end #----------------------------------------------------------------------- script, tile unit, tile, begin if(not(tile)) then( script error(string sprintf(0, $1="tile is null")) exit returning(0) ) if(get slice lookup(tile) <> sli:tile) then( script error(string sprintf(0, $1="%d is not a tile", tile)) exit returning(0) ) variable(unit) unit := lookup slice(sli:unit, tile) if(unit && get slice lookup(unit) <> sli:unit) then( script error(string sprintf(0, $1="%d is not a unit", unit)) exit returning(0) ) exit returning(unit) end script, unit tile, unit, begin if(get slice lookup(unit) <> sli:unit) then( script error(string sprintf(0, $1="%s is not a unit", unit)) exit returning(0) ) variable(tile) tile := parent slice(unit) if(not(tile)) then( script error(string sprintf(0, $1="unit %s is unparented", unit)) exit returning(0) ) if(get slice lookup(tile) <> sli:tile) then( script error(string sprintf(0, $1="unit %s parent %s is not a tile", unit, tile)) exit returning(0) ) exit returning(tile) end script, move unit to, unit, tile, over ticks, begin variable(tx, ty, ux, uy, dx, dy) tx := slice screen x(tile) ty := slice screen y(tile) + unit y offset ux := slice screen x(unit) uy := slice screen y(unit) dx := tx -- ux dy := ty -- uy move slice to(unit, slice x(unit) + dx, slice y(unit) + dy, over ticks) end script, for each unit, tile, callback, arg2=0, begin # Returns true if at least one callback returns true variable(ch, next ch, result) result := false ch := first child(tile) while(ch) do( next ch := next sibling(ch) if(get slice lookup(ch) == sli:unit) then( if(run script by id(callback, ch, arg2)) then(result := true) ) ch := next ch ) exit returning(result) end script, for each unit around, tile, callback, arg2, arg3, begin variable(i, x, y, ax, ay, atile, aunit) x := x for tile(tile) y := y for tile(tile) for(i, 0, 5) do( ax := x + hex around x(i) ay := y + hex around y(i) atile := get tile at(ax, ay) if(atile) then( aunit := tile unit(atile) if(aunit) then( run script by id(callback, aunit, arg2, arg3) ) ) ) end script, for each unit around unit, unit, callback, arg2, arg3, begin variable(tile) tile := unit tile(unit) if(tile) then( for each unit around(tile, callback, arg2, arg3) ) end script, is foe, unit, begin if(unit == player) then(exit returning(false)) if(get unit inert(unit)) then(exit returning(false)) exit returning(true) end script, step back, unit, begin variable(tile, x, y, back, bx, by, back tile) tile := unit tile(unit) x := x for tile(tile) y := y for tile(tile) back := get last step(unit) bx := x -- hex around x(back) by := y -- hex around y(back) back tile := get tile at(bx, by) clear array(route) append(route, back tile) set unit backwards(unit, true) end script, units are aligned, u1, u2, begin exit returning(tiles are aligned(unit tile(u1), unit tile(u2))) end script, can attack line of sight, attacker, target, begin if(not(target)) then(exit returning(false)) if(not(units are aligned(attacker, target))) then(exit returning(false)) if(hexmanhattan unit distance(attacker, target) > get attack range(attacker)) then(exit returning(false)) exit returning(true) end script, max range line of sight target, attacker, target, begin if(not(units are aligned(attacker, target))) then(exit returning(false)) variable(dir) dir := direction to unit(attacker, target) exit returning(tile ahead(unit tile(attacker), dir, get attack range(attacker))) end script, direction to unit, u1, u2, begin exit returning(direction to tile(unit tile(u1), unit tile(u2))) end script, x for unit, unit, begin variable(tile) tile := unit tile(unit) exit returning(x for tile(tile)) end script, y for unit, unit, begin variable(tile) tile := unit tile(unit) exit returning(y for tile(tile)) end script, same team, u1, u2, begin variable(team1, team2) team1 := get unit team(u1) team2 := get unit team(u2) if(team1 == 0 || team2 == 0) then(exit returning(false)) exit returning(team1 == team2) end #----------------------------------------------------------------------- script, add unit metadata, unit, begin variable(m) m := create container(0, 0) set slice visible(m, false) set slice lookup(m, sli:unit meta) set parent(m, unit) end script, get unit exbit, unit, bit, begin variable(meta, n) meta := lookup slice(sli:unit meta, unit) n := get slice extra(meta, 0) if(n,and,2^bit) then(exit returning(true)) exit returning(false) end script, set unit exbit, unit, bit, value=1, begin variable(meta, n) meta := lookup slice(sli:unit meta, unit) n := get slice extra(meta, 0) if(value) then(n := n, or, 2^bit) else(n := n, and, (-1, xor, 2^bit)) set slice extra(meta, 0, n) end #----------------------------------------------------------------------- # unit meta # extra 0 = bitsets # 0 = unit armored # 1 = backwards # 2 = overheated # 3 = inert # 4 = never saved # 5 = die after move # extra 1 = last step # extra 2 = ai callback # x = move range # y = move preview callback # width = unit id # height = attack range # padding top = unit team # padding right = unit step speed # padding bottom = memory target script, set unit armored, unit, val ( set unit exbit(unit, 0, val) ) script, get unit armored, unit ( exit returning(get unit exbit(unit, 0)) ) script, set unit backwards, unit, val ( set unit exbit(unit, 1, val) ) script, get unit backwards, unit ( exit returning(get unit exbit(unit, 1)) ) script, set unit overheated, unit, val ( set unit exbit(unit, 2, val) ) script, get unit overheated, unit ( exit returning(get unit exbit(unit, 2)) ) script, set unit inert, unit, val ( set unit exbit(unit, 3, val) ) script, get unit inert, unit ( exit returning(get unit exbit(unit, 3)) ) script, set unit never saved, unit, val ( set unit exbit(unit, 4, val) ) script, get unit never saved, unit ( exit returning(get unit exbit(unit, 4)) ) script, set unit die after move, unit, val ( set unit exbit(unit, 5, val) ) script, get unit die after move, unit ( exit returning(get unit exbit(unit, 5)) ) script, set last step, unit, val, begin variable(meta) meta := lookup slice(sli:unit meta, unit) set slice extra(meta, 1, val) end script, get last step, unit, begin variable(meta) meta := lookup slice(sli:unit meta, unit) exit returning(get slice extra(meta, 1)) end script, set ai callback, unit, callback, begin variable(meta) meta := lookup slice(sli:unit meta, unit) set slice extra(meta, 2, callback) end script, run ai callback, unit, arg2=0, arg3=0, begin variable(meta) meta := lookup slice(sli:unit meta, unit) variable(callback) callback := get slice extra(meta, 2) variable(result) if(callback) then( result := run script by id(callback, unit, arg2, arg3) ) exit returning(result) end script, set move range, unit, val, begin variable(meta) meta := lookup slice(sli:unit meta, unit) set slice x(meta, val) end script, get move range, unit, begin variable(meta) meta := lookup slice(sli:unit meta, unit) exit returning(slice x(meta)) end script, set move preview callback, unit, callback, begin variable(meta) meta := lookup slice(sli:unit meta, unit) set slice y(meta, callback) end script, get move preview callback, unit, begin variable(meta) meta := lookup slice(sli:unit meta, unit) exit returning(slice y(meta)) end script, run move preview callback, unit, arg2=0, arg3=0, begin variable(meta) meta := lookup slice(sli:unit meta, unit) variable(callback) callback := slice y(meta) variable(result) if(callback) then( result := run script by id(callback, unit, arg2, arg3) )else( script error(string sprintf(0, $1="unit %d has no move preview callback", unit)) ) exit returning(result) end script, set unit id, unit, val, begin variable(meta) meta := lookup slice(sli:unit meta, unit) set slice width(meta, val) end script, get unit id, unit, begin variable(meta) meta := lookup slice(sli:unit meta, unit) exit returning(slice width(meta)) end script, set attack range, unit, val, begin variable(meta) meta := lookup slice(sli:unit meta, unit) set slice height(meta, val) end script, get attack range, unit, begin variable(meta) meta := lookup slice(sli:unit meta, unit) exit returning(slice height(meta)) end script, set unit team, unit, val, begin variable(meta) meta := lookup slice(sli:unit meta, unit) set top padding(meta, val) end script, get unit team, unit, begin variable(meta) meta := lookup slice(sli:unit meta, unit) exit returning(get top padding(meta)) end script, set unit step speed, unit, val, begin variable(meta) meta := lookup slice(sli:unit meta, unit) set right padding(meta, val) end script, get unit step speed, unit, begin variable(meta, val) meta := lookup slice(sli:unit meta, unit) val := get right padding(meta) if(val == 0) then(exit returning(second / 4)) exit returning(val) end script, set unit memory target, unit, val, begin variable(meta) meta := lookup slice(sli:unit meta, unit) set bottom padding(meta, val) end script, get unit memory target, unit, begin variable(meta) meta := lookup slice(sli:unit meta, unit) exit returning(get bottom padding(meta)) end