include, plotscr.hsd include, scancode.hsi include, devwaffles.hsi #----------------------------------------------------------------------- define constant(true, default demo mode) global variable(100, play mode) global variable(101, falling) global variable(102, playbox) global variable(103, falltick) global variable(104, ticks) global variable(105, blockbox) global variable(106, since waffle) global variable(107, since butter) global variable(108, since syrup) global variable(109, effect layer) global variable(110, touch x) global variable(111, touch y) global variable(112, swipe drop ticks) global variable(113, last click tick) global variable(114, removal array) global variable(115, dev moved) global variable(116, path) global variable(117, spatula toggle) global variable(118, any dev moved this round) global variable(119, punched this round) global variable(120, puncher) global variable(121, debug enabled) global variable(122, push up) global variable(123, push up threshold) global variable(124, main col) global variable(125, tutorial) global variable(126, keyboard drop) global variable(127, break loop) global variable(128, saved save version) global variable(129, game over flag) global variable(130, last shape) global variable(131, watched intro) global variable(132, skipped intro) global variable(133, peril) global variable(134, cached dev array) global variable(135, explained toaster) global variable(136, demo mode) global variable(137, banner col) global variable(138, banner gravity) global variable(500, stats array) global variable(999, tcache dirty) global variable(1000, tcache) global variable(2000, acache) global variable(3000, bcache) global variable(4000, reactions) define constant(30, second) define constant(9, lastcol) define constant(15, lastrow) define constant(20, tilesize) define constant(10, touch move threshold) define constant(10, swipe down threshold) define constant(1, current save version) define constant(25, banner delay) define constant(0, mode:new block) define constant(1, mode:player) define constant(2, mode:placement) define constant(3, mode:dev) define constant(4, mode:punch) define constant(5, mode:afterpunch) define constant(6, mode:push up) define constant(0, kind:none) define constant(1, kind:waffle) define constant(2, kind:butter) define constant(3, kind:syrup) define constant(4, kind:buttered waffle) define constant(5, kind:completed waffle) define constant(6, kind:syruped waffle) define constant(100, kind:dev) define constant(106, kind:lastdev) define constant(0, bit:jump) define constant(1, bit:chomp) # 3-tile blocks define constant(1, shape:corner) define constant(2, shape:crowbar) define constant(3, shape:crowbar2) define constant(4, shape:caret) define constant(5, shape:3bar) define constant(6, shape:steps) # 4-tile blocks define constant(7, shape:square) define constant(8, shape:4bar) define constant(9, shape:J) define constant(10, shape:L) define constant(11, shape:Z) define constant(12, shape:S) define constant(13, shape:hat) define constant(1, first shape) define constant(6, last 3 shape) define constant(13, last 4 shape) define constant(0, stats:spatulas) define constant(1, stats:customer waffles) define constant(2, stats:dev total waffles) define constant(3, stats:devs) #3-9 define constant(9, last stat) define constant(0, slicol:main screen) define constant(1, slicol:alert) define constant(2, slicol:intro) define constant(3, slicol:gizsez) define constant(4, slicol:title) define constant(5, slicol:skipintro) define constant(6, slicol:banners) #----------------------------------------------------------------------- plotscript, new game, begin demo mode := default demo mode start demo timer play song(1) verify saves suspend player init mouse unhide mouse cursor title screen intro sequence init game stuff main loop end plotscript, load game, begin demo mode := default demo mode start demo timer hide banner play song(3) suspend player init mouse unhide mouse cursor free slice children(effect layer) play sound(5) tcache dirty := true main loop end script, init game stuff, begin last shape := last 3 shape init removal array init path play mode := mode:placement main col := load slice collection(slicol:main screen) playbox := lookup slice(sli:playbox) blockbox := lookup slice(sli:blockbox) effect layer := lookup slice(sli:effect layer) tcache dirty := true push up threshold := 11 push up := 0 init statistics if(skipped intro) then( after tutorial init )else( tutorial init ) resume timers ticks := 0 end script, create devs, begin variable(i, tx, ty, tile) for(i, 0, 6) do( while(true) do( tx := random(0, lastcol) ty := random(0, lastrow) tile := tile at pos(tx, ty) if(not(tile)) then( create tile(playbox, kind:dev+i, tx, ty, true) break ) ) ) end script, main loop, begin while(true) do( #show value(play mode) if(keyval(key:ESC) > 1) then( save game now play sound(6) reset game ) banner input check for game over if(keyval(key:pause) > 1) then( giz sez($0="Trying to PAUSE the game now? Sounds like you are just loafing around. Get back to work!") ) if(keyval(key:tilde) > 1) then( debug enabled := not(debug enabled) if(not(debug enabled)) then(show no value) ) switch(play mode) do( case(mode:new block) do( new block mode ) case(mode:player) do( update player mode ) case(mode:placement) do( update placement mode ) case(mode:dev) do( dev move mode ) case(mode:punch) do( dev punch mode ) case(mode:afterpunch) do( dev step after punch ) case(mode:push up) do( push up mode ) ) swipe drop ticks -= sign(swipe drop ticks) update effects do queued removals if(debug enabled) then( show string(string sprintf(0, $1="mode=%d", play mode)) ) wait(1) ticks += 1 ) end script, check for fatal peril, begin if(peril) then( variable(tile) tile := first child(playbox) while(tile) do( if(tile y(tile) < 0) then( game over flag := true ) tile := next sibling(tile) ) peril := false ) end script, check for game over, begin if(game over flag) then( giz sez($0="SLIME IT ALL! That's it! You Devs have messed up for the last time!") giz sez($0="Get out of my kitchen, all of you! YOU ARE ALL FIRED! GAME OVER!") delete save(1) variable(tile) while(child count(playbox) > 0) do( tile := first child(playbox) splash effect at(tile) queue for removal(tile) update effects do queued removals wait(1) ticks += 1 ) fade screen out(63, 0, 0) reset game ) end script, verify saves, begin if(save slot used(1)) then( if(import globals(1, @saved save version) <> current save version) then( # Invalidate save game of wrong save version delete save(1) ) ) end script, save game now, begin saved save version := current save version save in slot(1) end #----------------------------------------------------------------------- # TUTORIAL script, tutorial init, begin tutorial := 1 variable(tx, tile, prev) for(tx, 0, lastcol) do( switch(tx) do( case(0, 1, 2, 6, 7, 8) tile := create tile(playbox, kind:waffle, tx, lastrow) case(else) tile := 0 ) if(prev) then( connect waffles(tile, prev) ) prev := tile ) end script, next tutor, n, begin tutorial := n ticks := 0 end script, tutorial mode, begin switch(tutorial) do( case(1) if(ticks < second / 2) then( keyboard drop := true )else( keyboard drop := false ) if(ticks > second * 3 / 2) then( giz sez($0="Blocks of waffles, syrup, and butter fall from above.") next tutor(2) ) case(2) if(ticks > second) then( if(running on mobile) then( giz sez($0="Swipe left and right to move the falling blocks") )else( giz sez($0="Press left and right arrow keys to move the falling blocks") ) next tutor(3) ) case(3) if(ticks > second * 2) then( next tutor(4) )else if(ticks > second) then( if(ticks ,mod, (second / 4) == 0) then( try block move(falling, -1) ) )else( if(ticks ,mod, (second / 4) == 0) then( try block move(falling, 1) ) ) case(4) if(running on mobile) then( giz sez($0="Swipe down to drop the falling block quickly") )else( giz sez($0="Hold the down arrow key to drop the falling block quickly") ) next tutor(5) case(5) if(ticks > second / 3) then( keyboard drop := true ) if(ticks > second * 11 / 6) then( keyboard drop := false next tutor(6) ) case(6) if(ticks > second) then( if(running on mobile) then( giz sez($0="Double-tap or two-finger tap to rotate the block") )else( giz sez($0="Press the up arrow to rotate the block.") ) next tutor(7) ) case(7) if(ticks > second / 4) then( if(ticks ,mod, (second / 4) == 0) then( rotate right(falling) ) ) if(ticks > second * 2) then( giz sez($0="Put butter and syrup together with the waffles.") next tutor(8) ) case(8) if(ticks > second / 4) then( next tutor(9) ) case(9) if(ticks > second / 4) then( keyboard drop := true ) if(ticks > second * 3 / 2) then( keyboard drop := false giz sez($0="Waffles ain't fit to eat unless they are slathered in BOTH butter and syrup.") next tutor(10) ) case(10) if(ticks > second * 2) then( try block move(falling, -1) next tutor(11) ) case(11) if(ticks < second * 2) then( keyboard drop := true )else( keyboard drop := false giz sez($0="Yeah, One or two of those waffles might be fit to eat now.") next tutor(12) ) case(12) if(ticks > second) then( giz sez($0="Complete a full row to summon my spatula and serve the waffles to the customers.") rotate right(falling) next tutor(13) ) case(13) if(ticks > second) then( next tutor(14) ) case(14) if(ticks < second * 4 / 3) then( if(ticks ,mod, (second / 4) == 0) then( try block move(falling, 1) ) )else( next tutor(15) ) case(15) if(ticks < second * 2) then( keyboard drop := true )else( keyboard drop := false giz sez($0="NOW WORK HARD! MAKE ME PROUD!") next tutor(16) ) case(16) if(ticks > second / 8) then( next tutor(17) ) case(17) next tutor(0) after tutorial init ) end script, giz sez, str id, begin play sound(3) variable(col, box, pic, txt, i, fr) col := load slice collection(slicol:gizsez) box := lookup slice(sli:gizsez box, col) pic := lookup slice(sli:gizsez pic, col) txt := lookup slice(sli:gizsez text, col) set slice text(txt, str id) for(i, 0, 180, 20) do( set slice width(box, i) set slice height(box, i) wait(1) ) while(true) do( if((i / 2) ,mod, 2 == 0) then( fr += 1 if(fr > 3) then(fr := 0) ) set sprite set number(pic, 2 + fr) if(mouse click(left button)) then(break) if(keyval(key:space) > 1) then(break) if(keyval(key:enter) > 1) then(break) wait(1) i += 1 ) play sound(5) for(i, 180, 0, -20) do( set slice width(box, i) set slice height(box, i) wait(1) ) free slice(col) end script, after tutorial init, begin fade screen out wait(1) if(falling) then( free slice(falling) falling := 0 ) free slice children(effect layer) free slice children(playbox) create random rows(7, kind:waffle) create devs tcache dirty := true push up threshold := 11 push up := 0 init statistics play mode := mode:placement watched intro := true export globals(30, @watched intro, @watched intro) wait(1) play song(3) fade screen in end #----------------------------------------------------------------------- # TITLE SCREEN script, title screen, begin variable(col, newbut, contbut, cur, loop done) col := load slice collection(slicol:title) newbut := lookup slice(sli:new game button, col) contbut := lookup slice(sli:continue button, col) set button action(newbut, @new button action) set button action(contbut, @continue button action) if(save slot used(1)) then( cur := contbut )else( cur := newbut disable button(contbut) ) defocus button(newbut) defocus button(contbut) break loop := false while(not(break loop)) do( if(keyval(key:esc) > 1) then(play sound(6), game over) banner input if(keyval(key:right) > 1) then( defocus button(cur) cur := contbut ) if(keyval(key:left) > 1) then( defocus button(cur) cur := newbut ) if(keyval(key:space) > 1 || keyval(key:enter) > 1) then( do button action(cur) ) check for button click(newbut) check for button click(contbut) highlight button(cur) wait(1) ticks += 1 ) break loop := false free slice(col) end script, new button action, button, begin break loop := true end script, continue button action, button, begin load from slot(1) end script, check for button click, button, begin if(slice collide point(button, mouse pixel x, mouse pixel y)) then( if(mouse click(left button)) then( exit returning(do button action(button)) ) ) exit returning(false) end script, do button action, button, begin variable(callback, disabled) callback := get slice extra(button, 0) disabled := get slice extra(button, 1) if(not(disabled)) then( play sound(5) if(callback) then( run script by id(callback, button) ) exit returning(true) )else( play sound(6) ) exit returning(false) end script, set button action, button, callback, begin set slice extra(button, 0, callback) end script, disable button, button, begin set slice extra(button, 1, true) end script, highlight button, button, begin variable(box, text, disabled) box := lookup slice(sli:button box, button) text := lookup slice(sli:button text, button) disabled := get slice extra(button, 1) if((ticks / 4) ,mod, 2 == 0) then( set rect fgcol(box, 15) )else( set rect fgcol(box, 9) ) if(not(disabled)) then( set rect fuzziness(box, 100) set rect bgcol(box, 36) if(((ticks + 1) / 4) ,mod, 2 == 0) then( set text color(text, 0) )else( set text color(text, 14) ) ) end script, defocus button, button, begin variable(box, text, disabled) box := lookup slice(sli:button box, button) text := lookup slice(sli:button text, button) disabled := get slice extra(button, 1) set rect fgcol(box, 30) if(disabled) then( set rect fuzziness(box, 25) set rect bgcol(box, 16) set text color(text, 1) )else( set rect fuzziness(button, 100) set rect bgcol(box, 35) set text color(text, 0) ) end #----------------------------------------------------------------------- # INTRO #0 Giz #1 Bob #2 TMC #3 Spoonweaver #4 Marionline #5 Ichiro #6 Feenicks #7 BMR script, intro sequence, begin hide banner suspend timers skipped intro := false if(skip intro) then( skipped intro := true exit script ) variable(col, txt) if(main col) then(set slice visible(main col, false)) teleport to map(1, 0, 0) col := load slice collection(slicol:intro) clear intro text variable(who) for(who, 0, 7) do( init intro npc(who) ) skippable wait(second / 2) npc say(1, $0="Bob the Hamster: I am so hungry!") npc say(7, $0="BMR: I am hungry also!") npc say(3, $0="Spoonweaver: But we are indie game developers!") npc say(6, $0="Feenicks: Yeah, Indie game developers can't afford to buy food!") npc say(2, $0="TMC: We must starve for our art!") npc say(4, $0="Marionline: I am so cold! This basement is freezing!") npc say(5, $0="Ichiro: So hungry... So cold... Our games unfinished...") walk npc(0, left, 2) wait for npc(0) npc say(0, $0="Gizmog: LISTEN UP, CHUMPS!") skippable wait(second / 4) for(who, 1, 7) do( flip npc(who) ) skippable wait(second / 4) npc say(1, $0="Bob the Hamster: Oh my gosh! It's The Gizmog!") npc hop(0) npc say(0, $0="Gizmog: YOU DEVS NEED TO PAY ATTENTION!") npc hop(0) npc say(0, $0="Gizmog: MAKING GAMES IS FOR SUCKERS! STOP BEING LAZY SLIMES AND GO GET A JOB!") skippable wait(second / 4) npc say(5, $0="Ichiro: A Job? But How?") npc say(7, $0="BMR: As indie game developers we have absolutely no other marketable skills whatsoever!") npc hop(0) npc say(0, $0="Gizmog: YOU CAN WORK AT MY RESTAURANT.") npc hop(0) npc say(0, $0="Gizmog: SERVE WAFFLES TO MY CUSTOMERS, AND EARN AN HONEST LIVING.") skippable wait(second / 4) npc hop(4) npc say(4, $0="Marionline: Yes! We can do that!") npc say(2, $0="TMC: Giz has shown us the light! Lets follow him!") npc say(3, $0="Spoonweaver: Yeah! Making games is for chumps! We are waffle chefs now!") npc say(6, $0="Feenicks: Waffles! Waffles! Waffles!") flip npc(0) walk all npcs off screen free slice(col) teleport to map(0, 0, 0) if(main col) then(set slice visible(main col, true)) end script, skip intro, begin if(not(import globals(30, @watched intro))) then(exit returning(false)) variable(col, playbut, skipbut, cur, loop done, result) col := load slice collection(slicol:skipintro) playbut := lookup slice(sli:playintro button, col) skipbut := lookup slice(sli:skipintro button, col) cur := skipbut defocus button(playbut) defocus button(skipbut) while(true) do( if(keyval(key:esc) > 1) then(play sound(6), reset game) if(keyval(key:up) > 1) then( defocus button(cur) cur := playbut ) if(keyval(key:down) > 1) then( defocus button(cur) cur := skipbut ) if(keyval(key:space) > 1 || keyval(key:enter) > 1) then( play sound(5) if(cur == playbut) then(result := false, break) if(cur == skipbut) then(result := true, break) ) if(check for button click(playbut)) then(result := false, break) if(check for button click(skipbut)) then(result := true, break) highlight button(cur) wait(1) ticks += 1 ) free slice(col) exit returning(result) end script, walk all npcs off screen, begin variable(who) for(who, 1, 6) do( walk npc(who, down, 1) set npc fr(who, 4) ) wait(5) for(who, 0, 7) do( walk npc(who, right, 1) set npc fr(who, 0) ) walking wait(5, 1, 7) end script, init intro npc, who, begin variable(sl, pic, pic id) sl := get npc slice(who) pic := lookup slice(sl:walkabout sprite component, sl) set slice visible(pic, false) if(who == 0) then( # Gizmog pic := load large enemy sprite(2) set slice y(pic, 18) set slice x(pic, -2) )else( pic id := get sprite set number(pic) pic := load walkabout sprite(pic id) ) set parent(pic, sl) realign slice(pic, edge:center, edge:bottom, edge:center, edge:bottom) set slice lookup(pic, sli:intro npc pic) flip npc(who) set npc fr(who, 0) end script, clear intro text, begin variable(txt) txt := lookup slice(sli:intro text, sprite layer) set slice text(txt, $0="") end script, npc say, who, str id, begin variable(txt, talk, fr) txt := lookup slice(sli:intro text, sprite layer) set slice text(txt, 0) if(who == 0) then( play sound(3) )else( play sound(8) ) while(true) do( talk += 1 if(talk >= second / 2) then( talk := 0 ) if(who == 0) then( # Giz if(talk ,mod, (second / 4) == 0) then( fr += 1 if(fr >= 4) then(fr := 0) ) set npc fr(who, fr) )else( # Other Devs fr := 1 if(talk > second / 4) then(fr := 2) set npc fr(who, fr) ) wait(1) if(mouse click(left button)) then(break) if(keyval(key:space) > 1) then(break) if(keyval(key:enter) > 1) then(break) ) set npc fr(who, 0) clear intro text wait(1) end script, npc hop, who, begin variable(sl, pic, y, i) sl := get npc slice(who) pic := lookup slice(sli:intro npc pic, sl) y := slice y(pic) for(i, 0, second / 8) do( set slice y(pic, slice y(pic) -- 1) wait(1) ) for(i, 0, second / 8) do( set slice y(pic, slice y(pic) + 1) wait(1) ) set slice y(pic, y) end script, flip npc, who, begin variable(sl, pic) sl := get npc slice(who) pic := lookup slice(sli:intro npc pic, sl) horiz flip sprite(pic, not(sprite is horiz flipped(pic))) end script, set npc fr, who, fr, begin variable(sl, pic) sl := get npc slice(who) pic := lookup slice(sli:intro npc pic, sl) if(who == 0) then( set sprite set number(pic, 2 + fr) )else( set sprite frame(pic, fr) ) end script, walking wait, t, first npc, last npc, begin variable(i, who) for(i, 0, t -- 1) do( for(who, first npc, last npc) do( set npc fr(who, 0 + (ticks / 2) ,mod, 2) ) wait(1) ticks += 1 ) end script, skippable wait, t, begin wait(1) variable(i) for(i, 0, t -- 2) do( if(mouse click(left button)) then(break) if(keyval(key:space) > 1) then(break) if(keyval(key:enter) > 1) then(break) wait(1) ) end script, wait for click, begin while(mouse button(left button)) do( # First wait for any old press to be released wait(1) ) while(true) do( # Wait for a new click if(mouse click(left button)) then(break) if(keyval(key:space) > 1) then(break) if(keyval(key:enter) > 1) then(break) wait(1) ) # wait one more tick wait(1) end #----------------------------------------------------------------------- # NEW BLOCK MODE script, new block mode, begin animate all devs check for fatal peril drop next block punched this round := false play mode := mode:player if(tutorial == 0) then( save game now ) end #----------------------------------------------------------------------- # PUSH UP MODE script, push up mode, begin push up += 1 if(push up == push up threshold) then( create push up warning effect if(not(explained toaster)) then( giz sez($0="The toasters glow to let you know when more waffles are about to push up from the bottom.") explained toaster := true ) ) if(push up > push up threshold) then( push up := 0 create new bottom row push tiles up playmode := mode:placement exit script ) play mode := mode:new block end script, create new bottom row, begin variable(tx, ty, tile, ox, other, never, last tile) never := random(0, lastcol) ty := lastrow + 1 for(tx, 0, lastcol) do( if(random percent(70) && tx <> never) then( tile := create tile(playbox, kind:waffle, tx, ty) for(ox, large(0, tx -- 1), small(lastcol, tx + 1)) do( other := tile at pos(ox, ty -- 1) connect waffles(tile, other) ) connect waffles(tile, last tile) last tile := tile )else( last tile := 0 ) ) end script, connect waffles, tile, other, begin variable(kind) if(tile && other) then( kind := get kind(other) if(kind == kind:waffle || kind == kind:buttered waffle || kind == kind:syruped waffle || kind == kind:completed waffle) then( add tile connection(tile, other) add tile connection(other, tile) ) ) end script, push tiles up, begin variable(tile) tile := first child(playbox) while(tile) do( move tile up(tile) tile := next sibling(tile) ) end script, move tile up, tile, interval=-1, begin variable(ty) ty := tile y(tile) -- 1 set tile y(tile, ty) animate rising tile(tile, interval) end #----------------------------------------------------------------------- # PLAYER MODE script, update player mode, begin if(clear all jumped) then( play mode := mode:placement exit script ) falltick += 1 if(tutorial > 0) then( tutorial mode )else( mouse controls if(keyval(key:up) > 1 || keyval(key:period) > 1) then(rotate right(falling)) if(keyval(key:comma) > 1) then(rotate left(falling)) if(keyval(key:left) > 1) then(try block move(falling, -1)) if(keyval(key:right) > 1) then(try block move(falling, 1)) if(keyval(key:down) > 0) then(keyboard drop := true) else(keyboard drop := false) ) if(falling && falltick >= falling interval) then( falltick := 0 if(check for block collision(falling, 0, 1) || child count(falling) == 0) then( play sound(1) place block(falling) free slice(falling) falling := 0 play mode := mode:placement )else( move block down(falling) ) ) end script, mouse controls, begin if(mouse click(left button)) then( touch x := mouse pixel x touch y := mouse pixel y if(ticks -- last click tick < second / 3) then( rotate left(falling) ) last click tick := ticks ) if(mouse button(left button)) then( variable(drag x, drag y) drag x := mouse pixel x -- touch x drag y := mouse pixel y -- touch y if(drag y >= swipe down threshold) then( swipe drop ticks := second * 2 touch x := mouse pixel x touch y := mouse pixel y )else if(drag y > touch move threshold) then( touch x := mouse pixel x touch y := mouse pixel y ) if(abs(drag x) >= touch move threshold && drag y < touch move threshold && swipe drop ticks == 0) then( try block move(falling, sign(drag x)) touch x := mouse pixel x touch y := mouse pixel y exit script ) if(drag y < -1 * touch move threshold) then( swipe drop ticks := 0 touch x := mouse pixel x touch y := mouse pixel y ) )else( swipe drop ticks := 0 ) if(mouse click(right button)) then( rotate right(falling) ) end script, falling interval, begin if(keyboard drop || swipe drop ticks > 0) then( exit returning(second / 8) ) exit returning(second) end script, check for block collision, block, xgo, ygo, begin variable(tile) tile := first child(block) while(tile) do( if(check for block tile collision(tile, xgo, ygo)) then( exit returning(true) ) tile := next sibling(tile) ) exit returning(false) end script, try block move, block, xgo, begin variable(tile) tile := first child(block) while(tile) do( if(check for block tile collision(tile, xgo, 0)) then( exit returning(false) ) tile := next sibling(tile) ) set tile x(block, tile x(block) + xgo) animate sideways block(block, xgo) play sound(0) exit returning(true) end #----------------------------------------------------------------------- # DEV MODE script, tile is dev, tile, begin exit returning(kind is dev(get kind(tile))) end script, kind is dev, kind, begin if(kind >= kind:dev && kind <= kind:lastdev) then( exit returning(true) ) exit returning(false) end script, dev move mode, begin if(any tiles moving) then( animate all devs dev moved := true exit script ) if(dev moved) then( dev moved := false play mode := mode:placement exit script ) variable(dev array, node, dev, moved) moved := false dev array := get dev array node := first child(dev array) while(node) do( dev := get slice extra(node, 0) if(dev seeks waffle(dev)) then( moved := true any dev moved this round := true ) node := next sibling(node) ) if(not(moved)) then( if(not(any dev moved this round) && not(punched this round)) then( play mode := mode:punch exit script ) any dev moved this round := false play mode := mode:push up ) end script, animate all devs, begin variable(dev array, node, dev) dev array := get dev array node := first child(dev array) while(node) do( dev := get slice extra(node, 0) animate dev(dev) node := next sibling(node) ) end script, animate dev, dev, begin variable(pic, dist) pic := lookup slice(sli:tile pic, dev) if(get exbit(dev, bit:chomp)) then( dist := abs(slice x(pic)) + abs(slice y(pic)) if(dist >= tilesize / 2) then( set sprite frame(pic, 2) )else if(dist > 0)then( set sprite frame(pic, 3) )else( set sprite frame(pic, 0) set exbit(dev, bit:chomp, false) ) exit script ) if(get exbit(dev, bit:jump)) then( set sprite frame(pic, 4) exit script ) if(slice is moving(pic)) then( loop frame(pic, 0, 1, second / 8) exit script ) set sprite frame(pic, 0) end script, dev seeks waffle, dev, begin # Returns true if dev can see a waffle and tries to move towards it if(find path to waffle(dev)) then( if(dev walk(dev)) then( exit returning(true) ) ) exit returning(false) end script, init path, begin path := create container(0, 0) set slice visible(path, false) set slice lookup(path, sli:path holder) end script, clear path, p, begin free slice children(p) end script, append to path, p, tx, ty, begin variable(n) n := create container(0, 0) set parent(n, p) set slice x(n, tx) set slice y(n, ty) end script, find path to waffle, dev, begin # Store route to waffle location in path variable # Return true if a path was actually found variable(tx, ty, tile, d_i, d, kind, near, just jumped, start point) #trace(string sprintf(0, $1="find path to waffle %d %d", tile x(dev), tile y(dev))) for(d_i, 0, 1) do( if(d_i == 0) then( d := get tile direction(dev) )else( d := d * -1 ) #trace(string sprintf(0, $1="d=%d", d)) clear path(path) tx := tile x(dev) ty := tile y(dev) start point := true just jumped := get exbit(dev, bit:jump) while(true) do( #trace(string sprintf(0, $1="j=%d tx=%d ty=%d", just jumped, tx, ty)) tile := tile at pos(tx, ty) kind := get kind(tile) if(start point) then( # starting tile start point := false )else if(not(tile)) then( # empty space, add it to the path append to path(path, tx, ty) )else if(kind == kind:completed waffle) then( append to path(path, tx, ty) exit returning(true) ) # Check to see if we should fall down if(not(just jumped) && ty < lastrow) then( # Falling is possible near := tile at pos(tx, ty + 1) if(not(near) || get kind(near) == kind:completed waffle) then( # Space is empty ty += 1 just jumped := false continue ) ) # Check to see if we should jump straight up to eat if(not(just jumped)) then( near := tile at pos(tx, ty + 1) if(ty == last row || near) then( # Standing on something solid near := tile at pos(tx, ty -- 1) if(near && get kind(near) == kind:completed waffle) then( ty -= 1 just jumped := true continue ) ) ) # Horizontal checks if(tx + d >= 0 && tx + d <= lastcol) then( # Check directly ahead near := tile at pos(tx + d, ty) if(not(near) || get kind(near) == kind:completed waffle) then( tx += d just jumped := false continue ) # Check to see if we can jump up if(not(just jumped)) then( near := tile at pos(tx, ty -- 1) if(not(near)) then( near := tile at pos(tx + d, ty -- 1) if(not(near) || get kind(near) == kind:completed waffle) then( ty -= 1 just jumped := true continue ) ) ) ) # Did not find any waffles or empty spaces break ) # end of the pathfinding loop ) # end of the loop for each direction #trace($0="--not found") clear path(path) set exbit(dev, bit:jump, false) exit returning(false) end script, dev walk, dev, begin # Returns true if the walk happens # Assumes that path variable just populated with the route to the waffle #script error($0="examine path") if(child count(path) == 0) then( script error(string sprintf(0, $1="dev walk: empty waffle path %d %d", tile x(dev), tile y(dev))) ) #create path debug effects(path) variable(node, bx, by, tx, ty, xd, yd, tile, speed) node := first child(path) bx := tile x(dev) by := tile y(dev) xd := slice x(node) -- bx yd := slice y(node) -- by if(xd == 0 && yd == 0) then( # Nothing to do show string(string sprintf(0, $1="dev walk: nothing to do")) exit returning(false) ) if(abs(xd) > 1 || abs(yd) > 1) then( script error(string sprintf(0, $1="dev walk: overlarge move %d %d", xd, yd)) exit returning(false) ) if(yd < 0) then( # Jumping set exbit(dev, bit:jump, true) cancel nearby jumps(dev) )else( # Not jumping set exbit(dev, bit:jump, false) ) tx := bx + xd ty := by + yd tile := tile at pos(tx, ty) speed := second / 4 if(tile && get kind(tile) == kind:completed waffle) then( create tile dissolve effect(tile, dissolve:vapourise) splash effect at(tile) queue for removal(tile) set exbit(dev, bit:chomp) speed := second / 2 count dev waffle(dev) play sound(4) ) if(xd <> 0) then( set tile direction(dev, xd) ) set tile x(dev, tx) set tile y(dev, ty) variable(pic) pic := lookup slice(sli:tile pic, dev) set slice x(pic, tilesize * xd * -1) set slice y(pic, tilesize * yd * -1) move slice to(pic, 0, 0, speed) exit returning(true) end script, get tile direction, tile, begin variable(pic) pic := lookup slice(sli:tile pic, tile) if(sprite is horiz flipped(pic)) then( exit returning(-1) ) exit returning(1) end script, set tile direction, tile, d, begin variable(pic) pic := lookup slice(sli:tile pic, tile) horiz flip sprite(pic, d < 0) end script, cancel nearby jumps, dev, begin variable(tx, ty, ox, oy, other, near) tx := tile x(dev) ty := tile y(dev) for(oy, ty -- 1, ty + 1) do( for(ox, tx -- 1, ty + 1) do( if(ox >= 0 && ox <= lastcol && oy >= 0 && oy <= lastrow) then( if(ox <> tx) then( other := tile at pos(ox, oy) if(other && tile is dev(other)) then( set exbit(other, bit:jump, false) near := tile at pos(ox, oy) if(oy < lastrow && not(near)) then( move tile down(other, second / 4) ) ) ) ) ) ) end script, clear all jumped, begin # Returns true if there were actually any jumpers to clear variable(dev array, node, dev, result, near, tx, ty) result := false dev array := get dev array node := first child(dev array) while(node) do( dev := get slice extra(node, 0) tx := tile x(dev) ty := tile y(dev) near := tile at pos(tx, ty + 1) if(ty < lastrow && not(near)) then( result := true ) set exbit(dev, bit:jump, false) node := next sibling(node) ) animate all devs exit returning(result) end #----------------------------------------------------------------------- # DEV PUNCH MODE script, dev punch mode, begin if(any tiles moving) then( animate all devs exit script ) puncher := none variable(dev array, node, dev) dev array := get dev array shuffle array(dev array) # Try to find a dev who can punch something node := first child(dev array) while(node) do( dev := get slice extra(node, 0) if(try to make dev punch(dev)) then( puncher := dev break ) node := next sibling(node) ) punched this round := true play mode := mode:afterpunch ) script, dev step after punch, begin if(any tiles moving) then( animate all devs exit script ) if(puncher) then( move tile over(puncher, get tile direction(puncher), second / 8) play mode := mode:placement )else( play mode := mode:placement ) end script, try to make dev punch, dev, begin variable(near, d, i, tx, ty, pic) d := get tile direction(dev) tx := tile x(dev) ty := tile y(dev) if(burried(tx, ty)) then( for(i, 0, 1) do( if(i == 1) then(d := d * -1) near := tile at pos(tx + d, ty) if(near) then( if(not(tile is dev(near))) then( # Punch! set tile direction(dev, d) pic := lookup slice(sli:tile pic, dev) set slice x(pic, tilesize / 2 * d) move slice to(pic, 0, 0, second / 4) create punch effect(near, d) queue for removal(near) exit returning(true) ) ) ) ) exit returning(false) end script, burried, tx, ty, begin variable(count, i, ny) for(i, 0, 3) do( ny := ty -- 1 -- i if(tile at pos(tx, ny)) then(count += 1) ) exit returning(count >= 3) end script, get dev array, begin if(cached dev array) then( if(child count(cached dev array) == 7) then( exit returning(cached dev array) ) ) variable(array, node) array := create container(0, 0) set slice lookup(array, sli:dev array) set slice visible(array, false) variable(tile) tile := first child(playbox) while(tile) do( if(tile is dev(tile)) then( node := create container(0, 0) set parent(node, array) set slice extra(node, 0, tile) ) tile := next sibling(tile) ) cached dev array := array exit returning(array) end script, shuffle array, array, begin variable(node) node := first child(array) while(node) do( set sort order(node, random(0, 10000000)) node := next sibling(node) ) sort children(array) end #----------------------------------------------------------------------- # PLACEMENT MODE script, update placement mode, begin if(not(any tiles moving)) then( check for all tile merges if(not(check for unsupported tiles)) then( if(not(check for spatula rows)) then( play mode := mode:dev ) ) ) end script, any tiles moving, begin variable(tile, pic) tile := first child(playbox) while(tile) do( pic := lookup slice(sli:tile pic, tile) if(slice is moving(pic)) then(exit returning(true)) tile := next sibling(tile) ) if(any blocking effects) then(exit returning(true)) exit returning(false) end script, check for unsupported tiles, begin # Return true if any unsupported tiles exist (and are now falling) # Or false if nothing is unsupported clear support flags variable(tile, tx, ty, other) # First check for directly supported tiles tile := first child(playbox) while(tile) do( ty := tile y(tile) if(ty == lastrow) then( set slice extra(tile, 1, true) ) tile := next sibling(tile) ) variable(found, d) while(true) do( # Check for connected tiles in multiple passes. # The passes stop when no more connected/supported tiles are found found := false tile := first child(playbox) while(tile) do( # First check for support underneath if(get slice extra(tile, 1) == false) then( if(check for tile collision(tile, 0, 1, true)) then( other := tile at pos(tile x(tile), tile y(tile) + 1) if(other) then( if(get slice extra(other, 1)) then( set slice extra(tile, 1, true) found := true ) ) ) ) # Then check for support by attachment if(get slice extra(tile, 1) == false) then( for(d, 0, 7) do( if(supported in direction(tile, d)) then( set slice extra(tile, 1, true) found := true ) ) ) tile := next sibling(tile) ) if(not(found)) then( break ) ) variable(result) result := false tile := first child(playbox) while(tile) do( if(not(get slice extra(tile, 1)) && not(get exbit(tile, bit:jump))) then( # Unsupported, fall! move tile down(tile, second / 4) #create debug effect at tile(tile) result := true ) tile := next sibling(tile) ) exit returning(result) end script, supported in direction, tile, d, begin variable(kind, edge set, corner set, set, fr) kind := get kind(tile) edge set := sprite set for kind(kind, 0) corner set := sprite set for kind(kind, 1) variable(overlay) overlay := lookup slice(sli:overlay, tile) variable(pic) pic := first child(overlay) while(pic) do( set := get sprite set number(pic) fr := get sprite frame(pic) if(d == 0 && set == corner set && fr == 0) then( exit returning(supported at offset(tile, -1, -1)) ) if(d == 1 && set == edge set && fr == 1) then( exit returning(supported at offset(tile, 0, -1)) ) if(d == 2 && set == corner set && fr == 1) then( exit returning(supported at offset(tile, 1, -1)) ) if(d == 3 && set == edge set && fr == 2) then( exit returning(supported at offset(tile, 1, 0)) ) if(d == 4 && set == corner set && fr == 2) then( exit returning(supported at offset(tile, 1, 1)) ) if(d == 5 && set == edge set && fr == 3) then( exit returning(supported at offset(tile, 0, 1)) ) if(d == 6 && set == corner set && fr == 3) then( exit returning(supported at offset(tile, -1, 1)) ) if(d == 7 && set == edge set && fr == 4) then( exit returning(supported at offset(tile, -1, 0)) ) pic := next sibling(pic) ) exit returning(false) end script, supported at offset, tile, xd, yd, begin variable(other) other := tile at pos(tile x(tile) + xd, tile y(tile) + yd) if(other) then( exit returning(get slice extra(other, 1)) ) exit returning(false) end script, clear support flags, begin variable(tile) tile := first child(playbox) while(tile) do( set slice extra(tile, 1, false) tile := next sibling(tile) ) end #----------------------------------------------------------------------- # BLOCKS script, place block, block, begin variable(tile, next tile) tile := first child(block) while(tile) do( next tile := next sibling(tile) place tile(tile, convert tile x(tile), convert tile y(tile)) tile := next tile ) end script, drop next block, begin variable(block) #trace(string sprintf(0, $1="Tutorial=%d", tutorial)) switch(tutorial) do( case(1) block := create block(kind:waffle, shape:3bar, 0) case(5) block := create block(kind:butter, shape:crowbar, 0) case(9) block := create block(kind:syrup, shape:steps, 0) case(11) block := create block(kind:butter, shape:corner, 2) case(else) block := create random block ) set tile x(block, lastcol / 2 + random(0, 1)) set tile y(block, -2) animate falling block(block) falling := block end script, move block down, block, begin set tile y(block, tile y(block) + 1) animate falling block(block) end script, create random block, begin variable(block, kind, shape, rotation) kind := weighted random kind shape := random(first shape, last shape) rotation := random(0, 3) block := create block(kind, shape, rotation) exit returning(block) end script, weighted random kind, begin variable(kind) kind := random(1, 3) if(since waffle >= 4) then( kind := kind:waffle )else if(since butter >= 4) then( kind := kind:butter )else if(since syrup >= 4) then( kind := kind:syrup ) switch(kind) do( case(kind:waffle) do(since waffle := 0, since butter += 1, since syrup += 1) case(kind:butter) do(since butter := 0, since waffle += 1, since syrup += 1) case(kind:syrup) do(since syrup := 0, since waffle += 1, since butter += 1) ) exit returning(kind) end script, create block, kind, shape, rotation, begin variable(block) block := create container(tilesize, tilesize) set slice lookup(block, sli:block) set parent(block, blockbox) switch(shape) do( # 3-tile blocks case(shape:corner) do( create tile(block, kind, -1, 0) create tile(block, kind, 0, 0) create tile(block, kind, 0, -1) ) case(shape:crowbar) do( create tile(block, kind, -1, -1) create tile(block, kind, 0, 0) create tile(block, kind, 0, 1) ) case(shape:crowbar2) do( create tile(block, kind, 1, -1) create tile(block, kind, 0, 0) create tile(block, kind, 0, 1) ) case(shape:caret) do( create tile(block, kind, -1, 0) create tile(block, kind, 0, 1) create tile(block, kind, 1, 0) ) case(shape:3bar) do( create tile(block, kind, -1, 0) create tile(block, kind, 0, 0) create tile(block, kind, 1, 0) ) case(shape:steps) do( create tile(block, kind, -1, -1) create tile(block, kind, 0, 0) create tile(block, kind, 1, 1) ) # 4-tile blocks case(shape:square) do( create tile(block, kind, 0, 0) create tile(block, kind, 1, 0) create tile(block, kind, 1, 1) create tile(block, kind, 0, 1) ) case(shape:4bar) do( create tile(block, kind, 0, -1) create tile(block, kind, 0, 0) create tile(block, kind, 0, 1) create tile(block, kind, 0, 2) ) case(shape:J) do( create tile(block, kind, 0, -1) create tile(block, kind, 0, 0) create tile(block, kind, 0, 1) create tile(block, kind, -1, 1) ) case(shape:L) do( create tile(block, kind, 0, -1) create tile(block, kind, 0, 0) create tile(block, kind, 0, 1) create tile(block, kind, 1, 1) ) case(shape:Z) do( create tile(block, kind, -1, 0) create tile(block, kind, 0, 0) create tile(block, kind, 0, 1) create tile(block, kind, 1, 1) ) case(shape:S) do( create tile(block, kind, 1, 0) create tile(block, kind, 0, 0) create tile(block, kind, 0, 1) create tile(block, kind, -1, 1) ) case(shape:hat) do( create tile(block, kind, 0, -1) create tile(block, kind, 0, 0) create tile(block, kind, -1, 0) create tile(block, kind, 1, 0) ) ) variable(i) for(i, 1, rotation) do( rotate right(block, false) ) update block connections(block) exit returning(block) end script, update block connections, block, begin variable(tile, other) tile := first child(block) while(tile) do( reset tile connections(tile) other := first child(block) while(other) do( if(tile <> other) then( add tile connection(tile, other) ) other := next sibling(other) ) tile := next sibling(tile) ) end script, rotate right, block, check=true, begin variable(tile, tx, ty, wall) tile := first child(block) while(tile) do( tx := tile x(tile) ty := tile y(tile) set tile x(tile, ty * -1) set tile y(tile, tx) tile := next sibling(tile) ) if(check && check for block collision(block, 0, 0)) then( if(not(try block move(block, 1))) then( if(not(try block move(block, -1))) then( rotate left(block, false) ) ) ) update block connections(block) end script, rotate left, block, check=true, begin variable(tile, tx, ty) tile := first child(block) while(tile) do( tx := tile x(tile) ty := tile y(tile) set tile x(tile, ty) set tile y(tile, tx * -1) tile := next sibling(tile) ) if(check && check for block collision(block, 0, 0)) then( if(not(try block move(block, -1))) then( if(not(try block move(block, 1))) then( rotate right(block, false) ) ) ) update block connections(block) end script, sever all connections, tile, begin variable(parent, other, tx, ty, ox, oy, dx, dy, overlay) overlay := lookup slice(sli:overlay, tile) free slice children(overlay) tx := tile x(tile) ty := tile y(tile) parent := parent slice(tile) other := first child(parent) while(other) do( if(other <> tile) then( ox := tile x(other) oy := tile y(other) dx := ox -- tx dy := oy -- ty if(abs(dx) <= 1 && abs(dy) <= 1) then( sever connection(other, dx * -1, dy * -1) ) ) other := next sibling(other) ) end script, sever connection, tile, dx, dy, begin variable(overlay, pic, next pic, kind, edge set, corner set, set, fr) kind := get kind(tile) edge set := sprite set for kind(kind, 0) corner set := sprite set for kind(kind, 1) overlay := lookup slice(sli:overlay, tile) pic := first child(overlay) while(pic) do( next pic := next sibling(pic) set := get sprite set number(pic) fr := get sprite frame(pic) if(set == edge set) then( if(fr == 1 && dx == 0 && dy == -1) then( free slice(pic), exit script ) if(fr == 2 && dx == 1 && dy == 0) then( free slice(pic), exit script ) if(fr == 3 && dx == 0 && dy == 1) then( free slice(pic), exit script ) if(fr == 4 && dx == -1 && dy == 0) then( free slice(pic), exit script ) )else if(set == corner set) then( if(fr == 0 && dx == -1 && dy == -1) then( free slice(pic), exit script ) if(fr == 1 && dx == 1 && dy == -1) then( free slice(pic), exit script ) if(fr == 2 && dx == 1 && dy == 1) then( free slice(pic), exit script ) if(fr == 3 && dx == -1 && dy == 1) then( free slice(pic), exit script ) ) pic := next pic ) end #----------------------------------------------------------------------- # TILES script, move tile down, tile, interval=-1, begin variable(ty) ty := tile y(tile) + 1 if(ty > last row) then(exit script) set tile y(tile, ty) animate falling tile(tile, interval) end script, move tile over, tile, d, interval, begin variable(tx) tx := tile x(tile) + d set tile x(tile, tx) variable(pic) pic := lookup slice(sli:tile pic, tile) set slice x(pic, tilesize * d * -1) move slice to(pic, 0, 0, interval) end script, reset tile connections, tile, begin variable(overlay) overlay := lookup slice(sli:overlay, tile) free slice children(overlay) end script, add tile connection, tile, other, begin variable(tx, ty, ox, oy, dx, dy) tx := tile x(tile) ty := tile y(tile) ox := tile x(other) oy := tile y(other) dx := ox -- tx dy := oy -- ty if(dx < -1 || dx > 1 || dy < -1 || dy > 1) then( # Tiles are not actually nearby exit script ) if(dx == 0 && dy == 0) then( script error($0="add tile connection: tiles overlap") ) add connection overlay(tile, dx, dy) end script, add connection overlay, tile, dx, dy, begin variable(overlay, kind, pic, set, fr) overlay := lookup slice(sli:overlay, tile) kind := get kind(tile) if(dx == 0 && dy == -1) then( set := sprite set for kind(kind, 0) fr := 1 ) if(dx == 1 && dy == 0) then( set := sprite set for kind(kind, 0) fr := 2 ) if(dx == 0 && dy == 1) then( set := sprite set for kind(kind, 0) fr := 3 ) if(dx == -1 && dy == 0) then( set := sprite set for kind(kind, 0) fr := 4 ) if(dx == -1 && dy == -1) then( set := sprite set for kind(kind, 1) fr := 0 ) if(dx == 1 && dy == -1) then( set := sprite set for kind(kind, 1) fr := 1 ) if(dx == 1 && dy == 1) then( set := sprite set for kind(kind, 1) fr := 2 ) if(dx == -1 && dy == 1) then( set := sprite set for kind(kind, 1) fr := 3 ) pic := load walkabout sprite(set) set sprite frame(pic, fr) set parent(pic, overlay) variable(pic2) if(dx == -1 && dy == -1) then( set := sprite set for kind(kind, 1) fr := 5 pic2 := load walkabout sprite(set) set sprite frame(pic2, fr) set parent(pic2, pic) set tile x(pic2, -1) fr := 7 pic2 := load walkabout sprite(set) set sprite frame(pic2, fr) set parent(pic2, pic) set tile y(pic2, -1) ) if(dx == 1 && dy == -1) then( set := sprite set for kind(kind, 1) fr := 4 pic2 := load walkabout sprite(set) set sprite frame(pic2, fr) set parent(pic2, pic) set tile x(pic2, 1) fr := 6 pic2 := load walkabout sprite(set) set sprite frame(pic2, fr) set parent(pic2, pic) set tile y(pic2, -1) ) end script, place tile, tile, tx, ty, begin set parent(tile, playbox) set tile x(tile, tx) set tile y(tile, ty) end script, tile at pos, tx, ty, which=1, begin # if which=0 then returns the number of tiles at that pos # if which=1 returns the first tile at that pos, and so-on variable(tile, apos, tc) if(tcache dirty) then( #trace(string sprintf(0, $1="tcache dirty %d", ticks)) # The cache has been marked dirty, we need to rebuild it variable(ox, oy) # First zero out the cache counts for(oy, 0, lastrow) do( for(ox, 0, lastcol) do( apos := oy * (lastcol + 1) + ox write global(@tcache + apos, 0) ) ) # Now write all tile's handles into the cache tile := first child(playbox) while(tile) do( ox := tile x(tile) oy := tile y(tile) if(oy >= 0 && oy <= lastrow && ox >= 0 && ox <= lastcol) then( # Only tiles in-range get cached apos := oy * (lastcol + 1) + ox tc := read global(@tcache + apos) tc += 1 write global(@tcache + apos, tc) write global(@tcache + apos + 160 * tc, tile) ) tile := next sibling(tile) ) # The cache is fresh and clean tcache dirty := false ) if(tx < 0 || tx > lastcol || ty < 0 || ty > lastrow) then( exit returning(0) ) # Return the cached tile handle for this tx,ty position apos := ty * (lastcol + 1) + tx tc := read global(@tcache + apos) if(which == 0) then(exit returning(tc)) if(tc < which) then(exit returning(0)) exit returning(read global(@tcache + apos + 160 * which)) end script, tile x, tile, begin exit returning(slice x(tile) / tilesize) end script, tile y, tile, begin exit returning(slice y(tile) / tilesize) end script, set tile x, tile, tx, begin if(parent slice(tile) == playbox) then( remove tile from cache(tile) ) set slice x(tile, tx * tilesize) if(parent slice(tile) == playbox) then( add tile to cache(tile) ) end script, set tile y, tile, ty, begin if(parent slice(tile) == playbox) then( remove tile from cache(tile) if(ty < 0) then( peril := true ) ) set slice y(tile, ty * tilesize) if(parent slice(tile) == playbox) then( add tile to cache(tile) ) end script, free tile, tile, begin sever all connections(tile) if(parent slice(tile) == playbox) then( remove tile from cache(tile) ) free slice(tile) end script, remove tile from cache, tile, begin if(tcache dirty) then( # Don't bother, the cache will be rebuilt soon exit script ) variable(tx, ty, tc, apos, i, j, other, found) tx := tile x(tile) ty := tile y(tile) if(tx < 0 || tx > lastcol || ty < 0 || ty > lastrow) then(exit script) apos := ty * (lastcol + 1) + tx tc := read global(@tcache + apos) if(tc <= 0) then( # Tried to remove a cached tile when cache count is <= 0 exit script ) for(i, 1, tc) do( other := read global(@tcache + apos + 160 * i) if(other == tile) then( # Found it! found := true for(j, i + 1, tc) do( other := read global(@tcache + apos + 160 * j) write global(@tcache + apos + 160 * (j -- 1), other) ) break ) ) if(not(found)) then( trace(string sprintf(0, $1="Tried to remove a cached tile but that tile is missing from the cache")) exit script ) tc -= 1 write global(@tcache + apos, tc) end script, add tile to cache, tile, begin if(tcache dirty) then( # Don't bother, the cache will be rebuilt soon exit script ) variable(tx, ty, tc, apos) tx := tile x(tile) ty := tile y(tile) if(tx < 0 || tx > lastcol || ty < 0 || ty > lastrow) then(exit script) apos := ty * (lastcol + 1) + tx tc := read global(@tcache + apos) tc += 1 write global(@tcache + apos + 160 * tc, tile) write global(@tcache + apos, tc) end script, create tile, parent, kind, txoff, tyoff, clearspot=false, begin variable(tile) if(clearspot && parent == playbox) then( tile := tile at pos(txoff, tyoff) if(tile) then( free tile(tile) ) ) tile := create container(tilesize, tilesize) set slice lookup(tile, sli:tile) set parent(tile, parent) set tile x(tile, txoff) set tile y(tile, tyoff) set kind(tile, kind) variable(pic) exit returning(tile) end script, update kind, tile, kind, begin variable(pic) pic := lookup slice(sli:tile pic, tile) if(not(pic)) then( pic := load walkabout sprite(0) set slice lookup(pic, sli:tile pic) set parent(pic, tile) ) set sprite set number(pic, sprite set for kind(kind)) variable(overlay) overlay := lookup slice(sli:overlay, pic) if(not(overlay)) then( overlay := create container(tilesize, tilesize) set slice lookup(overlay, sli:overlay) set parent(overlay, pic) ) end script, set kind, tile, kind, begin set slice extra(tile, 0, kind) update kind(tile, kind) end script, get kind, tile, begin if(not(tile)) then(exit returning(kind:none)) exit returning(get slice extra(tile, 0)) end script, sprite set for kind, kind, subset=0, begin if(kind is dev(kind)) then(exit returning(20 + kind -- kind:dev)) exit returning(1 + (kind -- 1) * 2 + subset) end script, check for block tile collision, tile, xgo, ygo, begin variable(tx, ty) tx := convert tile x(tile) ty := convert tile y(tile) exit returning(check for collision(get kind(tile), tx, ty, xgo, ygo)) end script, check for tile collision, tile, xgo, ygo, merge=false, begin if(parent slice(tile) <> playbox) then( script error($0="check for tile collision: tile is not parented to the playbox") ) exit returning(check for collision(get kind(tile), tile x(tile), tile y(tile), xgo, ygo, merge)) end script, check for collision, kind, tx, ty, xgo, ygo, merge=false, begin variable(x, y) x := tx + xgo y := ty + ygo if(y > lastrow) then(exit returning(true)) if(x < 0) then(exit returning(true)) if(x > lastcol) then(exit returning(true)) variable(tile, tc, i, other kind) tc := tile at pos(x, y, 0) if(tc > 0 && not(merge)) then(exit returning(true)) for(i, 1, tc) do( tile := tile at pos(x, y, i) other kind := get kind(tile) if(not(merge kinds(kind, other kind))) then( exit returning(true) ) ) exit returning(false) end #----------------------------------------------------------------------- # PRE-FILLED ROWS script, create random rows, count, kind, density=60, begin variable(tx, ty) for(ty, lastrow, lastrow -- count + 1, -1) do( for(tx, 0, lastcol) do( if(random percent(density)) then( create tile(playbox, kind, tx, ty) ) ) ) update block connections(playbox) end #----------------------------------------------------------------------- # TILE MERGES script, merge kinds, k1, k2, begin if(k1 == kind:waffle && k2 == kind:butter) then(exit returning(kind:buttered waffle)) if(k1 == kind:butter && k2 == kind:waffle) then(exit returning(kind:buttered waffle)) if(k1 == kind:waffle && k2 == kind:syrup) then(exit returning(kind:syruped waffle)) if(k1 == kind:syrup && k2 == kind:waffle) then(exit returning(kind:syruped waffle)) if(k1 == kind:buttered waffle && k2 == kind:syrup) then(exit returning(kind:completed waffle)) if(k1 == kind:syrup && k2 == kind:buttered waffle) then(exit returning(kind:completed waffle)) if(k1 == kind:syruped waffle && k2 == kind:butter) then(exit returning(kind:completed waffle)) if(k1 == kind:butter && k2 == kind:syruped waffle) then(exit returning(kind:completed waffle)) exit returning(false) end script, check for all tile merges, begin check for tile merges of kind(kind:butter, kind:syruped waffle) check for tile merges of kind(kind:syrup, kind:buttered waffle) do queued removals end script, check for tile merges of kind, topping, other topped waffle, begin variable(tx, ty, tc, i, j, tile, other, kind, okind) for(ty, 0, lastrow) do( for(tx, 0, lastcol) do( tc := tile at pos(tx, ty, 0) if(tc > 1) then( for(i, 1, tc) do( for(j, 1, tc) do( if(i <> j) then( tile := tile at pos(tx, ty, i) other := tile at pos(tx, ty, j) kind := get kind(tile) okind := get kind(other) if(kind == topping && (okind == kind:waffle || okind == other topped waffle)) then( if(check for tile merge(tile, other)) then( # Waffle merge happened ) ) ) ) ) ) ) ) end script, check for tile merge, tile, other, begin variable(k1, k2, k3) k1 := get kind(tile) k2 := get kind(other) k3 := merge kinds(k1, k2) if(k3) then( splash effect at(tile) set kind(other, k3) sever all connections(other) queue for removal(tile) exit returning(true) ) exit returning(false) end #----------------------------------------------------------------------- # SPATULA ROWS script, check for spatula rows, begin # Return true if any row was spatula'd variable(tx, ty, tile, found, result) result := false for(ty, 0, lastrow) do( found := 0 for(tx, 0, lastcol) do( tile := tile at pos(tx, ty) if(tile && not(tile is dev(tile))) then( found += 1 ) ) if(found > lastcol) then( # Remove a completed row result := true play sound(7) for(tx, 0, lastcol) do( tile := tile at pos(tx, ty) if(get kind(tile) == kind:completed waffle) then( increment stat(stats:customer waffles, 1) ) create tile dissolve effect(tile) queue for removal(tile) ) clear all jumped spatula effect(ty) increment stat(stats:spatulas, 1) ) ) exit returning(result) end #----------------------------------------------------------------------- # EFFECTS script, update effects, begin variable(e, next e, cb) e := first child(effect layer) while(e) do( next e := next sibling(e) cb := get slice extra(e, 0) if(cb) then( run script by id(cb, e) ) e := next e ) end script, any blocking effects, begin variable(e, cb) e := first child(effect layer) while(e) do( cb := get slice extra(e, 0) switch(cb) do( case(@update dissolve effect) do( exit returning(true) ) case(@update path debug effect) do( exit returning(true) ) case(@update punch effect) do( exit returning(true) ) ) e := next sibling(e) ) exit returning(false) end script, create punch effect, tile, d, begin splash effect at(tile) variable(e, pic) pic := lookup slice(sli:tile pic, tile) e := load walkabout sprite(get sprite set number(pic)) set sprite frame(e, get sprite frame(pic)) dissolve sprite(e, dissolve:shrink, second / 2) set parent(e, effect layer) put slice(e, slice x(tile), slice y(tile)) set slice extra(e, 0, @update punch effect) move slice to(e, slice x(e) + tilesize * 3 * d, slice y(e) + random(tilesize * -1, tilesize), second / 2) end script, update punch effect, e, begin if(not(sprite is dissolving(e))) then( free slice(e) ) end script, spatula effect, ty, begin variable(e) e := load large enemy sprite(1) set parent(e, effect layer) variable(x, d) x := 0 -- 40 d := 1 if(spatula toggle) then( x := 200 + 40 d := -1 horiz flip sprite(e, true) ) set slice edge x(e, edge:center, x) set slice edge y(e, edge:center, ty * tilesize + tilesize / 2) move slice by(e, (200 + 80 + 80) * d, 0, second) set slice extra(e, 0, @update spatula effect) spatula toggle := not(spatula toggle) exit returning(e) end script, update spatula effect, e, begin if(not(slice is moving(e))) then( free slice(e) ) end script, create debug effect at tile, tile, begin exit returning(create debug effect(tile x(tile), tile y(tile))) end script, create debug effect, tx, ty, begin variable(e) e := load border sprite(4) set slice edge x(e, edge:center, tx * tilesize + tilesize / 2) set slice edge y(e, edge:center, ty * tilesize + tilesize / 2) set slice extra(e, 0, @update path debug effect) set parent(e, effect layer) exit returning(e) end script, create path debug effects, p, begin variable(node) node := first child(p) while(node) do( create debug effect(slice x(node), slice y(node)) node := next sibling(node) ) end script, update path debug effect, e, begin if(frame to last(e, 0, 15)) then( free slice(e) ) end script, create tile dissolve effect, tile, dissolve=dissolve:flicker, begin variable(e, pic) pic := lookup slice(sli:tile pic, tile) e := load walkabout sprite(get sprite set number(pic)) set sprite frame(e, get sprite frame(pic)) dissolve sprite(e, dissolve, second / 2) set parent(e, effect layer) put slice(e, slice x(tile), slice y(tile)) set slice extra(e, 0, @update dissolve effect) end script, update dissolve effect, e, begin if(not(sprite is dissolving(e))) then( free slice(e) ) end script, splash effect at, tile, begin variable(kind, pic num) kind := get kind(tile) if(kind == kind:waffle || kind == kind:butter) then( pic num := 1 )else if(kind == kind:buttered waffle || kind == kind:syrup) then( pic num := 2 )else( pic num := 3 ) variable(i, e) for(i, 0, 4) do( e := create droplet(pic num) set slice edge x(e, edge:center, slice edge x(tile, edge:center)) set slice edge y(e, edge:center, slice edge y(tile, edge:center)) ) play sound(2) end script, create droplet, pic num, begin variable(e) e := load border sprite(pic num) set slice extra(e, 0, @update droplet effect) set slice extra(e, 1, random(-6, 6)) set slice extra(e, 2, random(-10, -5)) set parent(e, effect layer) exit returning(e) end script, update droplet effect, e, begin variable(fx, fy) fx := get slice extra(e, 1) fy := get slice extra(e, 2) set slice x(e, slice x(e) + fx) set slice y(e, slice y(e) + fy + 3) fx -= sign(fx) fy -= sign(fy) set slice extra(e, 1, fx) set slice extra(e, 2, fy) if(frame to last(e, 0, 15)) then( free slice(e) ) end script, create push up warning effect, begin variable(i, e) for(i, 0, 12) do( e := load border sprite(5) set slice x(e, i * 16) set slice y(e, 320) set vert anchor(e, edge:bottom) set sprite frame(e, i) set slice extra(e, 0, @update push up warning effect) set parent(e, effect layer) ) end script, update push up warning effect, e, begin if(push up <> push up threshold) then( free slice(e) exit script ) loop frame(e, 0, 11, 2) end #----------------------------------------------------------------------- # TILE/BLOCK CONVERSION script, convert tile x, tile, begin variable(block) block := parent slice(tile) if(get slice lookup(block) <> sli:block) then( script error($0="convert tile x: tile does not belong to a block") ) exit returning(tile x(block) + tile x(tile)) end script, convert tile y, tile, begin variable(block) block := parent slice(tile) if(get slice lookup(block) <> sli:block) then( script error($0="convert tile y: tile does not belong to a block") ) exit returning(tile y(block) + tile y(tile)) end #----------------------------------------------------------------------- # ANIMATION script, animate falling block, block, begin variable(tile) tile := first child(block) while(tile) do( animate falling tile(tile) tile := next sibling(tile) ) end script, animate falling tile, tile, interval=-1, begin if(interval == -1) then( # Auto interval interval := falling interval ) variable(pic) pic := lookup slice(sli:tile pic, tile) set slice y(pic, -1 * tilesize) move slice to(pic, 0, 0, interval) end script, animate rising tile, tile, interval=-1, begin if(interval == -1) then( # Auto interval interval := falling interval ) variable(pic) pic := lookup slice(sli:tile pic, tile) set slice y(pic, tilesize) move slice to(pic, 0, 0, interval) end script, animate sideways block, block, xgo, begin variable(tile) tile := first child(block) while(tile) do( animate sideways tile(tile, xgo) tile := next sibling(tile) ) end script, animate sideways tile, tile, xgo, interval=-1, begin if(interval == -1) then( # Auto interval interval := second / 8 ) variable(pic) pic := lookup slice(sli:tile pic, tile) set slice x(pic, -1 * xgo * tilesize) move slice to(pic, 0, 0, interval) end #----------------------------------------------------------------------- # STATISTICS script, init statistics, begin variable(i) for(i, @stats array, @stats array + last stat) do( write global(i, 0) ) end script, giz reacts to stats, begin if(tutorial > 0) then(exit script) giz react over(1, stats:dev total waffles, 1, $0="Eating waffles on the job, huh? That's okay, I guess...") giz react waffle diff(1, 5, $0="You Devs seem to be eating more waffles than you are serving.") giz react waffle diff(2, 10, $0="These waffles are coming out of your pay. Don't say I didn't warn you.") giz react waffle diff(3, 25, $0="You are eating all my profits! Do I regret hiring you all?") giz react waffle diff(4, 26, $0="YES I DO, I REGRET IT! You are taking advantage of my generous nature.") giz react waffle diff(5, 40, $0="How am I going to make rent? Try to serve more waffles to the customers!") giz react waffle diff(6, 60, $0="You know what? I give up. Eat all you want. I hope you choke.") giz react waffle diff(7, 61, $0="Actually don't choke. Paramedics outside a restaurant is bad for business.") giz react over(100, stats:customer waffles, 1, $0="You served your first waffle to the customers! Took you long enough.") giz react over(101, stats:customer waffles, 5, $0="Five waffles served! Step up the pace!") giz react over(102, stats:customer waffles, 10, $0="Ten waffles served! Keep it up!") giz react over(103, stats:customer waffles, 20, $0="Twenty waffles served. If you weren't eating so many, I would be proud.") if(giz react over(104, stats:customer waffles, 30, $0="Thirty waffles served. I'm gonna speed up the toasters a little.")) then( push up threshold := 10 ) giz react over(105, stats:customer waffles, 40, $0="Forty waffles served. Not bad, not bad.") if(giz react over(106, stats:customer waffles, 50, $0="Fifty waffles served. I think you can handle bigger blocks now.")) then( last shape := last 4 shape ) giz react over(107, stats:customer waffles, 60, $0="Sixty waffles served. The customers are fat and happy!") if(giz react over(108, stats:customer waffles, 70, $0="Seventy waffles served. Now that is a lot of waffles!")) then( giz sez($0="I think you can handle faster toasters.") push up threshold := 9 ) giz react over(109, stats:customer waffles, 80, $0="Waffles were invented in 1124AD by Sir Oublie Wafele of Belgium") giz react over(110, stats:customer waffles, 90, $0="Did you know? The word 'Waffle' is an onomatopoea") giz react over(111, stats:customer waffles, 100, $0="15 to 20 people die every year from acute waffle overdose") if(giz react over(112, stats:customer waffles, 101, $0="1 to 2 of those yearly deaths happens in my restaurant")) then( push up threshold := 8 ) giz react over(113, stats:customer waffles, 150, $0="You are still here? The restaurant closed hours ago!") end script, giz react waffle diff, rnum, diff, str id, begin if(not(read global(@reactions + rnum))) then( variable(n1, n2) n1 := read global(@stats array + stats:dev total waffles) n2 := read global(@stats array + stats:customer waffles) if(n1 >= n2 + diff) then( write global(@reactions + rnum, true) giz sez(str id) exit returning(true) ) ) exit returning(false) end script, giz react over, rnum, stat id, over n, str id, begin if(not(read global(@reactions + rnum))) then( if(read global(@stats array + stat id) >= over n) then( write global(@reactions + rnum, true) giz sez(str id) exit returning(true) ) ) exit returning(false) end script, statistic name, string id, stat, begin switch(stat) do( case(stats:spatulas) do($string id="Spatulas") case(stats:customer waffles) do($string id="Waffles served") case(stats:dev total waffles) do($string id="Waffles eaten by devs") case(stats:devs+0) do($string id="Bob the Hamster") case(stats:devs+1) do($string id="TMC") case(stats:devs+2) do($string id="Spoonweaver") case(stats:devs+3) do($string id="Marionline") case(stats:devs+4) do($string id="Ichiro") case(stats:devs+5) do($string id="Feenicks") case(stats:devs+6) do($string id="BMR") ) exit returning(string id) end script, set statistic image, e, begin variable(stat, img) stat := get slice extra(e, 1) img := lookup slice(sli:alert sprite, e) switch(stat) do( case(stats:devs+0) do(replace walkabout sprite(img, 20)) case(stats:devs+1) do(replace walkabout sprite(img, 21)) case(stats:devs+2) do(replace walkabout sprite(img, 22)) case(stats:devs+3) do(replace walkabout sprite(img, 23)) case(stats:devs+4) do(replace walkabout sprite(img, 24)) case(stats:devs+5) do(replace walkabout sprite(img, 25)) case(stats:devs+6) do(replace walkabout sprite(img, 26)) ) end script, increment stat, stat, n=1, begin variable(v) v := read global(@stats array + stat) v += n write global(@stats array + stat, v) animate statistic(stat) giz reacts to stats end script, count dev waffle, dev, begin increment stat(stats:dev total waffles, 1) variable(kind, dev id) kind := get kind(dev) dev id := kind -- kind:dev increment stat(stats:devs + dev id, 1) end script, find statistic animation, stat, begin variable(e) e := first child(effect layer) while(e) do( if(effect is statistic(e)) then( if(get slice extra(e, 1) == stat) then( exit returning(e) ) ) e := next sibling(e) ) exit returning(0) end script, animate statistic, stat, begin variable(col, e) e := find statistic animation(stat) if(not(e)) then( col := load slice collection(slicol:alert) e := lookup slice(sli:alert plank, col) set parent(e, effect layer) free slice(col) set slice extra(e, 0, @update statistic effect) set slice extra(e, 1, stat) set slice x(e, 200) set slice y(e, next statistic effect y(e)) move slice by(e, -200, 0, second / 3) set statistic image(e) ) variable(meta) meta := lookup slice(sli:meta, e) set slice extra(meta, 0, 0) update statistic text(e) exit returning(e) end script, effect is statistic, e, begin variable(cb) cb := get slice extra(e, 0) exit returning(cb == @update statistic effect) end script, next statistic effect y, ignore, begin variable(y, e, ey) e := first child(effect layer) while(e) do( if(e <> ignore) then( if(effect is statistic(e)) then( ey := slice y(e) if(y == ey) then(y += 10) ) ) e := next sibling(e) ) exit returning(y) end script, update statistic text, e, begin variable(txt, stat, v) txt := lookup slice(sli:alert text, e) stat := get slice extra(e, 1) v := read global(@stats array + stat) set slice text(txt, string sprintf(0, $1="%d %s", v, statistic name(2, stat))) end script, meta tick, e, begin variable(meta, t) meta := lookup slice(sli:meta, e) t := get slice extra(meta, 0) t += 1 set slice extra(meta, 0, t) exit returning(t) end script, update statistic effect, e, begin variable(t) t := meta tick(e) if(t > second * 4) then( move slice to(e, 0, -1 * slice height(e), second / 3) set slice extra(e, 0, @update statistic effect exit) ) end script, update statistic effect exit, e, begin if(not(slice is moving(e))) then( free slice(e) ) end #----------------------------------------------------------------------- # REMOVAL ARRAY script, init removal array, begin removal array := create container(0, 0) set slice visible(removal array, false) set slice lookup(removal array, sli:removal array) end script, queue for removal, sl, is tile=true, begin variable(r, rsl) r := first child(removal array) while(r) do( rsl := get slice extra(r, 0) if(sl == rsl) then( # This slice is already queued for removal exit script ) r := next sibling(r) ) r := create container(0, 0) set parent(r, removal array) set slice extra(r, 0, sl) set slice extra(r, 1, is tile) end script, do queued removals, begin variable(r, sl, is tile) r := first child(removal array) while(r) do( sl := get slice extra(r, 0) is tile := get slice extra(r, 1) if(is tile) then( free tile(sl) )else( free slice(sl) ) r := next sibling(r) ) free slice children(removal array) end #----------------------------------------------------------------------- # DEMO MODE BANNERS script, start demo timer, begin if(not(banner col)) then( banner col := load slice collection(slicol:banners) ) set timer(1, banner delay, second, @show banner) end script, show banner, begin if(not(demo mode)) then( set timer(1, 30, second, @show banner) exit script ) if(tutorial) then( set timer(1, 30, second, @show banner) exit script ) banner gravity := calc banner gravity set slice visible(banner col, true) slice to front(banner col) variable(rect, spr) rect := lookup slice(sli:banner rect, banner col) set rect bgcol(rect, random(0, 255)) set rect fgcol(rect, random(0, 255)) if(banner gravity) then( # from bottom set slice y(rect, slice height(sprite layer)) move slice to(rect, 0, slice height(sprite layer) -- 44, second / 3) )else( # from top set slice y(rect, -44) move slice to(rect, 0, 0, second / 3) ) spr := lookup slice(sli:banner sprite, banner col) variable(bnum, bset, fr) bnum := random(0, 6) set slice extra(banner col, 0, bnum) bset := bnum / 5 fr := bnum ,mod, 5 set sprite set number(spr, 2 + bset) set slice y(spr, -40 * fr) set timer(2, 0, second / 8, @banner flash) set timer(1, 4, second, @banner removal) end script, calc banner gravity, begin variable(tx, ty, tc) for(ty, 0, lastrow / 2) do( for(tx, 0, lastcol) do( tc := tile at pos(tx, ty, 0) if(tc > 0) then(exit returning(1)) ) ) exit returning(0) end script, banner flash, begin variable(c1, c2, rect) rect := lookup slice(sli:banner rect, banner col) c1 := get rect bgcol(rect) c2 := get rect fgcol(rect) set rect bgcol(rect, c2) set rect fgcol(rect, c1) set timer(2, 0, second / 8, @banner flash) end script, banner removal, begin variable(rect) rect := lookup slice(sli:banner rect, banner col) if(banner gravity) then( # move down off bottom move slice to(rect, 0, slice height(sprite layer), second / 3) )else( # move up off top move slice to(rect, 0, -44, second / 3) ) set timer(1, 0, second / 3, @hide banner) end script, hide banner, begin set slice visible(banner col, false) stop timer(2) set timer(1, banner delay, second, @show banner) end script, banner input, begin if(not(demo mode)) then(exit script) if(not(banner col)) then(exit script) variable(rect) if(mouse click(left button)) then( rect := lookup slice(sli:banner rect, banner col) if(slice collide point(rect, mouse pixel x, mouse pixel y)) then( clicked banner ) ) end script, clicked banner, begin suspend timers variable(bnum) bnum := get slice extra(banner col, 0) switch(bnum) do( case(0) giz sez($0="They ain't as delicious as waffles, that is secret #1") case(1) giz sez($0="The APR might be great, but is the interest rate fixed?") case(2) giz sez($0="Sinful, so buttery good and sinful...") case(3) giz sez($0="A problem shared by all macho-men of good taste.") case(4) giz sez($0="Hey now! That ad wasn't for my restaurant! Come back!") case(5) giz sez($0="Do you install every single waffle-related game you find?") giz sez($0="This waffle-App thing is a fetish for you, isn't it?") case(6) giz sez($0="Only in my darkest hours have I considered eating government repo waffles.") ) switch(bnum) do( case(5) do() case(else) giz sez($0="Want to get rid of the ads? The full version is $0.99 in your App Store.") giz sez($0="But don't buy it! If the Devs earn any money, who will work in my restaurant?") ) resume timers set timer(1, 0, 1, @banner removal) end #----------------------------------------------------------------------- # UTILITY script, small, v1, v2, begin if(v1 >> v2) then(exit returning(v2)) exit returning(v1) end script, large, v1, v2, begin if(v1 << v2) then(exit returning(v2)) exit returning(v1) end script, frame to last, sl, first, last, tickmod=1, begin # Returns true if the frame has reached the last if(tickmod > 0 && ticks ,mod, tickmod <> 0) then(exit script) variable(fr) fr := get sprite frame(sl) fr += 1 if(fr < first) then(fr := first) if(fr > last) then(fr := last) set sprite frame(sl, fr) exit returning(fr == last) end script, loop frame, sl, first, last, tickmod=1, begin if(tickmod > 0 && ticks ,mod, tickmod <> 0) then(exit script) variable(fr) fr := get sprite frame(sl) fr += 1 if(fr < first) then(fr := first) if(fr > last) then(fr := first) set sprite frame(sl, fr) end script, random percent, p, begin exit returning(random(1, 100) <= p) end script, get exbit, sl, bit, begin variable(n) n := get slice extra(sl, 2) if(n,and,2^bit) then(exit returning(true)) exit returning(false) end script, set exbit, sl, bit, value=1, begin variable(n) n := get slice extra(sl, 2) if(value) then(n := n, or, 2^bit) else(n := n, and, (-1, xor, 2^bit)) set slice extra(sl, 2, n) end #-----------------------------------------------------------------------