From 2b91a49997e1552f4174c519b4bf12f8c4fc2c35 Mon Sep 17 00:00:00 2001 From: cha0s Date: Sat, 27 Jul 2024 09:47:17 -0500 Subject: [PATCH] perf: damage rendering in CSS --- app/react/components/dom/damage.jsx | 69 +++------- app/react/components/dom/damage.module.css | 121 +++++++++++++++--- app/react/components/dom/damages.jsx | 1 + app/react/components/dom/damages.module.css | 3 +- app/root.css | 5 + app/util/math.js | 5 + public/assets/fonts/Joystix.ttf | Bin 0 -> 47604 bytes public/assets/magic-swords/collision-start.js | 9 +- 8 files changed, 143 insertions(+), 70 deletions(-) create mode 100644 public/assets/fonts/Joystix.ttf diff --git a/app/react/components/dom/damage.jsx b/app/react/components/dom/damage.jsx index 83f431f..893cd46 100644 --- a/app/react/components/dom/damage.jsx +++ b/app/react/components/dom/damage.jsx @@ -1,72 +1,43 @@ -import {useEffect, useState} from 'react'; - -import {useRadians} from '@/react/context/radians.js'; +import {memo, useEffect, useState} from 'react'; import styles from './damage.module.css'; -export default function Damage({ +function Damage({ camera, damage, scale, + zIndex, }) { - const [hue, setHue] = useState(0); - const [opacity, setOpacity] = useState(0.5); - const [growth, setGrowth] = useState(0.25); - const [offset, setOffset] = useState({x: 0, y: 0}); const [randomness] = useState({ - hue: Math.random() * 10, + radians: Math.random() * (Math.PI / 16) - (Math.PI / 32), x: 1 * (Math.random() - 0.5), - y: 150 * (Math.random()), - rotation: Math.random() * (Math.PI / 8) - (Math.PI / 16), - }); - const radians = useRadians(); + y: Math.random(), + }) useEffect(() => { - setHue(15 + (Math.cos(radians * 4) * (5 + randomness.hue))); - }, [radians, randomness.hue]); - useEffect(() => { - let handle; - let accumulated = 0; - let last = Date.now(); - function float() { - const elapsed = (Date.now() - last) / 1000; - accumulated += elapsed; - last = Date.now(); - if (accumulated < 0.25) { - setOpacity(0.5 + accumulated * 2) - } - if (accumulated < 0.5) { - setGrowth(0.25 + (accumulated * 1.5)) - setOffset({ - x: 80 * (accumulated * randomness.x), - y: -((80 + randomness.y) * (accumulated)), - }); - } - if (accumulated >= 1.5) { - damage.onClose(); - } - handle = requestAnimationFrame(float); - } - handle = requestAnimationFrame(float); + const handle = setTimeout(() => { + damage.onClose(); + }, 1_500); return () => { - cancelAnimationFrame(handle); + clearTimeout(handle); }; - }, [damage, randomness.x, randomness.y]); - + }, [damage]); const {amount, position} = damage; - const left = position.x * scale - camera.x + offset.x; - const top = position.y * scale - camera.y + offset.y; return (

{amount}

); } + +export default memo(Damage); diff --git a/app/react/components/dom/damage.module.css b/app/react/components/dom/damage.module.css index ae70dbb..25acdd7 100644 --- a/app/react/components/dom/damage.module.css +++ b/app/react/components/dom/damage.module.css @@ -1,25 +1,110 @@ +@property --hue { + initial-value: 0; + inherits: false; + syntax: ''; +} +@property --opacity { + initial-value: 0; + inherits: false; + syntax: ''; +} +@property --scale { + initial-value: 0; + inherits: false; + syntax: ''; +} +@property --offsetX { + initial-value: 0; + inherits: false; + syntax: ''; +} +@property --offsetY { + initial-value: 0; + inherits: false; + syntax: ''; +} +@property --randomnessX { + initial-value: 0; + inherits: false; + syntax: ''; +} +@property --randomnessY { + initial-value: 0; + inherits: false; + syntax: ''; +} + .damage { - color: red; - overflow-wrap: break-word; - position: fixed; - margin: 0; - margin-right: -66%; - text-shadow: - 0px -1px 0px black, - 1px 0px 0px black, - 0px 1px 0px black, - -1px 0px 0px black, - - 0px -2px 0px black, - 2px 0px 0px black, - 0px 2px 0px black, - -2px 0px 0px black - + --hue: 0; + --opacity: 0.75; + --randomnessX: 0; + --randomnessY: 0; + --scale: 0.35; + --background: hsl(var(--hue) 100% 12.5%); + --foreground: hsl(var(--hue) 100% 50%); + animation: + fade 1.5s linear forwards, + grow 1.5s ease-in forwards, + move 1.5s cubic-bezier(0.5, 1, 0.89, 1), + shimmer 250ms infinite ease-in-out + ; + color: var(--foreground); + font-size: calc(10px + (var(--magnitude) * 12px)); + opacity: var(--opacity); + overflow-wrap: break-word; + position: absolute; + margin: 0; + text-shadow: + 0px -1px 0px var(--background), + 1px 0px 0px var(--background), + 0px 1px 0px var(--background), + -1px 0px 0px var(--background), + 0px -2px 0px var(--background), + 2px 0px 0px var(--background), + 0px 2px 0px var(--background), + -2px 0px 0px var(--background) + ; + scale: var(--scale); + translate: + calc(-50% + (1px * var(--offsetX)) + var(--positionX)) + calc(-50% + (1px * var(--offsetY)) + var(--positionY)) ; - transform: translate(-50%, -50%); user-select: none; - max-width: 66%; p { margin: 0; } } + +@keyframes move { + 0% { + --offsetX: 0; + --offsetY: 0; + } + 33%, 91.6% { + --offsetX: calc(80 * var(--randomnessX)); + --offsetY: calc(-1 * (10 + var(--randomnessY) * 90)); + } +} + +@keyframes fade { + 0% { --opacity: 0.75; } + 25% { --opacity: 1; } + 91.6% { --opacity: 1; } + 100% { --opacity: 0; } +} + +@keyframes grow { + 0% { --scale: 0.35; } + 33% { --scale: 1; } + 45% { --scale: 1; } + 40% { --scale: 1.5; } + 45% { --scale: 1; } + 91.6% { --scale: 1; } + 95% { --scale: 0; } +} + +@keyframes shimmer { + 0% { --hue: 0 } + 50% { --hue: 30 } + 100% { --hue: 0 } +} diff --git a/app/react/components/dom/damages.jsx b/app/react/components/dom/damages.jsx index 0df6e0f..e0e1f1a 100644 --- a/app/react/components/dom/damages.jsx +++ b/app/react/components/dom/damages.jsx @@ -11,6 +11,7 @@ export default function Damages({camera, damages, scale}) { damage={damages[key]} key={key} scale={scale} + zIndex={key} /> ); } diff --git a/app/react/components/dom/damages.module.css b/app/react/components/dom/damages.module.css index 6a815d4..acd2d67 100644 --- a/app/react/components/dom/damages.module.css +++ b/app/react/components/dom/damages.module.css @@ -1,4 +1,3 @@ .damages { - font-family: Cookbook, Georgia, 'Times New Roman', Times, serif; - font-size: 40px; + font-family: Joystix, 'Courier New', Courier, monospace; } diff --git a/app/root.css b/app/root.css index 369ce5f..2a868e0 100644 --- a/app/root.css +++ b/app/root.css @@ -31,3 +31,8 @@ body { font-family: "Cookbook"; src: url("/assets/fonts/Cookbook.woff") format("woff"); } + +@font-face { + font-family: "Joystix"; + src: url("/assets/fonts/Joystix.ttf") format("ttf"); +} diff --git a/app/util/math.js b/app/util/math.js index f7b1b08..8f0c64d 100644 --- a/app/util/math.js +++ b/app/util/math.js @@ -27,6 +27,7 @@ export const { log10, max, min, + pow, round, sign, sin, @@ -317,6 +318,10 @@ export function removeCollinear([...vertices]) { return trimmed; } +export const smoothstep = (x) => x * x * (3 - 2 * x); + +export const smootherstep = (x) => x * x * x * (x * (x * 6 - 15) + 10); + export function transform( vertices, { diff --git a/public/assets/fonts/Joystix.ttf b/public/assets/fonts/Joystix.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5fd36a5435f787a86adba9b38736d0f7fdc86687 GIT binary patch literal 47604 zcmeI5d7NEEnfI&C?IlZR>2x|9q3KR1orEm(p3Wk6Rs;h72( z$?G<5zxXb9%?n&VLGxQL?B2TR(DQzsbDtasJ{N4*yk^z-?7=&n+jX~dC1-40b@7(u zSa&(~&!Tr*%tAzYb zZm4Ue5A~G)WVp^`7WiwqQ{sC)+y!Sla^9rt#Fq_De3E2JZg$D{N4n0cwE1agpS;3# zy0NcjGqvE*1I|6Q&VNexle?0;IMfQd+rt+O?W^z8w8Lz8m7bSgtbFwWG=k z>f3o**6(PrVq1f+{`%E<-Rp?Y>)tPfGf>@>o z@p!)wzV7Kd_956Q-o^u6>t5Qn5cfZKK0FU6g=a_gRrvjLFjBnx*NOP&;Pk)$KfQMS za7*!QcpX~)Qa_{qLc0`xO3&-T`%CxL?yr$gl(pKVGB&vj##ZMJJruwArb9Qza~=Em zsw};aFS2Wur{DCR)dRllG18UO$Je9t|CjQ~d7M++|JRPG%>Q4~`hSxi(eeM1roX1I z*YiRBd7r{`QSKbgE;OE`em1q4cr5ahsn6t|ALN{kq5bNo{`Idq_QzA#!nLqG#a(5E z^s4{DdjHe&!v4%ZM7Sw^g8P^H`g8aD-LtVR9dic4*@ga1E`_*F{$HY3eg1b~^{-sO%q!rE1CRTpjr&H;KI7)ss(lle4e7DQ*gRgKHq4>ZX!UbJNJDyXo0KxTD?C zkU4jlA8plh1K; z$U9s|w%5&dbIIqqdF1omeDVcu0r?x;8?wK5$GT(5-{{^*-sw8Y7rKSyi`=5@@7!Xy zn0$#_LcY{3C12*2kss%d%l?*#^-bi*yW`1Ea3_$z*}a*3xm%w7jXTkuNPdz#iF}1y zL4LA3nfxv8E!khYQ`{-!r@B+gPjjb{pYBd4Kf|4oeaW5a&Lls}okf1OJDYr^TS@*_ z_txyM+&S(X^0&FSk)P|%C4aknJNbF;yzDRCDz}P!wOdWT#;qama$V%zt~>i*ZmnBO ze!e@Oe4SfIzTT}TzrbCPebHU$E+pUJHjr<08_74hP2`*1=Ik%r7Pp1`9qt|ETisUj zZEhR+cDFtIg4^MCkYD63B7diQC;7$hV)9GeCE1_5OWmd9?{e=Vzsy}m{&(*0$S-%7 zXMg72?cPm(g}Z|M@7>>%U+JzSe~)`l_NQ*A+e!Xj_g?b%x%ZL3-@TvwDtA@(C+-98 z1LRk`tI7Yt{R8<2-3Q4(KI%S7e!aV% z{2$#vlHcHNApe;ASoVP1<#v&O+@)74-9M9m)qR!xYwm00cep#qzwW-CecFA) zeS`d)?wjOyx;x3g<-SG!ZTIc$Q|@2fzmVVM?jrwJ_pjvNao-{TH}`MZC*9rdZt{P3 z|4x37yNCQg+<%bY>+a1y;lAs>OMaibkNkdjKY5SqA%DO1&^<{0pYA`&A94?o zf6sl7e6QP^ecXNDeV_bc_b~Yn+z-efagUHc>K@HL=JvULSpLNfY?|1vj54Z#5&$;KakGSXE^W;Bq zKOz6A`ziU)+|S5=?tY&AfqTKdK>iE&3-TA;i{$_1{)_yV?w8qz-LKrQ$X{|Vk^kEL zn*2BJH{`!{zs-K%{m%W4{P*tn~>|XZ=_XqM<-K*q(bblm&&Amqc zC-44KE4{?J{F%o9$$V0KKw|0_fh!lI(&6KK6(nic`816 zI=*-YK6nFT33DcW3&a_@CmJ-|Cr>n+|4(@MwP5frS)sqtf5Lyt-|Tn$PrCQ|pUVgNFZ#Rv=lvHX3IAF5Hh+`GbX)h(s`4*Cw+IyRZ|{pC~FwiFu$R*VNt_*4Qm?C zZ`j=Mx&8k4NA}L|-PpUW_fx(1_kOSU$(M(|T>0|Ems?(*`|=xK&9YV|Yp7+kdl!E9 z%lOIt?hk&hU+7POQ}2gU*BGaE!Ks`5SNzxDRIh(E83(5pCd&&rbzkyC#%0QiIJF&4 z?Sxa;WIhY0TuDPoW683TlS|Gn*;;aS>B!QFrISl%!>OcZNX@94nwm*93u>0soKSN{ z&B~hdYA&d`qUJg{b#u)t#;K~>akUd`YmHOQwR4SA+iS0={e0~|!>K!K?}AffBBxHR zdu!db#;M8zPIX02l{SoQn3v;Jcf_1@R}Q12rz4|#d`%T+Je zyxjis0&yz)V)nW0J=vb@=bX#ll6{|aR-f!5zVovk+4gK3XR||T-!H=P(91gZZRy)Y zTHAMa->^f64n2M7sYCk?eeckHhweS}ABX;p#mG+`y5P`y)jZVA)o=K+UU={}m873P zJ&>LabbRjnDm`$`v)KdhKd|$_dk$QA;N1rSa4wOftCZK4~#lcd0_Z~ zVf(+e|C{^2{Or^FKePYx{TJ^)?%5}w{ob<=J^S5f?|Jqc&))d#d!D`GN4uUm_n9M~ ze*WpFp8nd?UwQhrr$6%aho8RY=?^{q)=8P+2i4QCk1Oy089c4fulgF@_Y<)EJ^rh# z6^={mC!@F;m5ffta2$g+P2gCQ)TZ|bJ|-ohJaI__^)Kan58oI0zMAx9UdX(Z`Ay~( z-2W??S2KO+TT(KpWJpOx$?%eqC8J8lmDH3>V^wxq$=-qC|8JL;Tu`!s{&tpJS8{#H z4JCU@ZYlXv$#+U#D0#_x8bK^}Io?b@?Mh;_op?kdGR0$x#uSSw5>p(eC`>V!;zC7X zioq0tDgILQrPxc6m*Or(U5dFBaVg$Xw53=}krr{*3`JRru@qq`zEX6h*h-O=;wnW| zim4P)DV|a^rC3TnTyd15D8*2UpcFqTdQ$A9$VqXNq9(;mikK8HDOysjq)16|lAOJc@S|?I_k!q+`$pnRrLh4&%|Uhz|ZhRG`uFk3dP3- zX8?DmFZYA|U_ZnU^%Z`YtM|i&n;+q(`jNiUkMdP+mLCmnM@P)2xOQJH%>JsnhxdD& zKhD>Z>PVAF^`yz9DWnF{RMIrkbkfnJ8Kjw{S)|#dV@QppCQ`F+*38bgkXlJ?q;}FA zQU_@+X`Y{#l=%6i1*A8SjwQX3)Jax`1>cX#;5!X)|dH=^do4q-~__q#dM- zNbe+FOuB@0Dd}CL%SeAmx}5ZG(iNn?CtXQ;4{0aqy`=Y%-cP!U^a0YPKG2ylZsr~uw+;= zoHT+ol2l15Ps%m7#1D^3sz{?r)k(GaAbbpdc`RuhUORe$WPCD#bOdQ4=|~bocXAY| zmQ+V#$dxRTdeUUllw^w5Cz1v{_TS>Ozr|;Ni_iWRpZzU9`&)eWxA^RD@!8+vv;V*1 zvxN2aj$~Kn1=c~!*``!iS(mA-t4wzFRrubnzI{CEHxF82NmWp&i~ z`f5v+Ep2tazO5zM)uoT0*|&wf*G_v5E$L!?b&sEE?Mhi;9l?q!ZQE#(;XA{pXKLR= zE517TYrA>`Nm=N-3m9jy{(2NUyXd*izHKdP-_}xXUodLXjfe|i!l%bTrdK*bk7ote zB?qDBhyYPA+v-RLQ826PNG-`hn)g81KB3mrx6jY)2amPmt*$G15Ln`)_*2Cio8cy*R56eS~ugpeB4m*B~*IQe(SInElO666lib3gng~MPh=TOt&{= zccV+S(C#``_l-TvWFcfPMQtSgb|9;?|CDt6IpDx*x~ zXT4$3Qf0aq=ne9(HhmIz1gE&kUF3blHmjB82C%O#Y=HB zdEkCT({n$3K@L5t3tz|*uf28fWs236KBs)4V{y<2-KSm#nCMopEIQ>fz~EUB_oNX? zLN8j$?u>d_tV`m4PLooNN{{I10H0KWf*R3hl7l_WwBGc@1XbBmEvtfe*Z}&}lC(xe z#1f$<)e`YboV3y$-<;__e4CDji~r;;$%80vcQ;H^XC8(R6Nkwv2 z-a00;Sx2tjrPHKGRy<(z^AP$UFtuso%FMheWdsE|MAam9^F6SYA@%J5~4 z*(FR)?vl$k*9N4Z<2nA0m(RtQLhZljeHB<%urc$?gL$rJHe@<( z-a-~<@X#^5Y|ds;290y*6?Pd?)KqbiWb~U~iwGHFg_-netLsS~WS?!o4;m}^$|{nx z^hI89OFkmsUplJ74W-z3+Fz8H@nB7NYLcGeQ#XaXz)&S$L^i*IT~j;M#FUe>3M;Y?3*7VaMPO6l?`sDQs8CZU^&zMW){}RYHdd z(`vNEY*Z>Bf(?Z&VRSR{3-G9v?FS7+T3`Yn;a>(%A{#L|S-2vsfEKU<=1h@StRwx$ z`~1jcBV^!=6jBH>Ix-9iJt=|Vnd)?^qs)BJQBu%PQ%>_D1+vFBQwapU*BB?g2W)WX z#W+H3&X)(NBW-yV$=r|$IthqyWn($y7WA3Z8EJIT@BwrNha&DpyX!=Vn$r*`hp|g- z+tRTlr?aVzgpnX}rO--@TQQRjq`ZnVKjW6+q&Sa;-D@=JYD9w|`GS7<1nCP8CB{L+ zK$dFOCLZ){33ii4dWIE!`$2JD5of641tSl^6Lyo?sToDyMhnMm<2xRqAmwbMI&}Z{`n%}>st82{~e8V1eHMgEHC+da*4Cb_oC;6a9*seH=S3o@=CgBOX zOa2ud4>67~>M0|U<|MORmKj~h7~RgTFL|*lSO# z5!tAb2OE)uR3#Vn+u#)xnKp6EBwn|5l_@eq(6ya+t-0WBzjH&B%F1mzU*{*)6>y!}Lf z!il#_L>769MOU1(Yu7IS?vI~%qWr1(o1NwhU^Dv|X3EtBea5$a3_oF(T$QQ<$}tB9 z>{(;hBh&9i$oh-xA?#`1O}wYIlQ=?%>2Qo_%4npbB0mv&-+eSQF|ikIkJbjkr`&%X z_7FQ3m3C!r%t_@HRM)yAJ+c=BR@Q{O`G@3HZ!&ud@Dgw|L0vkFDLj+9N!%tyXGafu+WP zdiWclbafTcc1NTwlhf6(a)=KW@0b~Zc#~kSHFJmCVLA=hg+o7mokMT2AsSM6E~S;G z$o6cWE)MXq9QuOgq*|Ik(#K$Y1>;uK2l+UyY05s>_ZGaJ#-Qpt@gQA`>VKSqxMX~y zsja@#I!I&Wd~e|_I26uP+Z6u`6M6&QqJK~hx3LkY8SJ)cVW+Jm0dQ?d z4cqx}SzlX^O)=K!9Y%?u+~Co-FD(%JQ*;9Zb9E!`GYwPWHZ+Hu)(0zDPa4mz;W~B- zPiM!{e0XQZt8r_N@r7~Xzt2GgCTmi!#-13x@(on}D8&Pn zKgo|62P$8YRfD)LK>Vcj1>!%jmA=7YMFT|ZD1*qUB2QXD+9nvL^*zMy(1T;>MY>G- zxGR7b(q4lvYAty z)a4ieSKx`*0+Rx_i)m~$oS!5wE^o5(MNbS|zH-{Y^zbsb&}4Z5DrNu@>^F-`Mn0P%bzuARt5&{+CnFwA8r zfC^Z8g-S>)e=@jDU$i zru(Mkt`Eue!H4j??JUkTYC1hznF{$CEGVq7%0q^s4SyAA%QVLb`w%k&g$@v>ZjK|5j8}T1WM(?25Ov?vas0P8J{-)3m zJUX*K9-;ivj)BV`ZyvaOpG=?#z8r9w+xJjmx#$mee>nZ2{4o|Bi{XUw$5me7<0=*V zXc;t3C}XvMSW{?dw$)4thv{6<>w#d}w6zH5>GV;?uR!<=Q2ve>5{0-uV`7csIQ~*xS`X0G7Hl2R1u|?OJ$q33<@vc4spB2 zq0UZpw5PN0RrFiYyB1Cuf8vKe@;V!QZ|Y}4xnvf~Q>r1YSn5b`|uo+C`)QiNsqk^(3!!_x=0o`!9Nc zHB=U{4}D=R;Iw*MEF-NIBU6pH;%BfcXqsi^=Q3L@u0NZCa(>S#1IUl5#O;c;@qC&S zk%+hmd6|TeHL)|P0|ekPAJ#&AzPsg5hG$_m4>FkP~fdEt0_ft z4`WNtC+6@E<>&4N`~dY$xBKC5(UvI+zE5+yeNqpi6Y&iSZ0#clOLCXOm+_0J{(Xe< z$6lxWDftNGHwyVpL4LL$LsSzhiFp>+NMAEk4!wo0ztVfpJ-vO4uQ8>7pVHD|nl#(N zSEc>sco51DmtiR1cYp>tdgNo%3nIWACHlZ4nL&tp3Wnfy*ENf~+&3u8avn63*%jcpjjvzrn&Js-^XX%1=0rKG3-Kn+g-7ra zVV$ki21fB!oE1AXP@1yI8yT19aHe%OeXtGtasWe>=o2HU$aq_%$v+cd%#Y7v48ABv z73eLj7R&FYJH}GcNp`{c3Ob>R-4OW&_EE(TDZ^MnjtE5oa68R@1D>p_!9Whvm1 zu0hLALf4?6Re9?#JY_L6Ew1Zj;OewmI~@XVGcO1~tBf76Zn-u-x1pxhTZ{N?VLQ~} zeJHg&chUYzCm&?bU0yIfO8g*V5k2>b`$H=0*b8Cv1@OWrnNHIzx2DMRY2qA+*NUQO zg->}L6o)~b3`T6$@$rCce2^6JW?u?8J!p6j&}OTNAYE7uZL--z4`pimUbQxh4&E#A z7L~2cm95LvX3w#DkLJp5r0i%bdoouR;O!)uJ3UvHulHE4tdD;0v$l`t%JO}z2xTrg z^bjU0{K7s(=~(?(Sa9f}s8c*^2x1f7v2MBhVGd?HI9_A@Je4cU_p>k8Pl`{F89mHV zFMY=7%uaac{GmP^_I=nW^71AK-M8sZ;9Fm|qwhXW%N;anZ>?~m>{Tl}H`jl@?1^02 zI(~J0j@5&|xwgA$+oi~uvdg&3UQFL>`zxh)I0&BMQNZlN#v-;h$cMzaa}^Y5d>191 zVa}|{nFS*@*Y3>u9DB;8=Tq{Yrevt2v~~*Zv1ciz{$zORG?zjH1zO-WkLL>s69M6c zY3W%Efwk_%@yYO#UJC0li3G3ex=tGg(_twPqv4JI*bC-5BaU%CLR)+>NuIeyZ8dx; zd=(SIL`zPcCk_L&<@u9M)if+yTib$5TWcN0!`^~%J>ra?Gpuu7-PU9(1tB^lkc}8b zCm&sVAr28rsd!A1n@edx%jBRV6&e81?%<&d`4^sx(v%QWgNqIGFtJk4(RdC57V--y(n78)RYhuL^R~e~6%zvju$TzX>clfyE%XuT*-~~G2U31T9kCdDtXWc+z_!6F zv!9@#6;d%2#rGb%RdWeckx$;PXK*2rOEskerUvq=nz~zDD0R@6JUm-UgEd?LnBogk|>3@iilnWf;j)0}HM4{i;10T$i?{TkZAe z!FV)sh&!=qF(2`P$W5AKvTF-6r*#~QjJNVu;0^>SIDQ9->KH$!TLrj;m;@L>2h7() zkDkG6hnaNHn$X-NY(W;|ttew;2EjaCwwKgKT-mmkQKZ{-9^iG=jJ8^q0*LSf0uX_2 zf(=9$=>W5E*@=8nuo0OyR$^N%XiEQzE})JN60z}zc|x^4&o@6RyP~zIiPn~Z=VG8D z>#(w57ShwzEG{)0LIzsM9o%2CT(|#pN8!9TU84bvXbX8|eJM~`Ur*8M~*5w!nEk$(Iz-r8d?JV6C|jW0Ep^C?k)INM(~69HT$XXs#xDHSE{< zL29Y^8xH5{pnYhZ#un8HSS!lVaHi*Y3RXe1(8jgKh)tl>(Z5SSq@}_lcz7}2#__vo z%Xz>l+GOgZZ7`FfnlMZdf2EHm#4vTH6VpM-q!?G0CQGFr$kv>)0u_1+!b!!Xbt)*8 z@<9SZk>YR`H9)`tt3weT*qr87LO-ub(koJs8JZ-F)Y509T)hh+foxD8(EE>Yyg7b8yEnKUt*UP=Xfo+>2pWMTJsC?MdC5@esj{2dS6BG zA@+;_Im>66f?AwqOctYL2x=Ghnj1}qMYJ`}3+O-_Q+ooGNRh@DYp3x)`e#8hG3dlT zxhtLYZ7F~q;sBdhrpVbZp~MgB29nY+ptzm+PjMixYe+feUT_z|>WoQ+DpdpXPM+za|5Ph`$4tfB1&|p%rJ<^3R4Msnp(lUW9nq!PacMqRq@NBR& z$lDZmAU}aJrFJKb4Qq~2q$@K$o#~@7AWw^p%hF^?Kze0%Y|od1e>SsFJH|X2nkE+l zQLG2dU86iCO~b`xLU0BSVYHLw9^9YGCKrRE4Wa+2LoL;5@3O)`N$RxaxQg+&d1$c~ z=Gv#4D6E4%9p2t_L;Xv3(kP5ldV*G_a3VWXp2{mo&BT+)ib5IkMqJ5o1^Ga-J-nQV z;jsEV3yt&8(+`6a<}wDSC^pK?$Yog?#Pz!j&xvN_NDlqe+%gR0CP)a=B2hmbJZ=Dd zG%wa>yZ&?u&oD1O9M4dGIK83Vp4%7l&Eq9g_yxMfRvby!W((|1mnuUG+?SK3{bbE8 zY~Id{bAa}6muFgNw#8$N;*zv%GlXzhgZT}P8k+Ls##C$$Jw_AI3#{wU_*`4@$XQ+P zgg(-9QypcXs6L_}!>+@g<5cJ9M{!1sW@4|xHU*TPM9-XFszL$WF!zRMZGt8*Co0mx zFGiy{RZ|O742`P6*#pV2EwpdNw9!YKWnk%M;Z{{@#X6aZ1sw|pp66p6C$TI=7aCS&pPH2y_~7_EVvS3ThSnpa zp{9WtGCB{7tus82O=!%mGu~;)3ctC{`*ZCbcVi{+B5ti171eL196691oE%=QR{!zr-hTDlLVd}t0N->j6W4xnmV_0U z#vn02?*^MCF|C#%*@W|kV6|pWMwf7~n9%kCwTHgc6@8^~C38|@BSn>Zwn|8;V4pd4 zF(1NSl*9M5hVtD0E$O%Q70Sbyk+&KA1oICY?L?D$jmgfmmMOg}_#I=^cOyxQu>E2z zFqh(m@kg*Unxe+#_#*p7pH?zVm0^=cBCHBG5R6GN711Ue5LF5d_3-vhc=2CRPy_!N|vLy>h~D*X`Q

$T|Vx8wR-~5Ypo^y}@x%K%vnW_QnJfC?oU*~n;ygt6#U!23Yz@G5&VNAzNp|wFWUq*9z9t={$1WltHieq*x-C~L`VpTEZ$_rYP8+u;D zcchJ36ps6S@;0n!b$n{WiYE*jtHE{S?YTi*ix=8@`reNWds=Cyyfu3FZnx*90>9y0Atrccsyz2U5p`k_8;ejLB8~5F*7S`ICfvo zkDUY52l(Bt&Va6=&qSObTY_GpAt4gexDv<6o-PJP3;*ZSU-@x- zzTvj$K@NwNM_T0jc)E44;JsPw7?4-O7(IV8`Hxmcim~-16|-d z-=}AL0x}v(^Ejo54FE%{KLNM@=KJ!10lvE;zBbd%m?D-(LY6cl<>s<}1ZB0b3nVdprWWe4w-jUSGgVzjg8J+Y@0-viN z0!QCx??;eIVwdgx2>Y5ub@;t1&%o;2^!_S#LF9g= zs`Dz!F*MB?a(JZ}3SVs!k+sI8XBgI%@Ma%VD{GbI5CJ4;g)gdT;jHNwI(%(zFAC9@ z>Qv82(#is=PH+kwI2S*Rm*R(b8KXhTJ~W~aA~a*7S_oD97$1>UXlHSrg1XSobVt!- z+EP(u{0PtTzR%F{xzJL~H=`^4Wo-YWKQ{$Yc$9S&B-!_#-0!=;MlXo9sO*~ql-)T% z*|!EL`}P23|1v-so08Nov4H6*JPN-LH(#rWND;A~Xh}0|B+#@@r*hXS06?xS^K@g9Vj@W_-{bX`=OT+V9Jp(76*L(pDnC@wXmc-x-S*QyOxr1ONlR_B!{c!lb zuyD0sS_{q|A!oaFcyNF!Xf6oKQi?)+(W5#d9n+sY-f^#Rq3nbQEerV+_Fh=8P!Ms) zLKSk_`xZj~SgQdlY8zJ9z*pl$Xx(Oz!n3{L1p?(X4iLd*jF_~HQqxt^}-4EuSwoG z4C8u1rtZ{X@r_Uq-C}^!N4(0xmPCbkLwwDOs(z0pBouJr+wrPQIId0SmBN;|MmMClogkWp88Q=rqNV(&XZgTy*9E>AAnq3NV#q+8sG zLZgo;7h*rwcGyc9d|BXPlt`2lGGf@1a0CI~ArwVzfh;D~6T=NXfpf_NQVxXI{Q$qpxu$Pxa;8XJ)4h7_ z+SU9o;8^9bpN_|He0EGFf|tDzen+57`I_*{*_q9rENI-Xt9 z#FApC;5;L3K*-BcZ;ObdjOw}k*jOy%fGKF?BxL)+DrH0eVEyna~*eX%4Pyin0hdvplk(nnm=t3 z6vND94~1ceo^`LGP3x@e%L14zvCx;6N6Ud*=^KMG(8XAe3u{6zJ!IO`9J>D2A>N8} z=#YE`FUh&Rn|HZ%^*zNqar&0~-}epc_E+$39Ar=wvjGcztk({jYL5KEMsf#$OeDGn z1Zwin%g^S6x!I@e8C=@z9hJq;mNZirpkUo%Hhdr@(RXlN?r-_$tP z&gcIvE)G^HOvEozAus1Axf?cl(UlNqnqUY+oJ}1O7{L z2?Lw17nKS*xoJCMcm*Hx;&v@&2gQK>&`^l~cvhNc@mt=x{Flpx{Fh2BGjbb#7gJ() z!1cd_ecYvyqXB0A1?+Q}>LjX1I4MRweOC{>FJ;}R&fd_|R7im&faeW#pp=8Cu0zR2$O^J<17cP8}_?$I_f;i4s8)2#zRx@fa53{fH~R zLgN>4cTR0-lqw<lVlLWNg(i_ONW%e!s0iLETvxyP=sY*hrl(|DO{6j7&Nd}Xe782)u>gFxQb>b>wz@xoM#II(Gsm6&ifqf*>8 zP3Rlq5iv9MDHaaP_VR0R%;ihX`Yf&Gn!c3!+5O!YmgDn+9hH# zFubFM1&ue2&`vPTOYIX6b{-?nE?yq5SgH`Fe$)^mv zIXh-8jeY8Rdj)Hz*jI?%*4Vo?W9%k#v%Z3dpg--H3SKsJ6r`;P+K31-PQDMt-e$8= zB@LiL6B||)b>%-OjE&O)5ak9e4@;VWIT=Fz;AqIuz@hhc#gCwwHj)=W)ZK#E(te+* zU&ZS;g!YSg?Z>irIxo?gE6|rrSiu+1%5B~yvyfr%zPS3pMKn--S$~=dn>50lH9xmk zpHcVHo{4u%yG5R&WktvZ*cd!v&WWbQ!Yq`D#KKrc`#!^)_d+zNRUH|v>A1}jz*lo8 zjr-~?6Tk8iI#*fn6R8dNi(v{}tZ7?jr@{aPXT)+BlsGj>${#{^j8lU(+gmdOR#-*q zh4GGhx2n3YBG(yvsN+s!BT_CZaKPkh@U2f{M5w}PYBM%oXm!ApO>V2&XcOqL#>P&7 zK>##pb_gyjp6X5raTxsab8yWi*lC3af`^qv{BToWi```xMm=1}c|jZn=Qh8UCn?-3 z4~}?i=3Tb#CLaO$O5zG@hJs-qNEdgFQaixcJWi=D88;Pgs5Q`Fqt+biI19gVVQ5Be zY(d`8V?miCP=lKYz9FoQhxG~|h+mcryEd@P+pJuEst$&m98V1x_E7Z@ z^TLWSr09yy?yuSUH9!(_9;NY%PzI8hD^OtZ7-cm&%-)M zy4MSGr-xOftB7F zfATgUuQG$UGF7Zq1uFf>sr1}^x0Vz5*!_45AC8=)7f~jR z^WnD)*sAp=R;mXmi8jbNXU3sDCghx?1)H8jm>*vqst8Q(gO0V2-}b0z&2$R$q!wwQ zVQ<_DvLBmgn#j`a>eMeWvk;}GVR`b57SRYI5=^Rkass(p;enmqmJJs8Zq`OkYU-%a zo2qN{QNFN^HEuqU(6lS|k63?cFQS_cpcsDUe}@u$t9Bqoh>WzHRT~d&ecLoeq~<-X z4ell^>lot1PZM8YuY^XVlii(}pV`T*O>;JSKr0Mi$*Yi>$V&RK(Na$W0(I2$qt7|V zZ$78*R~)L&Ip>_W^5tX2|7piVPo8s*HbQ|xf%fF0Fcn7~;$7(S5f*=FJkpbg5JT7# z?B1TfVfSNq^H4bbUo9wr8I`OJ+W3E0{+YPm?=&BvWrx4xEADl+-!Ah!trJ+`x42=i z@XEMHXEF>b-0OSzZ+F8U<-^Nstlz`SiPW?Y!)T52Wxqul(Oc9B&n?LsHD9qI5RDEz zAfT`85LWn3K!vepc1CFz??JHtC_m6XYSu;$R-_$(v(*fYfCxmyU+p{p_X%PV)VFoimJw*b4Gwm2ug@a~2g>vCPiwjrHwu{Q+ z9`VPu{i3kG4}4ys`l2D?Kxv({R#AW@Sx}o|3h6rbL|m`|P6i~TlOdQg7ZBZ{4*B~bJ@RSI2z+aKl) zVqp79WRff-PzPKBNCYdKYDRy7tNx$uij3V~3TO8Jrc-Ry&PW!4I-Oy{KHj zCkW+_6_u-gu+`InR@`qWw|>pv+ulf%H<0YP3HqXuUZy~pU>cp1QY&6Jj%KD$uLVt~ zG>-k~c**Um5&G@#YfL6Zd^nYg(T)euX)pl`)8#h93sp&V`X+YCSp?N{zrAfum+6qJ z@eE9X9oK{y3-qRKJ;{-}g)t^)A%abr#R~SGF7#OKl_6;JNjf(L@ACJfE6;`mJKRvEIXs@^0I5o zZY_JT?1l2t<&EX1ly{Y1Reodn9p(3w?*(2+yW9r~q;q@tms zx#HN06DrQASY2^V#T^yTRlHR3+OV==qlVQCJ9=3Autmc*47+&P&SBRM+db^oVRsCB zVtC2$k;5krpEkU8c<1nQhF>)N%Hh`xzj63|!yg&`5nmYb@Q7zdyfC77P@@JL5tLz&!WYn}#t)n_eEgyB( zsIE~T9CgR2ACG#aYC_e#s!dflR^3_kL{;zTF{3Aqo;`Z`=&hr#8hz8~+ed$A^dqD9 zkAAIsbahSjwCd*S1=Y){Pp)2B-Bo>Q_0H;Rs&`d?q59j^_g3$%exmxh>R(pBHfGeA zjxo!|bd9-k%*|u&9rLrX6=TPZJ$md3W7m!S;MkkS-aGcCal^+ok2`kUS>rAqw{zU> z;~p9J%J`AvCyt*szIFWa@fVE0di>qvUzkufVbp}9C!8>0^@K|&TsPsi2@g(q@rbe` z8jm>Rh|7-Hbwtk*FHRgaaq`3k6VI7=-Nd^mzIbHqk*6Ga*^#@B{OXbWYD#JvYnIil ztGS`(t2KLTUOKAmsM$xYJZkMx*B|wbqxK!uTRXaTLG7DrPpdtzc0=vOwYzI?t-Yi6 z?%IcHpQ!yw?W=Vqb+vV;)LmY8OWnP7&(ys-Y0RW!C!H|qj7gVG`og4dOuA>%-bpV` zdZj+8A6`G9zM=l)`g7_x)n8iwzWVFx@2r2W{-wz^lN%>5nta;iwUaNJeAVO|Cx2=3 zcP8(h{Nj|6QzlNCJ*9KXDO0+pY?*TXl-s5}Jms~9iiVno#)d@=CpD~WSle)2!%Yo$ zH$2twvxeU_^i3TybVs2%Ic@l~Nz*!~oiuIjwB6Hg zo7OY!C)1PZjnn5%Uo!oq>1Rz}J$=LUi>6;c{R`6{n*Ph9ha5fa=o5}!d-Qcj-*NQ8 z88tKBG-Jz*-7~&3bSGx-j0Vmp6Pg@qj&D)xs7ud%w0S8dL{EK9>=v7f5^Y+z&k#{lb{jVyUE+L zyU9B&pHI#{4a=)7ug|_f$;|8pJaZnO-AmqX=kqydb=C4}%XN2zn?b7)R)2&+9^vL$ z`2zBhK)8VX2s@u*d0X}+N(6JH;V{w(he|gH+$vpVwv4=TFO%Ewb*`AGU2@2aUk-r7#EI!92xmt75mv%e>=v-5WH z1}kp>lUq0!y}Sq6a^0N=V5Y?TkEZM)&nZkV^zYBwd~b34#3a2?i5hxO87@aIu~FS7)3a=zW2Z>{EA{RQ0p zxm&=wZQyki{IO_S_|$R;=blx|+IXIzRa4`6297tz^Ab1Cof^-ztL?&gUPk%F@w}Yp zme%^Agv{|BeZ5OQG?n@w|-k6i&H2H#sJj4{~FY55@DroPRc+SGd;XTk(9P z8=m|so>#h2$)7%7+cbA>`>f{1rjFXvF4?lVt9$Fl^=oREZQitfTkY|i)|{~Ul5N}9 zUwq=`O`ErES+%CSZFXa0ys6eeyk4bP zUb}u4<`CvDXcs9EAZVjc&DB0w;yKS5w z&)FJx0wtGly`35tQ+lG+*i6Y5w~G7S?i9Y~yB%%=*IO}-+4P|_pFYlZC-Vd0`Td|A z4r5k7D8;@0<@#qB72Cj3_}3O-@z+8su3rm8@nRL*#SiT%Lz{9>dw;@>*-uN?Nm##Ac*ejQ!z!Bi1hb_`(aF zC;X1lC)iI3PYKGf^Fi465d1&|zGFBe(MZOOQH%_uS#ux543rT8&v1mBNbFw2a}KS+ zO~U_7W|d6;m0%j{J4fTKXQF(wAw%ld%<5SyB5G&1L7L1azDr&@`L>lm-Rz^g&*dJ`w`3{D&4Dol&|umeYGFs z$NF)8yr1BY@Du%!zQ!NrYu$6c&QJ37ezKp!oMWoH-B0t={n35~58(gge&T2O+5Q;c z=$m}AZ}F|Z&A0nGzQfOTKjUqi^O>c*0l$BXf1~g83;iO$*e~%*{W5=?e-rV>0r#|f z#{J0ccTc)!{qg<;|7O43pXg8WE12E9#h>C&^{4sM{TcpDf0jSnuk>&A=lHkzbN$=> zd482&?brA&-|g4>^Zh!%-e2G^WKCtG-{d}phyH}$;@{!7`fYx@-{CLv@AMb@OZ=t& zUH&rvcm8t!ZhwXUdw->WkKgIv%UtUH{wn_gf3^Py|3UvDe~tezd#pag@4iim;a^zm4C_q+W*G?*8k4`p0|F!>|gPJ@UQwm`q%uQ{6T-n_xWtX(mm^d znWQ8sbzgN~bKh{^boaVD+}GWA-IeYh_kQ<9cVAMLl)LXRqTZDZN(LuGlA%dOGAtRM zj7UZ%mC2~2DjA(rCu5Sa$+%>EG9fu4nV1}z)FekGwMiZG()wg_G9_t9rY6&p=~(9n zlNrg(WL7deIVNdLnv&*(|M#A>xn1r?_i;w$e{$Ek-R^Vl!|rOg6xtovcjWnw*oojal;Blk<{Q$?9ZH(v@`cpZd;E)+Otc3z7?y4avr2Q?fbP zlDs3?nrut9Cp(ghSS)>K`HoHN8ylPElxa}G`E(#Y4xhDWyfz{zoDzU{P+m`_<+sv0pgJ3 zb0CuAPY4ZLS}WdM0Ih8Ksx>>dcULSgDlVuUUo`odrD#3Qv%pi?bgs!*R0>VX2-_08@ey9IIXbSX;!V|G?90D zAn)|p)#=t%>FHb7Z#sY2>4hDZpB_jadS)K%(6jUBWh<@MAuDqn3GC=-ipM$exG)}< z#^bVZoZA|Y9r3s%92YjmW30ERC0s9y^_PYE&8?xI=GMi7&)>T0qHYLYJ=jpvnYC$Y zY#wan7L)`iEsgE5M!>SAv18b}&6_V=wR&@a6z>MyTN)R|>&4;N6mV*3T2uk`tGhRB zerLXm<_NkuAllL#2y2t2S-k-o2rF{i=$k zTehv=Kv1XpgO+ZO_m9T{tf*oIK`bT^E>16~JY>bj?(;*X%Joz)>dTOCZE7i9(!F8( zDin3&>aJDES?go@veHx6pTBWcxN2_AoV;!Q=p6y}0AL!ML&e6xi`K@#+1AFnu{`ju zHS(^tG4QUnF|ebxG3Y~UV~}%eQ;=tCQ-sqL*x1?>B-Gjz*xA|?;Wq`Dv^K~7Bimb> zWBthf*5+8hIpWitwu|^g@w7Hae3~OZb0Qucv0X>3-x2H04SL!-H}WCsbL-rQ_uPo@ z+}M6@Y(F=)k9yv^Ft%S9`&$^>FO2OM#`X(i`$e(eMX}wY*ltm5wf4PQC>?Tyd@Fdk_c~U#A9j1V`=PvX{^6A)?XUyFN^pu zi|wLaw=RqLNBeGF7TYh2?U#l2ZB3zlTT^J?)*Sk6i}G)aa%}4`IW{c~ddkt@aWr^M zOGA5(2DfQxv%%wN@S2vk#Comqx;3_MGd!D?w#Dmq!>4I!du-pHmM<VCV#j*Y3Nblmv&d<3#`+JZ^K- z+<^{#yv9Ps=JrPOXBZ!taMXnwA_z18%OV_-vj zu(@a7F&v%BB1W7USt@w1JFWvv1CWv#*IaJ1GOtu;r(lA~eC(L~A7 zuwB*~#wL!&1CE9*N5gViYq0rct-*#lMtH%7m$e07x-9x&j-mgyAbhR^ytd$5m$fw; zZ#f!oImY_IXLB9!YYSsE*Rg%@<;&WF>2eHsw6(l2T-UO$BOfHBPco0+{I%k29MX3tkMDKX97GC07i$O z;O6?HXvKRIfTk68JsHq*0m1Xue_>u~YuQ@W*6O{U2dI8pLr()r>}i0W1+dl+20wS6 zp7yfNq`P_|pyvU48ld~(j-Ceyp4R8}BtU&@eV+doLLRPuZM@Xg&$+i3%$r%c(h~r! z|7-PM^@=&IRe!ghC2bO zF!a>j3-`3bAIeQu^mGCGr1gER?w8PyAc!Aeu69Pb@?QdDFm)2q!2R7u)n2YT3_J9p zxFu_ETCYpj>3Eh?utHaFD{|9Vi_=P6v#q~%gta$Tv?^^CYl5E`wSEXIb5|GHP7S#7 z!FJgB1WqLd*Pb%g3)gO4wZ=7A-nfm?$j!67lW}sJTW0xk+NwPkS9B&TQ)$RUjSLbQ z4h=P|A~u3gxYtZA)x3$j!sDx~x`dL4;_=7v_zXws??|Xz=FVYNuLS!Ug%_B_dZ6}> zkM=*XV>K&;x*p>nwc`X@miR~Fy~Oa)JH%CEUqOw>3eF#o=ZU+@4b?gpE0|}wvkOVk@&et)rd? iU+sDE=+qav&Ili_-%d(cXZtE8)B;NQrGbYx)c-$)8QlE< literal 0 HcmV?d00001 diff --git a/public/assets/magic-swords/collision-start.js b/public/assets/magic-swords/collision-start.js index 004ea66..903f874 100644 --- a/public/assets/magic-swords/collision-start.js +++ b/public/assets/magic-swords/collision-start.js @@ -1,4 +1,11 @@ const playerEntity = ecs.lookupPlayerEntity(entity.Owned.owner); if (playerEntity !== other && other.Vulnerable) { - other.Vulnerable.damage({amount: Math.round(60 + Math.random() * 10), position: other.Position.toJSON()}) + const magnitude = Math.floor(Math.random() * 3) + other.Vulnerable.damage({ + amount: Math.floor( + Math.pow(10, magnitude) + + Math.random() * (Math.pow(10, magnitude + 1) - Math.pow(10, magnitude)), + ), + position: other.Position.toJSON(), + }) }