From ed925b9aceef21180201bbbeeadba87cefdbbc72 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Sat, 2 Oct 2021 20:52:16 -0700 Subject: [PATCH] Add Technical Doodads + UI Fixes New category for the Doodad Dropper: "Technical" Technical doodads have a dashed outline and label for now, and they turn invisible on level start, and are for hidden technical effects on your level. The doodads include: * Goal Region: acts like an invisible Exit Flag (128x128), the level is won when the player character touches this region. * Fire Region: acts like a death barrier (128x128), kills the player when a generic "You have died!" message. * Power Source: on level start, acts like a switch and emits a power(true) signal to all linked doodads. Link it to your Electric Door for it to be open by default in your level! * Stall Player (250ms): The player is paused for a moment the first time it touches this region. Useful to work around timing issues, e.g. help prevent the player from winning a race against another character. There are some UI improvements to the Doodad Dropper window: * If the first page of doodads is short, extra spacers are added so the alignment and size shows correctly. * Added a 'background pattern' to the window: any unoccupied icon space has an inset rectangle slot. * "Last pages" which are short still render weirdly without reserving the correct height in the TabFrame. Doodad scripting engine updates: * Self.Hide() and Self.Show() available. * Subscribe to "broadcast:ready" to know when the level is ready, so you can safely Publish messages without deadlocks! --- dev-assets/doodads/build.sh | 4 +++ dev-assets/doodads/regions/Makefile | 25 ++++++++++++++ dev-assets/doodads/regions/fire-128.png | Bin 0 -> 965 bytes dev-assets/doodads/regions/fire.js | 19 +++++++++++ dev-assets/doodads/regions/goal-128.png | Bin 0 -> 986 bytes dev-assets/doodads/regions/goal.js | 19 +++++++++++ dev-assets/doodads/regions/power-128.png | Bin 0 -> 1150 bytes dev-assets/doodads/regions/power-64.png | Bin 0 -> 873 bytes dev-assets/doodads/regions/power.js | 22 +++++++++++++ dev-assets/doodads/regions/stall-128.png | Bin 0 -> 1106 bytes dev-assets/doodads/regions/stall.js | 40 +++++++++++++++++++++++ 11 files changed, 129 insertions(+) create mode 100644 dev-assets/doodads/regions/Makefile create mode 100644 dev-assets/doodads/regions/fire-128.png create mode 100644 dev-assets/doodads/regions/fire.js create mode 100644 dev-assets/doodads/regions/goal-128.png create mode 100644 dev-assets/doodads/regions/goal.js create mode 100644 dev-assets/doodads/regions/power-128.png create mode 100644 dev-assets/doodads/regions/power-64.png create mode 100644 dev-assets/doodads/regions/power.js create mode 100644 dev-assets/doodads/regions/stall-128.png create mode 100644 dev-assets/doodads/regions/stall.js diff --git a/dev-assets/doodads/build.sh b/dev-assets/doodads/build.sh index d115872..6bc41eb 100755 --- a/dev-assets/doodads/build.sh +++ b/dev-assets/doodads/build.sh @@ -66,6 +66,10 @@ objects() { cd crumbly-floor/ make cd .. + + cd regions/ + make + cd .. } onoff() { diff --git a/dev-assets/doodads/regions/Makefile b/dev-assets/doodads/regions/Makefile new file mode 100644 index 0000000..63b40ad --- /dev/null +++ b/dev-assets/doodads/regions/Makefile @@ -0,0 +1,25 @@ +ALL: build + +.PHONY: build +build: + # Goal Region + doodad convert -t "Goal Region" goal-128.png reg-goal.doodad + doodad install-script goal.js reg-goal.doodad + + # Fire Region + doodad convert -t "Fire Region" fire-128.png reg-fire.doodad + doodad install-script fire.js reg-fire.doodad + + # Stall Region + doodad convert -t "Stall Player (250ms)" stall-128.png reg-stall-250.doodad + doodad edit-doodad --tag "ms=250" reg-stall-250.doodad + doodad install-script stall.js reg-stall-250.doodad + + # Power Source + doodad convert -t "Power Source" power-64.png power-source.doodad + doodad install-script power.js power-source.doodad + + for i in *.doodad; do\ + doodad edit-doodad --tag "category=technical" $${i};\ + done + cp *.doodad ../../../assets/doodads/ \ No newline at end of file diff --git a/dev-assets/doodads/regions/fire-128.png b/dev-assets/doodads/regions/fire-128.png new file mode 100644 index 0000000000000000000000000000000000000000..117a231f879e5c23ca611ac8e9ffbfa32928211c GIT binary patch literal 965 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU~I{Bb`J1#c2+1T%1_J8No8Qr zm{>c}*5j~)%+dH@S4~lN?GB5S6^{}eLyiQl4rt+87?yGM;FC-G8J8w3*nm5IldZQUej0Ta5>j_YDf3X zH>+-Z?Gj-5k}T46Mkm>C(xeZv@!vTkmQ`2g9BpXuusO|hS?!*}yn9=C z&;33k7&ayJQSl?g$$B1tPLv*fY<`Y)I_o@1!^>7JvJ+ToF(=lyAYIA`CcGo`bfJrV@HCnz{MimFaYRCZhK*VQWW_IT}|=5_H( z)1B4{Nmz;nG_u|N+Wi0E`@FS(p0rFC>0_R&-}l*&r{pbD@2tl)^45NjSvc&N!>dlm zuVgl!zvOyU)EAByciHsTMbFyA9`lZY*}pC4)H;zRnom9-_$^r*EcRkIt5bGd{@L0& zb_|)Xv?`fpWSEp$PsM$&EHAIl|35GD+jnLS*P_l(3HOuXF*Aw$FN_DqF!Z*N5xH5o`W zTs*Kt`rC7*JMynL`k%SLb7g+C?+MHPP~~I!4wp*SCsr(%o%i^L>-^nMZL_4eUrV0% zrE?kQg2KChu55fd#d+_u`#X&rycw7r7&sc(Y!~epD?VTN=9=96cWU443y|TwNE~um5;8-*sD^(|AY+%kW;Ke(9i>H74te))@UclzGiCGh$B zp_7u_j_$|ftLjn~YVQ)*A~LIfFEax}{4U;->`QXHn><1OabQ>mBpDbL7+4s<;7)h! zLEcT;GgKH@8W>m-xPYVp0~1IM80-+deMmYb+QJj0iQ|9>L~8>?vY~pT_72A~*2yeD zO$`h_ji_41cQ;9=gd3o1%{a4u=>y$uI@0--{kM*-{W@bVqX2{EUj{=TOZ`1b4;4XX Nd%F6$taD0e0ssu}n-c&4 literal 0 HcmV?d00001 diff --git a/dev-assets/doodads/regions/fire.js b/dev-assets/doodads/regions/fire.js new file mode 100644 index 0000000..aae40c8 --- /dev/null +++ b/dev-assets/doodads/regions/fire.js @@ -0,0 +1,19 @@ +// Goal Region. +function main() { + Self.Hide(); + + Events.OnCollide(function (e) { + if (!e.Settled) { + return; + } + + // Only care if it's the player. + if (!e.Actor.IsPlayer()) { + return; + } + + if (e.InHitbox) { + FailLevel("You have died!"); + } + }); +} diff --git a/dev-assets/doodads/regions/goal-128.png b/dev-assets/doodads/regions/goal-128.png new file mode 100644 index 0000000000000000000000000000000000000000..b76991735766e6e6762b97b8e7e970c1eccf6a7d GIT binary patch literal 986 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU~I{Bb`J1#c2+1T%1_J8No8Qr zm{>c}*5j~)%+dH@S4~lN?GB5S6^{}eLyiQl4rt+87?yGM;FC-G8J8w3*nm5IldZQUej0Ta5>j_YDf3X zH>+-Z?Gj-5k}T46Mkm>C(xeZv@!vTkmQ`2g9BpXuusO|hS?!*}yn9=C z&;33k7&ayJQSl?g$$B1tPLv*fY<`Y)I_o@1!^>7JvJ+ToF(=lyAYIA`CcGo`bfJrV@HCnz{MimFaYRCZhK*VQWW_IT}|=5_H( z)1B4{Nmz;nG_u|N+Wi0E`@FS(p0rFC>0_R&-}l*&r{pbD@2tl)^45NjSvc&N!>dlm zuVgl!zvOyU)EAByciHsTMbFyA9`lZY*}pC4)H;zRnom9-_$^r*EcRkIt5bGd{@L0& zb_|)Xv?`fpWSEp$PsM$&EHAIl|35GD+jnLS*P_l(3HOuXTABOxwao{{F!Z*MvFH7hW% z2AJ5+D*wc@H~9UtH9j)UT(hDke4ljl%1Wj>L5;f>J;4?a|5lc-{6D+6_tv@S?3wAc z3o@B5?8v)W`lQ72N_OS>uMBaF91Khi3>OxJzguBw7Hu)hGe>s5y}kAC8&Q8|oZr6P zLP*>F)%W1n^1uIN&CTa`Saaa9f!{{1-oqBU{dZGix0OnMJGD7{|CHHbPJj1*E(SM{$Y7JPMG7UX>Ke(cA1lOuOb&)1j7?|<@P|G9sULV}j| zotk=ksr}yLQPG(aFYRmk6pN{01R-EF!8_i**75~mDKqsTFik*R>&V<**G_ybUAPb`d zg8&2L1s0$;6&QfN1%@mT*mTDppjwR$^(I$e*}(9RWCHNfCW9jYzrs>q#H0s&>w}rZp-`WYuBND=zDSq~?Bt846+B!qlB;il&U(Zm>GDb*5hJQoGZuvvP%1ZhgJJ zNBOABshpO8G#Q@rN_VtMo074*Nh8>n`PH!E zkAW}L*tCwpCT%0ws>oD3B*C)qxK3rVac}OW0gFBEelz#xQ`@^ltvwPFh<0ZvN*n56 zCUuQZIyDPxckyI=cD*ZOXtkD^DYa2%XlkjwLt=VuzPQfFa@+V_pPLVfFII^AoX*R; zEb^HVFU$TK++XynS=&gqwkL!$XNO3+Ym1HEr=w_>zviwCW7n1zA1OT-d`Tn=Nrb-Q5NhKE6KjZ6^= zE`a3LyVKJ|vf{G&LULB1FFd6NO@z}$e%X?Hrt)LVCSWH9$wxFUDP^zKcN}%kW7tV( z#^h%RJRSUxd1rz^$z0_8x~De&%{lrEH;A_>T$59&`-(h|g5>3r(ng^hEQ|q^5#0uw z+zlXnK}3To{D1?J1TWoeED?5=7XXsMkKPTrLj(f`xl?}p`FwVyYXC6OBZBn&_keoN z|K#tnTXJ}}`93ql@lC)H1O59Ypj~Qm)=vgX>qkpKVy literal 0 HcmV?d00001 diff --git a/dev-assets/doodads/regions/power-64.png b/dev-assets/doodads/regions/power-64.png new file mode 100644 index 0000000000000000000000000000000000000000..cfe47f55a065c001c773b19937b1e605d2e3fd36 GIT binary patch literal 873 zcmV-v1D5=WP)EX>4Tx04R}tkv&MmKpe$iQ$;Bi2P=p;WT@g`K~%(1t5Adrp;l;o12rOiL;hes*%ypVWNMI35kRU=q6(y8mBSx!EiiH&I$9?>Ru3sXTLaq`R zITlcX2HEw4|H1EWt^DMKmlTczoiC2_F${F=0*#vEd>=bb;{*sk16O*>U#SB#pQP7X zTJ#9$-3BhMTbi;5TFDGXRq=5hc0cJ@=K~#9!?OR(8gdhwQ!qL1F zXW&lW&HXYVL{YRY?RF;FpY;J9+Gz_hG9vyy=5z*m%Dq{DaAUC7A1MjdtUQ?W@vkjs_5yBKQ#o} zRc=Xv1~jW?P6NK+F2;LWBUzB8853-uzk45NwVIy1@XMg}FR03E(FQNfuD}iF= zI7Bv5PUtH4|8*9)D||+>ME#TW0ssI2z$;AT>$8-nq8Vd^lAmgAR1 z1ihp?6COadabh|Ir2G7+)p#jSNEVFeBqM4zUcw8aN4Hng4Ql8^f@kBW5um994W5k` z5y7joK`na^(d){Kg}}_Se|2?$#w|B-4^S5Z9ydic}*5j~)%+dH@S4~lN?GB5S6^{}eLyiQl4rt+87?yGM;FC-G8J8w3*nm5IldZQUej0Ta5>j_YDf3X zH>+-Z?Gj-5k}T46Mkm>C(xeZv@!vTkmQ`2g9BpXuusO|hS?!*}yn9=C z&;33k7&ayJQSl?g$$B1tPLv*fY<`Y)I_o@1!^>7JvJ+ToF(=lyAYIA`CcGo`bfJrV@HCnz{MimFaYRCZhK*VQWW_IT}|=5_H( z)1B4{Nmz;nG_u|N+Wi0E`@FS(p0rFC>0_R&-}l*&r{pbD@2tl)^45NjSvc&N!>dlm zuVgl!zvOyU)EAByciHsTMbFyA9`lZY*}pC4)H;zRnom9-_$^r*EcRkIt5bGd{@L0& zb_|)Xv?`fpWSEp$PsM$&EHAIl|35GD+jnLS*P_l(3HOuX@eA5~sqbZAVDk5LaSW-r_4ZC~Ub6xN zTS9Ktmb)v{U(BuA{&qU2a+k+J{dwv)=a)Gj31?A}j<;Wbf8l}OpXG|{%TF7w3wsy( z+NP4H#FxR!ye;qL&wqQ4Z>>zXSP&zX;WuBO*Y5g0 z{khWqPoGY+5C6Y(Kd-(2*1%W4ZP_26pCdfq`lPP-r;Nhb$G@gelbpWw3Sai|tib)t z`WY^}CO5ouG7kU$;hcT7euNF1hwWkSd55dZ^0$indcBsPUbyUY{j()@HjS%e4_p&h zkU66}HQMOJ9bE=X_MYZ|$9fjKey=lKydrY{UbcqBpZ$BKKJ_IxOmnn2s_@}<*OA!A zg6cPl|E}&~oF>*3Ww$t(+f(;d!Lm=!uZaW0Y{8_fu?JUL=DcfTv+h5yx<_ucw9_-a zv_F-v79F!r(J7eYeeL#v{K;Z^OP{qVl%KviGk$B_!Np_6FMa;5H1P{VFVlq2PLEe?PhDFj&$z;(E59(k&9+~`gzJFlvVuZ^6(S95 zvstpGHL~8%Dcx>9k8PP$b> literal 0 HcmV?d00001 diff --git a/dev-assets/doodads/regions/stall.js b/dev-assets/doodads/regions/stall.js new file mode 100644 index 0000000..c174594 --- /dev/null +++ b/dev-assets/doodads/regions/stall.js @@ -0,0 +1,40 @@ +// Stall Player. +// Tags: ms (int) +// Grabs the player one time. Resets if it receives power. +function main() { + Self.Hide(); + + var active = true, + timeout = 250, + ms = Self.GetTag("ms"); + + if (ms.length > 0) { + timeout = parseInt(ms); + } + + Events.OnCollide(function (e) { + if (!active || !e.Settled) { + return; + } + + // Only care if it's the player. + if (!e.Actor.IsPlayer()) { + return; + } + + if (e.InHitbox) { + // Grab hold of the player. + e.Actor.Freeze(); + setTimeout(function () { + e.Actor.Unfreeze(); + }, timeout); + + active = false; + } + }); + + // Reset the trap if powered by a button. + Message.Subscribe("power", function (powered) { + active = true; + }); +}