fix typecheck script, animations

This commit is contained in:
Brian Beck 2026-03-16 18:16:34 -07:00
parent 642fce9c06
commit ceb9fea9f4
120 changed files with 1308 additions and 911 deletions

View file

@ -1 +1 @@
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{o as i}from"./react-three-fiber.esm-IOIyqSDz.js";import{a}from"./SettingsProvider-BTNRdL6b.js";import{l as o,u as s}from"./three.module-BCXZgYUA.js";import{r as c}from"./engineStore-DYTudHqF.js";var l=t(),u=e(n(),1),d=r(),f=(0,u.createContext)(void 0);function p(e){let t=(0,l.c)(11),{children:n}=e,r=i(g),{audioVolume:p}=a(),_;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(_={audioLoader:null,audioListener:null},t[0]=_):_=t[0];let[v,y]=(0,u.useState)(_),b,x;t[1]===r?(b=t[2],x=t[3]):(b=()=>{let e=new s,t=r.children.find(h);t||(t=new o,r.add(t)),y({audioLoader:e,audioListener:t});let n=()=>{let e=t.context;!e||e.state!==`suspended`||e.resume().finally(()=>{document.removeEventListener(`click`,n),document.removeEventListener(`keydown`,n),document.removeEventListener(`touchend`,n)})};document.addEventListener(`click`,n),document.addEventListener(`keydown`,n),document.addEventListener(`touchend`,n);let i=c.subscribe(m,e=>{let n=t.context;n&&(e===`paused`?n.suspend():n.state===`suspended`&&n.resume())});return()=>{document.removeEventListener(`click`,n),document.removeEventListener(`keydown`,n),document.removeEventListener(`touchend`,n),i(),t&&r.remove(t)}},x=[r],t[1]=r,t[2]=b,t[3]=x),(0,u.useEffect)(b,x);let S,C;t[4]!==v.audioListener||t[5]!==p?(S=()=>{v.audioListener?.setMasterVolume(p)},C=[p,v.audioListener],t[4]=v.audioListener,t[5]=p,t[6]=S,t[7]=C):(S=t[6],C=t[7]),(0,u.useEffect)(S,C);let w;return t[8]!==v||t[9]!==n?(w=(0,d.jsx)(f.Provider,{value:v,children:n}),t[8]=v,t[9]=n,t[10]=w):w=t[10],w}function m(e){return e.playback.status}function h(e){return e instanceof o}function g(e){return e.camera}function _(){let e=(0,u.useContext)(f);if(e===void 0)throw Error(`useAudio must be used within AudioProvider`);return e}export{_ as n,p as t};
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{o as i}from"./react-three-fiber.esm-IOIyqSDz.js";import{a}from"./SettingsProvider-Dls8-Ecn.js";import{l as o,u as s}from"./three.module-BCXZgYUA.js";import{r as c}from"./engineStore-DYTudHqF.js";var l=t(),u=e(n(),1),d=r(),f=(0,u.createContext)(void 0);function p(e){let t=(0,l.c)(11),{children:n}=e,r=i(g),{audioVolume:p}=a(),_;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(_={audioLoader:null,audioListener:null},t[0]=_):_=t[0];let[v,y]=(0,u.useState)(_),b,x;t[1]===r?(b=t[2],x=t[3]):(b=()=>{let e=new s,t=r.children.find(h);t||(t=new o,r.add(t)),y({audioLoader:e,audioListener:t});let n=()=>{let e=t.context;!e||e.state!==`suspended`||e.resume().finally(()=>{document.removeEventListener(`click`,n),document.removeEventListener(`keydown`,n),document.removeEventListener(`touchend`,n)})};document.addEventListener(`click`,n),document.addEventListener(`keydown`,n),document.addEventListener(`touchend`,n);let i=c.subscribe(m,e=>{let n=t.context;n&&(e===`paused`?n.suspend():n.state===`suspended`&&n.resume())});return()=>{document.removeEventListener(`click`,n),document.removeEventListener(`keydown`,n),document.removeEventListener(`touchend`,n),i(),t&&r.remove(t)}},x=[r],t[1]=r,t[2]=b,t[3]=x),(0,u.useEffect)(b,x);let S,C;t[4]!==v.audioListener||t[5]!==p?(S=()=>{v.audioListener?.setMasterVolume(p)},C=[p,v.audioListener],t[4]=v.audioListener,t[5]=p,t[6]=S,t[7]=C):(S=t[6],C=t[7]),(0,u.useEffect)(S,C);let w;return t[8]!==v||t[9]!==n?(w=(0,d.jsx)(f.Provider,{value:v,children:n}),t[8]=v,t[9]=n,t[10]=w):w=t[10],w}function m(e){return e.playback.status}function h(e){return e instanceof o}function g(e){return e.camera}function _(){let e=(0,u.useContext)(f);if(e===void 0)throw Error(`useAudio must be used within AudioProvider`);return e}export{_ as n,p as t};

View file

@ -1 +1 @@
import{r as e}from"./chunk-DECur_0Z.js";import{r as t,t as n}from"./jsx-runtime-BpGWiA-R.js";import{i as r,o as i}from"./react-three-fiber.esm-IOIyqSDz.js";import{a,i as o}from"./SettingsProvider-BTNRdL6b.js";import{t as s}from"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import{Ht as c,c as l,yt as u}from"./three.module-BCXZgYUA.js";import"./mission-CgOJ5O6t.js";import{r as d}from"./engineStore-DYTudHqF.js";import{r as f}from"./loaders-YyTXpfdm.js";import{n as p}from"./AudioContext-zfBZ8gWo.js";import{t as m}from"./FloatingLabel-CKXJ8qNh.js";var h=e(t(),1),g=n(),_=s(`AudioEmitter`),v=new Map,y=new Map;function b(e,t=1){y.set(e,t)}function x(e){y.delete(e)}var S=0;function C(){return S}function w(){S++;for(let[e]of y){try{e.stop()}catch{}try{e.disconnect()}catch{}}y.clear()}d.subscribe(e=>e.playback.rate,e=>{for(let[t,n]of y)try{t.setPlaybackRate(n*e)}catch{}});function T(e,t){let n=t(e),r=n?.filename;if(!r)return null;let i=r.endsWith(`.wav`)?r:`${r}.wav`,a=n.description,o=a==null?void 0:t(a);return{filename:i,is3D:o?.is3D??!0,isLooping:o?.isLooping??!1,refDist:o?.referenceDistance??20,maxDist:o?.maxDistance??100,volume:o?.volume??1}}function E(e,t,n,r,i){let a;try{a=f(e.filename)}catch{return}let o=d.getState().playback.rate,s=S;D(a,n,n=>{if(s===S)try{if(e.is3D&&i){let a=new u(t);a.setBuffer(n),a.setDistanceModel(`inverse`),a.setRefDistance(e.refDist),a.setMaxDistance(e.maxDist),a.setRolloffFactor(1),a.setVolume(e.volume),a.setPlaybackRate(o),r&&a.position.copy(r),i.add(a),y.set(a,1),a.play(),a.source.onended=()=>{y.delete(a);try{a.disconnect()}catch{}i.remove(a)}}else{let r=new l(t);r.setBuffer(n),r.setVolume(e.volume),r.setPlaybackRate(o),y.set(r,1),r.play(),r.source.onended=()=>{y.delete(r);try{r.disconnect()}catch{}}}}catch{}})}function D(e,t,n){v.has(e)?n(v.get(e)):t.load(e,t=>{v.set(e,t),n(t)},void 0,t=>{_.error(`Audio load error %s: %o`,e,t)})}var O=(0,h.memo)(function({entity:e}){let{debugMode:t}=o(),n=e.audioFileName??``,s=e.audioVolume??1,d=e.audioMinDistance??1,_=e.audioMaxDistance??1,v=e.audioMinLoopGap??0,y=e.audioMaxLoopGap??0,b=e.audioIs3D??!0?1:0,x=e.audioIsLooping??!0,[S,C,w]=e.position??[0,0,0],T=i(e=>e.scene),E=i(e=>e.camera),{audioLoader:O,audioListener:k}=p(),{audioEnabled:A}=a(),j=(0,h.useRef)(null),M=(0,h.useRef)(null),N=(0,h.useRef)(null),P=(0,h.useRef)(!1),F=(0,h.useRef)(!1),I=(0,h.useRef)(new c(S,C,w)),L=(0,h.useRef)(0),R=()=>{M.current!=null&&(clearTimeout(M.current),M.current=null),N.current!=null&&(clearTimeout(N.current),N.current=null)},[z]=(0,h.useState)(()=>Math.random());(0,h.useEffect)(()=>{if(!O||!k)return;L.current++;let e;if(b){let t=new u(k);t.position.copy(I.current),t.setDistanceModel(`inverse`),t.setRefDistance(d),t.setMaxDistance(_),t.setRolloffFactor(1),t.setVolume(s),e=t,T.add(e)}else e=new l(k),e.setVolume(s);return j.current=e,()=>{R();try{e.stop()}catch{}try{e.disconnect()}catch{}b&&T.remove(e),j.current=null,P.current=!1,F.current=!1}},[O,k,b,d,_,s,T]);let B=(e,t)=>{if(x)if(v>0||y>0){let n=Math.max(0,v),r=Math.max(n,y),i=n===r?n:z*(r-n)+n;e.loop=!1;let a=()=>{t===L.current&&(e.isPlaying===!1?M.current=setTimeout(()=>{if(t===L.current)try{e.play(),B(e,t)}catch{}},i):N.current=setTimeout(a,100))};N.current=setTimeout(a,100)}else e.setLoop(!0)},V=(0,h.useEffectEvent)(e=>{if(!O)return;let t=L.current;if(P.current)try{e.isPlaying||(e.play(),B(e,t))}catch{}else{let r;try{r=f(n)}catch{return}D(r,O,n=>{if(t===L.current&&!e.buffer){e.setBuffer(n),P.current=!0;try{e.play(),B(e,t)}catch{}}})}});return(0,h.useEffect)(()=>{let e=j.current;!e||b||!A||!n||V(e)},[A,b,n,O,k]),r(()=>{let e=j.current;if(!e||!b||!A||!n)return;let t=E.position.distanceTo(I.current),r=F.current,i=t<=_;if(i&&!r)F.current=!0,V(e);else if(!i&&r){F.current=!1,R();try{e.stop()}catch{}}}),(0,h.useEffect)(()=>{let e=j.current;if(e&&!A){R();try{e.stop()}catch{}F.current=!1}},[A]),t?(0,g.jsxs)(`mesh`,{position:I.current,children:[(0,g.jsx)(`sphereGeometry`,{args:[d,12,12]}),(0,g.jsx)(`meshBasicMaterial`,{color:`#00ff00`,wireframe:!0,opacity:.05,transparent:!0,toneMapped:!1}),(0,g.jsx)(m,{color:`#00ff00`,position:[0,d+1,0],children:n})]}):null});export{O as AudioEmitter,v as audioBufferCache,D as getCachedAudioBuffer,C as getSoundGeneration,E as playOneShotSound,T as resolveAudioProfile,w as stopAllTrackedSounds,b as trackSound,x as untrackSound};
import{r as e}from"./chunk-DECur_0Z.js";import{r as t,t as n}from"./jsx-runtime-BpGWiA-R.js";import{i as r,o as i}from"./react-three-fiber.esm-IOIyqSDz.js";import{a,i as o}from"./SettingsProvider-Dls8-Ecn.js";import{t as s}from"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import{Ht as c,c as l,yt as u}from"./three.module-BCXZgYUA.js";import"./mission-CgOJ5O6t.js";import{r as d}from"./engineStore-DYTudHqF.js";import{r as f}from"./loaders-Ba8dC3nL.js";import{n as p}from"./AudioContext-uUCY0wVz.js";import{t as m}from"./FloatingLabel-DtfOOmmG.js";var h=e(t(),1),g=n(),_=s(`AudioEmitter`),v=new Map,y=new Map;function b(e,t=1){y.set(e,t)}function x(e){y.delete(e)}var S=0;function C(){return S}function w(){S++;for(let[e]of y){try{e.stop()}catch{}try{e.disconnect()}catch{}}y.clear()}d.subscribe(e=>e.playback.rate,e=>{for(let[t,n]of y)try{t.setPlaybackRate(n*e)}catch{}});function T(e,t){let n=t(e),r=n?.filename;if(!r)return null;let i=r.endsWith(`.wav`)?r:`${r}.wav`,a=n.description,o=a==null?void 0:t(a);return{filename:i,is3D:o?.is3D??!0,isLooping:o?.isLooping??!1,refDist:o?.referenceDistance??20,maxDist:o?.maxDistance??100,volume:o?.volume??1}}function E(e,t,n,r,i){let a;try{a=f(e.filename)}catch{return}let o=d.getState().playback.rate,s=S;D(a,n,n=>{if(s===S)try{if(e.is3D&&i){let a=new u(t);a.setBuffer(n),a.setDistanceModel(`inverse`),a.setRefDistance(e.refDist),a.setMaxDistance(e.maxDist),a.setRolloffFactor(1),a.setVolume(e.volume),a.setPlaybackRate(o),r&&a.position.copy(r),i.add(a),y.set(a,1),a.play(),a.source.onended=()=>{y.delete(a);try{a.disconnect()}catch{}i.remove(a)}}else{let r=new l(t);r.setBuffer(n),r.setVolume(e.volume),r.setPlaybackRate(o),y.set(r,1),r.play(),r.source.onended=()=>{y.delete(r);try{r.disconnect()}catch{}}}}catch{}})}function D(e,t,n){v.has(e)?n(v.get(e)):t.load(e,t=>{v.set(e,t),n(t)},void 0,t=>{_.error(`Audio load error %s: %o`,e,t)})}var O=(0,h.memo)(function({entity:e}){let{debugMode:t}=o(),n=e.audioFileName??``,s=e.audioVolume??1,d=e.audioMinDistance??1,_=e.audioMaxDistance??1,v=e.audioMinLoopGap??0,y=e.audioMaxLoopGap??0,b=e.audioIs3D??!0?1:0,x=e.audioIsLooping??!0,[S,C,w]=e.position??[0,0,0],T=i(e=>e.scene),E=i(e=>e.camera),{audioLoader:O,audioListener:k}=p(),{audioEnabled:A}=a(),j=(0,h.useRef)(null),M=(0,h.useRef)(null),N=(0,h.useRef)(null),P=(0,h.useRef)(!1),F=(0,h.useRef)(!1),I=(0,h.useRef)(new c(S,C,w)),L=(0,h.useRef)(0),R=()=>{M.current!=null&&(clearTimeout(M.current),M.current=null),N.current!=null&&(clearTimeout(N.current),N.current=null)},[z]=(0,h.useState)(()=>Math.random());(0,h.useEffect)(()=>{if(!O||!k)return;L.current++;let e;if(b){let t=new u(k);t.position.copy(I.current),t.setDistanceModel(`inverse`),t.setRefDistance(d),t.setMaxDistance(_),t.setRolloffFactor(1),t.setVolume(s),e=t,T.add(e)}else e=new l(k),e.setVolume(s);return j.current=e,()=>{R();try{e.stop()}catch{}try{e.disconnect()}catch{}b&&T.remove(e),j.current=null,P.current=!1,F.current=!1}},[O,k,b,d,_,s,T]);let B=(e,t)=>{if(x)if(v>0||y>0){let n=Math.max(0,v),r=Math.max(n,y),i=n===r?n:z*(r-n)+n;e.loop=!1;let a=()=>{t===L.current&&(e.isPlaying===!1?M.current=setTimeout(()=>{if(t===L.current)try{e.play(),B(e,t)}catch{}},i):N.current=setTimeout(a,100))};N.current=setTimeout(a,100)}else e.setLoop(!0)},V=(0,h.useEffectEvent)(e=>{if(!O)return;let t=L.current;if(P.current)try{e.isPlaying||(e.play(),B(e,t))}catch{}else{let r;try{r=f(n)}catch{return}D(r,O,n=>{if(t===L.current&&!e.buffer){e.setBuffer(n),P.current=!0;try{e.play(),B(e,t)}catch{}}})}});return(0,h.useEffect)(()=>{let e=j.current;!e||b||!A||!n||V(e)},[A,b,n,O,k]),r(()=>{let e=j.current;if(!e||!b||!A||!n)return;let t=E.position.distanceTo(I.current),r=F.current,i=t<=_;if(i&&!r)F.current=!0,V(e);else if(!i&&r){F.current=!1,R();try{e.stop()}catch{}}}),(0,h.useEffect)(()=>{let e=j.current;if(e&&!A){R();try{e.stop()}catch{}F.current=!1}},[A]),t?(0,g.jsxs)(`mesh`,{position:I.current,children:[(0,g.jsx)(`sphereGeometry`,{args:[d,12,12]}),(0,g.jsx)(`meshBasicMaterial`,{color:`#00ff00`,wireframe:!0,opacity:.05,transparent:!0,toneMapped:!1}),(0,g.jsx)(m,{color:`#00ff00`,position:[0,d+1,0],children:n})]}):null});export{O as AudioEmitter,v as audioBufferCache,D as getCachedAudioBuffer,C as getSoundGeneration,E as playOneShotSound,T as resolveAudioProfile,w as stopAllTrackedSounds,b as trackSound,x as untrackSound};

View file

@ -1 +1 @@
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import"./mission-CgOJ5O6t.js";import{m as i}from"./index-CmEWnrr6.js";var a=t(),o=e(n(),1),s={InputForm:`_InputForm_18kom_1`,Input:`_Input_18kom_1`},c=r();function l(){let e=(0,a.c)(8),[t,n]=(0,o.useState)(``),r;e[0]===t?r=e[1]:(r=e=>{e.preventDefault();let r=t.trim();r&&(i.getState().sendCommand(`messageSent`,r),n(``))},e[0]=t,e[1]=r);let l=r,f;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(f=e=>n(e.target.value),e[2]=f):f=e[2];let p;e[3]===t?p=e[4]:(p=(0,c.jsx)(`input`,{className:s.Input,type:`text`,placeholder:`Say something…`,value:t,onChange:f,onKeyDown:d,onKeyUp:u,maxLength:255}),e[3]=t,e[4]=p);let m;return e[5]!==l||e[6]!==p?(m=(0,c.jsx)(`form`,{className:s.InputForm,onSubmit:l,children:p}),e[5]=l,e[6]=p,e[7]=m):m=e[7],m}function u(e){return e.stopPropagation()}function d(e){return e.stopPropagation()}export{l as ChatInput};
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import"./mission-CgOJ5O6t.js";import{m as i}from"./index-BngaOpHI.js";var a=t(),o=e(n(),1),s={InputForm:`_InputForm_18kom_1`,Input:`_Input_18kom_1`},c=r();function l(){let e=(0,a.c)(8),[t,n]=(0,o.useState)(``),r;e[0]===t?r=e[1]:(r=e=>{e.preventDefault();let r=t.trim();r&&(i.getState().sendCommand(`messageSent`,r),n(``))},e[0]=t,e[1]=r);let l=r,f;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(f=e=>n(e.target.value),e[2]=f):f=e[2];let p;e[3]===t?p=e[4]:(p=(0,c.jsx)(`input`,{className:s.Input,type:`text`,placeholder:`Say something…`,value:t,onChange:f,onKeyDown:d,onKeyUp:u,maxLength:255}),e[3]=t,e[4]=p);let m;return e[5]!==l||e[6]!==p?(m=(0,c.jsx)(`form`,{className:s.InputForm,onSubmit:l,children:p}),e[5]=l,e[6]=p,e[7]=m):m=e[7],m}function u(e){return e.stopPropagation()}function d(e){return e.stopPropagation()}export{l as ChatInput};

View file

@ -1 +1 @@
import{r as e}from"./chunk-DECur_0Z.js";import{r as t}from"./jsx-runtime-BpGWiA-R.js";import"./react-three-fiber.esm-IOIyqSDz.js";import{a as n}from"./SettingsProvider-BTNRdL6b.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import{c as r}from"./three.module-BCXZgYUA.js";import"./mission-CgOJ5O6t.js";import{i,r as a}from"./engineStore-DYTudHqF.js";import{r as o}from"./loaders-YyTXpfdm.js";import{n as s}from"./AudioContext-zfBZ8gWo.js";import"./FloatingLabel-CKXJ8qNh.js";import{getCachedAudioBuffer as c,getSoundGeneration as l,trackSound as u,untrackSound as d}from"./AudioEmitter-DxpFnV3F.js";var f=e(t(),1);function p(){let{audioLoader:e,audioListener:t}=s(),{audioEnabled:p}=n(),m=i(e=>e.playback.streamSnapshot?.chatMessages),h=i(e=>e.playback.streamSnapshot?.timeSec),g=(0,f.useRef)(new WeakSet),_=(0,f.useRef)(new Map);return(0,f.useEffect)(()=>{if(!p||!e||!t||!m?.length||h==null)return;let n=g.current,i=_.current;for(let s of m)if(!n.has(s)&&(n.add(s),s.soundPath&&!(Math.abs(h-s.timeSec)>2)))try{let n=o(s.soundPath),f=s.soundPitch??1,p=a.getState().playback.rate,m=s.sender,h=l();c(n,e,e=>{if(h!==l())return;if(m){let e=i.get(m);if(e){try{e.stop()}catch{}d(e);try{e.disconnect()}catch{}i.delete(m)}}let n=new r(t);n.setBuffer(e),n.setPlaybackRate(f*p),u(n,f),m&&i.set(m,n),n.play(),n.source.onended=()=>{d(n);try{n.disconnect()}catch{}m&&i.get(m)===n&&i.delete(m)}})}catch{}},[p,e,t,m,h]),null}export{p as ChatSoundPlayer};
import{r as e}from"./chunk-DECur_0Z.js";import{r as t}from"./jsx-runtime-BpGWiA-R.js";import"./react-three-fiber.esm-IOIyqSDz.js";import{a as n}from"./SettingsProvider-Dls8-Ecn.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import{c as r}from"./three.module-BCXZgYUA.js";import"./mission-CgOJ5O6t.js";import{i,r as a}from"./engineStore-DYTudHqF.js";import{r as o}from"./loaders-Ba8dC3nL.js";import{n as s}from"./AudioContext-uUCY0wVz.js";import"./FloatingLabel-DtfOOmmG.js";import{getCachedAudioBuffer as c,getSoundGeneration as l,trackSound as u,untrackSound as d}from"./AudioEmitter--X9CqSsb.js";var f=e(t(),1);function p(){let{audioLoader:e,audioListener:t}=s(),{audioEnabled:p}=n(),m=i(e=>e.playback.streamSnapshot?.chatMessages),h=i(e=>e.playback.streamSnapshot?.timeSec),g=(0,f.useRef)(new WeakSet),_=(0,f.useRef)(new Map);return(0,f.useEffect)(()=>{if(!p||!e||!t||!m?.length||h==null)return;let n=g.current,i=_.current;for(let s of m)if(!n.has(s)&&(n.add(s),s.soundPath&&!(Math.abs(h-s.timeSec)>2)))try{let n=o(s.soundPath),f=s.soundPitch??1,p=a.getState().playback.rate,m=s.sender,h=l();c(n,e,e=>{if(h!==l())return;if(m){let e=i.get(m);if(e){try{e.stop()}catch{}d(e);try{e.disconnect()}catch{}i.delete(m)}}let n=new r(t);n.setBuffer(e),n.setPlaybackRate(f*p),u(n,f),m&&i.set(m,n),n.play(),n.source.onended=()=>{d(n);try{n.disconnect()}catch{}m&&i.get(m)===n&&i.delete(m)}})}catch{}},[p,e,t,m,h]),null}export{p as ChatSoundPlayer};

View file

@ -1 +1 @@
import{r as e,t}from"./chunk-DECur_0Z.js";import{n,r,t as i}from"./jsx-runtime-BpGWiA-R.js";import{n as a,r as o}from"./react-three-fiber.esm-IOIyqSDz.js";import"./traditional-ec-lUAFC.js";import{t as s}from"./Html-DNykBNnc.js";var c=t(((e,t)=>{(function(n,r){typeof e==`object`&&t!==void 0?t.exports=r():typeof define==`function`&&define.amd?define(r):n.Stats=r()})(e,function(){var e=function(){function t(e){return i.appendChild(e.dom),e}function n(e){for(var t=0;t<i.children.length;t++)i.children[t].style.display=t===e?`block`:`none`;r=e}var r=0,i=document.createElement(`div`);i.style.cssText=`position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000`,i.addEventListener(`click`,function(e){e.preventDefault(),n(++r%i.children.length)},!1);var a=(performance||Date).now(),o=a,s=0,c=t(new e.Panel(`FPS`,`#0ff`,`#002`)),l=t(new e.Panel(`MS`,`#0f0`,`#020`));if(self.performance&&self.performance.memory)var u=t(new e.Panel(`MB`,`#f08`,`#201`));return n(0),{REVISION:16,dom:i,addPanel:t,showPanel:n,begin:function(){a=(performance||Date).now()},end:function(){s++;var e=(performance||Date).now();if(l.update(e-a,200),e>o+1e3&&(c.update(1e3*s/(e-o),100),o=e,s=0,u)){var t=performance.memory;u.update(t.usedJSHeapSize/1048576,t.jsHeapSizeLimit/1048576)}return e},update:function(){a=this.end()},domElement:i,setMode:n}};return e.Panel=function(e,t,n){var r=1/0,i=0,a=Math.round,o=a(window.devicePixelRatio||1),s=80*o,c=48*o,l=3*o,u=2*o,d=3*o,f=15*o,p=74*o,m=30*o,h=document.createElement(`canvas`);h.width=s,h.height=c,h.style.cssText=`width:80px;height:48px`;var g=h.getContext(`2d`);return g.font=`bold `+9*o+`px Helvetica,Arial,sans-serif`,g.textBaseline=`top`,g.fillStyle=n,g.fillRect(0,0,s,c),g.fillStyle=t,g.fillText(e,l,u),g.fillRect(d,f,p,m),g.fillStyle=n,g.globalAlpha=.9,g.fillRect(d,f,p,m),{dom:h,update:function(c,_){r=Math.min(r,c),i=Math.max(i,c),g.fillStyle=n,g.globalAlpha=1,g.fillRect(0,0,s,f),g.fillStyle=t,g.fillText(a(c)+` `+e+` (`+a(r)+`-`+a(i)+`)`,l,u),g.drawImage(h,d+o,f,p-o,m,d,f,p-o,m),g.fillRect(d+p-o,f,o,m),g.fillStyle=n,g.globalAlpha=.9,g.fillRect(d+p-o,f,o,a((1-c/_)*m))}}},e})})),l=e(r());function u(e,t){typeof e==`function`?e(t):e!=null&&(e.current=t)}function d(e,t=[],n){let[r,i]=l.useState();return l.useLayoutEffect(()=>{let t=e();return i(t),u(n,t),()=>u(n,null)},t),r}var f=e(c());function p({showPanel:e=0,className:t,parent:n}){let r=d(()=>new f.default,[]);return l.useEffect(()=>{if(r){let i=n&&n.current||document.body;r.showPanel(e),i?.appendChild(r.dom);let s=(t??``).split(` `).filter(e=>e);s.length&&r.dom.classList.add(...s);let c=o(()=>r.begin()),l=a(()=>r.end());return()=>{s.length&&r.dom.classList.remove(...s),i?.removeChild(r.dom),c(),l()}}},[n,r,t,e]),null}var m=n(),h={StatsPanel:`_StatsPanel_10m5i_1`,AxisLabel:`_AxisLabel_10m5i_8`},g=i();function _(){let e=(0,m.c)(10),t=(0,l.useRef)(null),n;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(n=()=>{let e=t.current;e&&e.setColors(`rgb(153, 255, 0)`,`rgb(0, 153, 255)`,`rgb(255, 153, 0)`)},e[0]=n):n=e[0],(0,l.useEffect)(n);let r;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,g.jsx)(p,{className:h.StatsPanel}),e[1]=r):r=e[1];let i;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(i=[70],e[2]=i):i=e[2];let a;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,g.jsx)(`axesHelper`,{ref:t,args:i,renderOrder:999,children:(0,g.jsx)(`lineBasicMaterial`,{depthTest:!1,depthWrite:!1,fog:!1,vertexColors:!0})}),e[3]=a):a=e[3];let o;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(o=[80,0,0],e[4]=o):o=e[4];let c;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,g.jsx)(s,{position:o,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`y`,children:`Y`})}),e[5]=c):c=e[5];let u;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(u=[0,80,0],e[6]=u):u=e[6];let d;e[7]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,g.jsx)(s,{position:u,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`z`,children:`Z`})}),e[7]=d):d=e[7];let f;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(f=[0,0,80],e[8]=f):f=e[8];let _;return e[9]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,g.jsxs)(g.Fragment,{children:[r,a,c,d,(0,g.jsx)(s,{position:f,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`x`,children:`X`})})]}),e[9]=_):_=e[9],_}export{_ as DebugElements};
import{r as e,t}from"./chunk-DECur_0Z.js";import{n,r,t as i}from"./jsx-runtime-BpGWiA-R.js";import{n as a,r as o}from"./react-three-fiber.esm-IOIyqSDz.js";import"./traditional-ec-lUAFC.js";import{t as s}from"./Html-CQXfFjv-.js";var c=t(((e,t)=>{(function(n,r){typeof e==`object`&&t!==void 0?t.exports=r():typeof define==`function`&&define.amd?define(r):n.Stats=r()})(e,function(){var e=function(){function t(e){return i.appendChild(e.dom),e}function n(e){for(var t=0;t<i.children.length;t++)i.children[t].style.display=t===e?`block`:`none`;r=e}var r=0,i=document.createElement(`div`);i.style.cssText=`position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000`,i.addEventListener(`click`,function(e){e.preventDefault(),n(++r%i.children.length)},!1);var a=(performance||Date).now(),o=a,s=0,c=t(new e.Panel(`FPS`,`#0ff`,`#002`)),l=t(new e.Panel(`MS`,`#0f0`,`#020`));if(self.performance&&self.performance.memory)var u=t(new e.Panel(`MB`,`#f08`,`#201`));return n(0),{REVISION:16,dom:i,addPanel:t,showPanel:n,begin:function(){a=(performance||Date).now()},end:function(){s++;var e=(performance||Date).now();if(l.update(e-a,200),e>o+1e3&&(c.update(1e3*s/(e-o),100),o=e,s=0,u)){var t=performance.memory;u.update(t.usedJSHeapSize/1048576,t.jsHeapSizeLimit/1048576)}return e},update:function(){a=this.end()},domElement:i,setMode:n}};return e.Panel=function(e,t,n){var r=1/0,i=0,a=Math.round,o=a(window.devicePixelRatio||1),s=80*o,c=48*o,l=3*o,u=2*o,d=3*o,f=15*o,p=74*o,m=30*o,h=document.createElement(`canvas`);h.width=s,h.height=c,h.style.cssText=`width:80px;height:48px`;var g=h.getContext(`2d`);return g.font=`bold `+9*o+`px Helvetica,Arial,sans-serif`,g.textBaseline=`top`,g.fillStyle=n,g.fillRect(0,0,s,c),g.fillStyle=t,g.fillText(e,l,u),g.fillRect(d,f,p,m),g.fillStyle=n,g.globalAlpha=.9,g.fillRect(d,f,p,m),{dom:h,update:function(c,_){r=Math.min(r,c),i=Math.max(i,c),g.fillStyle=n,g.globalAlpha=1,g.fillRect(0,0,s,f),g.fillStyle=t,g.fillText(a(c)+` `+e+` (`+a(r)+`-`+a(i)+`)`,l,u),g.drawImage(h,d+o,f,p-o,m,d,f,p-o,m),g.fillRect(d+p-o,f,o,m),g.fillStyle=n,g.globalAlpha=.9,g.fillRect(d+p-o,f,o,a((1-c/_)*m))}}},e})})),l=e(r());function u(e,t){typeof e==`function`?e(t):e!=null&&(e.current=t)}function d(e,t=[],n){let[r,i]=l.useState();return l.useLayoutEffect(()=>{let t=e();return i(t),u(n,t),()=>u(n,null)},t),r}var f=e(c());function p({showPanel:e=0,className:t,parent:n}){let r=d(()=>new f.default,[]);return l.useEffect(()=>{if(r){let i=n&&n.current||document.body;r.showPanel(e),i?.appendChild(r.dom);let s=(t??``).split(` `).filter(e=>e);s.length&&r.dom.classList.add(...s);let c=o(()=>r.begin()),l=a(()=>r.end());return()=>{s.length&&r.dom.classList.remove(...s),i?.removeChild(r.dom),c(),l()}}},[n,r,t,e]),null}var m=n(),h={StatsPanel:`_StatsPanel_10m5i_1`,AxisLabel:`_AxisLabel_10m5i_8`},g=i();function _(){let e=(0,m.c)(10),t=(0,l.useRef)(null),n;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(n=()=>{let e=t.current;e&&e.setColors(`rgb(153, 255, 0)`,`rgb(0, 153, 255)`,`rgb(255, 153, 0)`)},e[0]=n):n=e[0],(0,l.useEffect)(n);let r;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,g.jsx)(p,{className:h.StatsPanel}),e[1]=r):r=e[1];let i;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(i=[70],e[2]=i):i=e[2];let a;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,g.jsx)(`axesHelper`,{ref:t,args:i,renderOrder:999,children:(0,g.jsx)(`lineBasicMaterial`,{depthTest:!1,depthWrite:!1,fog:!1,vertexColors:!0})}),e[3]=a):a=e[3];let o;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(o=[80,0,0],e[4]=o):o=e[4];let c;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,g.jsx)(s,{position:o,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`y`,children:`Y`})}),e[5]=c):c=e[5];let u;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(u=[0,80,0],e[6]=u):u=e[6];let d;e[7]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,g.jsx)(s,{position:u,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`z`,children:`Z`})}),e[7]=d):d=e[7];let f;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(f=[0,0,80],e[8]=f):f=e[8];let _;return e[9]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,g.jsxs)(g.Fragment,{children:[r,a,c,d,(0,g.jsx)(s,{position:f,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`x`,children:`X`})})]}),e[9]=_):_=e[9],_}export{_ as DebugElements};

View file

@ -1 +1 @@
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import"./traditional-ec-lUAFC.js";import"./engineStore-DYTudHqF.js";import{c as i,d as a,f as o,l as s,p as c,u as l}from"./index-CmEWnrr6.js";var u=t(),d=e(n(),1),f={Root:`_Root_16j0q_1`,PlayPause:`_PlayPause_16j0q_10`,Time:`_Time_16j0q_32`,Seek:`_Seek_16j0q_38`,Speed:`_Speed_16j0q_44`},p=r(),m=[.25,.5,1,2,4];function h(e){return`${Math.floor(e/60)}:${Math.floor(e%60).toString().padStart(2,`0`)}`}function g(){let e=(0,u.c)(33),t=o(),n=l(),r=i(),g=s(),x=c(),{play:S,pause:C,seek:w,setSpeed:T}=a(),E,D;e[0]!==n||e[1]!==C||e[2]!==S||e[3]!==t?(E=()=>{if(!t)return;let e=e=>{if(e.code!==`Space`)return;let t=e.target;t.tagName===`INPUT`||t.tagName===`TEXTAREA`||t.tagName===`SELECT`||t.tagName===`BUTTON`||t.isContentEditable||(e.preventDefault(),n?C():S())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},D=[t,n,S,C],e[0]=n,e[1]=C,e[2]=S,e[3]=t,e[4]=E,e[5]=D):(E=e[4],D=e[5]),(0,d.useEffect)(E,D);let O;e[6]===w?O=e[7]:(O=e=>{w(parseFloat(e.target.value))},e[6]=w,e[7]=O);let k=O,A;e[8]===T?A=e[9]:(A=e=>{T(parseFloat(e.target.value))},e[8]=T,e[9]=A);let j=A;if(!t||!Number.isFinite(t.duration))return null;let M=n?C:S,N=n?`Pause`:`Play`,P=n?`❚❚`:``,F;e[10]!==M||e[11]!==N||e[12]!==P?(F=(0,p.jsx)(`button`,{className:f.PlayPause,onClick:M,"aria-label":N,autoFocus:!0,children:P}),e[10]=M,e[11]=N,e[12]=P,e[13]=F):F=e[13];let I;e[14]===r?I=e[15]:(I=h(r),e[14]=r,e[15]=I);let L;e[16]===g?L=e[17]:(L=h(g),e[16]=g,e[17]=L);let R=`${I} / ${L}`,z;e[18]===R?z=e[19]:(z=(0,p.jsx)(`span`,{className:f.Time,children:R}),e[18]=R,e[19]=z);let B;e[20]!==r||e[21]!==g||e[22]!==k?(B=(0,p.jsx)(`input`,{className:f.Seek,type:`range`,min:0,max:g,step:.01,value:r,onChange:k}),e[20]=r,e[21]=g,e[22]=k,e[23]=B):B=e[23];let V;e[24]===Symbol.for(`react.memo_cache_sentinel`)?(V=m.map(_),e[24]=V):V=e[24];let H;e[25]!==j||e[26]!==x?(H=(0,p.jsx)(`select`,{className:f.Speed,value:x,onChange:j,children:V}),e[25]=j,e[26]=x,e[27]=H):H=e[27];let U;return e[28]!==z||e[29]!==B||e[30]!==H||e[31]!==F?(U=(0,p.jsxs)(`div`,{className:f.Root,onKeyDown:b,onPointerDown:y,onClick:v,children:[F,z,B,H]}),e[28]=z,e[29]=B,e[30]=H,e[31]=F,e[32]=U):U=e[32],U}function _(e){return(0,p.jsxs)(`option`,{value:e,children:[e,`x`]},e)}function v(e){return e.stopPropagation()}function y(e){return e.stopPropagation()}function b(e){return e.stopPropagation()}export{g as DemoPlaybackControls};
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import"./traditional-ec-lUAFC.js";import"./engineStore-DYTudHqF.js";import{c as i,d as a,f as o,l as s,p as c,u as l}from"./index-BngaOpHI.js";var u=t(),d=e(n(),1),f={Root:`_Root_16j0q_1`,PlayPause:`_PlayPause_16j0q_10`,Time:`_Time_16j0q_32`,Seek:`_Seek_16j0q_38`,Speed:`_Speed_16j0q_44`},p=r(),m=[.25,.5,1,2,4];function h(e){return`${Math.floor(e/60)}:${Math.floor(e%60).toString().padStart(2,`0`)}`}function g(){let e=(0,u.c)(33),t=o(),n=l(),r=i(),g=s(),x=c(),{play:S,pause:C,seek:w,setSpeed:T}=a(),E,D;e[0]!==n||e[1]!==C||e[2]!==S||e[3]!==t?(E=()=>{if(!t)return;let e=e=>{if(e.code!==`Space`)return;let t=e.target;t.tagName===`INPUT`||t.tagName===`TEXTAREA`||t.tagName===`SELECT`||t.tagName===`BUTTON`||t.isContentEditable||(e.preventDefault(),n?C():S())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},D=[t,n,S,C],e[0]=n,e[1]=C,e[2]=S,e[3]=t,e[4]=E,e[5]=D):(E=e[4],D=e[5]),(0,d.useEffect)(E,D);let O;e[6]===w?O=e[7]:(O=e=>{w(parseFloat(e.target.value))},e[6]=w,e[7]=O);let k=O,A;e[8]===T?A=e[9]:(A=e=>{T(parseFloat(e.target.value))},e[8]=T,e[9]=A);let j=A;if(!t||!Number.isFinite(t.duration))return null;let M=n?C:S,N=n?`Pause`:`Play`,P=n?`❚❚`:``,F;e[10]!==M||e[11]!==N||e[12]!==P?(F=(0,p.jsx)(`button`,{className:f.PlayPause,onClick:M,"aria-label":N,autoFocus:!0,children:P}),e[10]=M,e[11]=N,e[12]=P,e[13]=F):F=e[13];let I;e[14]===r?I=e[15]:(I=h(r),e[14]=r,e[15]=I);let L;e[16]===g?L=e[17]:(L=h(g),e[16]=g,e[17]=L);let R=`${I} / ${L}`,z;e[18]===R?z=e[19]:(z=(0,p.jsx)(`span`,{className:f.Time,children:R}),e[18]=R,e[19]=z);let B;e[20]!==r||e[21]!==g||e[22]!==k?(B=(0,p.jsx)(`input`,{className:f.Seek,type:`range`,min:0,max:g,step:.01,value:r,onChange:k}),e[20]=r,e[21]=g,e[22]=k,e[23]=B):B=e[23];let V;e[24]===Symbol.for(`react.memo_cache_sentinel`)?(V=m.map(_),e[24]=V):V=e[24];let H;e[25]!==j||e[26]!==x?(H=(0,p.jsx)(`select`,{className:f.Speed,value:x,onChange:j,children:V}),e[25]=j,e[26]=x,e[27]=H):H=e[27];let U;return e[28]!==z||e[29]!==B||e[30]!==H||e[31]!==F?(U=(0,p.jsxs)(`div`,{className:f.Root,onKeyDown:b,onPointerDown:y,onClick:v,children:[F,z,B,H]}),e[28]=z,e[29]=B,e[30]=H,e[31]=F,e[32]=U):U=e[32],U}function _(e){return(0,p.jsxs)(`option`,{value:e,children:[e,`x`]},e)}function v(e){return e.stopPropagation()}function y(e){return e.stopPropagation()}function b(e){return e.stopPropagation()}export{g as DemoPlaybackControls};

View file

@ -1 +1 @@
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{i}from"./react-three-fiber.esm-IOIyqSDz.js";import{Ht as a}from"./three.module-BCXZgYUA.js";import{t as o}from"./Html-DNykBNnc.js";var s={Label:`_Label_8rn2m_1`},c=t(),l=e(n(),1),u=r(),d=[0,0,0],f=new a;function p(e,t,n,r){let i=e.matrixWorld.elements;return(t-i[12])*-i[8]+(n-i[13])*-i[9]+(r-i[14])*-i[10]<0}var m=(0,l.memo)(function(e){let t=(0,c.c)(11),{children:n,color:r,position:a,opacity:m}=e,h=r===void 0?`white`:r,g=a===void 0?d:a,_=m===void 0?`fadeWithDistance`:m,v=_===`fadeWithDistance`,y=(0,l.useRef)(null),[b,x]=(0,l.useState)(_!==0),S=(0,l.useRef)(null),C;t[0]!==v||t[1]!==b||t[2]!==_?(C=e=>{let{camera:t}=e,n=y.current;if(!n)return;n.getWorldPosition(f);let r=p(t,f.x,f.y,f.z);if(v){let e=r?1/0:t.position.distanceTo(f),n=e<200;if(b!==n&&x(n),S.current&&n){let t=Math.max(0,Math.min(1,1-e/200));S.current.style.opacity=t.toString()}}else{let e=!r&&_!==0;b!==e&&x(e),S.current&&(S.current.style.opacity=_.toString())}},t[0]=v,t[1]=b,t[2]=_,t[3]=C):C=t[3],i(C);let w;t[4]!==n||t[5]!==h||t[6]!==b||t[7]!==g?(w=b?(0,u.jsx)(o,{position:g,center:!0,children:(0,u.jsx)(`div`,{ref:S,className:s.Label,style:{color:h},children:n})}):null,t[4]=n,t[5]=h,t[6]=b,t[7]=g,t[8]=w):w=t[8];let T;return t[9]===w?T=t[10]:(T=(0,u.jsx)(`group`,{ref:y,children:w}),t[9]=w,t[10]=T),T});export{m as t};
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{i}from"./react-three-fiber.esm-IOIyqSDz.js";import{Ht as a}from"./three.module-BCXZgYUA.js";import{t as o}from"./Html-CQXfFjv-.js";var s={Label:`_Label_8rn2m_1`},c=t(),l=e(n(),1),u=r(),d=[0,0,0],f=new a;function p(e,t,n,r){let i=e.matrixWorld.elements;return(t-i[12])*-i[8]+(n-i[13])*-i[9]+(r-i[14])*-i[10]<0}var m=(0,l.memo)(function(e){let t=(0,c.c)(11),{children:n,color:r,position:a,opacity:m}=e,h=r===void 0?`white`:r,g=a===void 0?d:a,_=m===void 0?`fadeWithDistance`:m,v=_===`fadeWithDistance`,y=(0,l.useRef)(null),[b,x]=(0,l.useState)(_!==0),S=(0,l.useRef)(null),C;t[0]!==v||t[1]!==b||t[2]!==_?(C=e=>{let{camera:t}=e,n=y.current;if(!n)return;n.getWorldPosition(f);let r=p(t,f.x,f.y,f.z);if(v){let e=r?1/0:t.position.distanceTo(f),n=e<200;if(b!==n&&x(n),S.current&&n){let t=Math.max(0,Math.min(1,1-e/200));S.current.style.opacity=t.toString()}}else{let e=!r&&_!==0;b!==e&&x(e),S.current&&(S.current.style.opacity=_.toString())}},t[0]=v,t[1]=b,t[2]=_,t[3]=C):C=t[3],i(C);let w;t[4]!==n||t[5]!==h||t[6]!==b||t[7]!==g?(w=b?(0,u.jsx)(o,{position:g,center:!0,children:(0,u.jsx)(`div`,{ref:S,className:s.Label,style:{color:h},children:n})}):null,t[4]=n,t[5]=h,t[6]=b,t[7]=g,t[8]=w):w=t[8];let T;return t[9]===w?T=t[10]:(T=(0,u.jsx)(`group`,{ref:y,children:w}),t[9]=w,t[10]=T),T});export{m as t};

View file

@ -1,4 +1,4 @@
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{i}from"./react-three-fiber.esm-IOIyqSDz.js";import{a}from"./SettingsProvider-BTNRdL6b.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import{Et as o,Vt as s,kt as c,p as l,y as u}from"./three.module-BCXZgYUA.js";import"./mission-CgOJ5O6t.js";import{t as d}from"./Texture-D0BO6ArI.js";import{p as f}from"./loaders-YyTXpfdm.js";import{t as p}from"./DebugSuspense-RneU-m3U.js";var m=t(),h=e(n(),1),g=`
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{i}from"./react-three-fiber.esm-IOIyqSDz.js";import{a}from"./SettingsProvider-Dls8-Ecn.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import{Et as o,Vt as s,kt as c,p as l,y as u}from"./three.module-BCXZgYUA.js";import"./mission-CgOJ5O6t.js";import{t as d}from"./Texture-D0BO6ArI.js";import{p as f}from"./loaders-Ba8dC3nL.js";import{t as p}from"./DebugSuspense-RneU-m3U.js";var m=t(),h=e(n(),1),g=`
#include <fog_pars_vertex>
varying vec2 vUv;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
import{n as e,t}from"./jsx-runtime-BpGWiA-R.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import"./mission-CgOJ5O6t.js";import"./engineStore-DYTudHqF.js";import{n}from"./KeyboardControls-BqqT6pch.js";import{f as r,h as i}from"./index-CmEWnrr6.js";var a=e(),o={Root:`_Root_uktvs_1`,Column:`_Column_uktvs_13`,Row:`_Row_uktvs_20`,Spacer:`_Spacer_uktvs_26`,Key:`_Key_uktvs_30`,Arrow:`_Arrow_uktvs_53`},s=t();function c(){let e=(0,a.c)(51),t=r(),c=i(y),b=n(v),x=n(_),S=n(g),C=n(h),w=n(m),T=n(p),E=n(f),D=n(d),O=n(u),k=n(l);if(t&&t.source!==`live`||t?.source===`live`&&!c)return null;let A;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,s.jsx)(`div`,{className:o.Spacer}),e[0]=A):A=e[0];let j;e[1]===b?j=e[2]:(j=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":b,children:`W`}),e[1]=b,e[2]=j);let M;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(M=(0,s.jsx)(`div`,{className:o.Spacer}),e[3]=M):M=e[3];let N;e[4]===j?N=e[5]:(N=(0,s.jsxs)(`div`,{className:o.Row,children:[A,j,M]}),e[4]=j,e[5]=N);let P;e[6]===S?P=e[7]:(P=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":S,children:`A`}),e[6]=S,e[7]=P);let F;e[8]===x?F=e[9]:(F=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":x,children:`S`}),e[8]=x,e[9]=F);let I;e[10]===C?I=e[11]:(I=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":C,children:`D`}),e[10]=C,e[11]=I);let L;e[12]!==P||e[13]!==F||e[14]!==I?(L=(0,s.jsxs)(`div`,{className:o.Row,children:[P,F,I]}),e[12]=P,e[13]=F,e[14]=I,e[15]=L):L=e[15];let R;e[16]!==N||e[17]!==L?(R=(0,s.jsxs)(`div`,{className:o.Column,children:[N,L]}),e[16]=N,e[17]=L,e[18]=R):R=e[18];let z;e[19]===Symbol.for(`react.memo_cache_sentinel`)?(z=(0,s.jsx)(`span`,{className:o.Arrow,children:``}),e[19]=z):z=e[19];let B;e[20]===w?B=e[21]:(B=(0,s.jsx)(`div`,{className:o.Row,children:(0,s.jsxs)(`div`,{className:o.Key,"data-pressed":w,children:[z,` Space`]})}),e[20]=w,e[21]=B);let V;e[22]===Symbol.for(`react.memo_cache_sentinel`)?(V=(0,s.jsx)(`span`,{className:o.Arrow,children:``}),e[22]=V):V=e[22];let H;e[23]===T?H=e[24]:(H=(0,s.jsx)(`div`,{className:o.Row,children:(0,s.jsxs)(`div`,{className:o.Key,"data-pressed":T,children:[V,` Shift`]})}),e[23]=T,e[24]=H);let U;e[25]!==B||e[26]!==H?(U=(0,s.jsxs)(`div`,{className:o.Column,children:[B,H]}),e[25]=B,e[26]=H,e[27]=U):U=e[27];let W;e[28]===Symbol.for(`react.memo_cache_sentinel`)?(W=(0,s.jsx)(`div`,{className:o.Spacer}),e[28]=W):W=e[28];let G;e[29]===E?G=e[30]:(G=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":E,children:``}),e[29]=E,e[30]=G);let K;e[31]===Symbol.for(`react.memo_cache_sentinel`)?(K=(0,s.jsx)(`div`,{className:o.Spacer}),e[31]=K):K=e[31];let q;e[32]===G?q=e[33]:(q=(0,s.jsxs)(`div`,{className:o.Row,children:[W,G,K]}),e[32]=G,e[33]=q);let J;e[34]===O?J=e[35]:(J=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":O,children:``}),e[34]=O,e[35]=J);let Y;e[36]===D?Y=e[37]:(Y=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":D,children:``}),e[36]=D,e[37]=Y);let X;e[38]===k?X=e[39]:(X=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":k,children:``}),e[38]=k,e[39]=X);let Z;e[40]!==J||e[41]!==Y||e[42]!==X?(Z=(0,s.jsxs)(`div`,{className:o.Row,children:[J,Y,X]}),e[40]=J,e[41]=Y,e[42]=X,e[43]=Z):Z=e[43];let Q;e[44]!==q||e[45]!==Z?(Q=(0,s.jsxs)(`div`,{className:o.Column,children:[q,Z]}),e[44]=q,e[45]=Z,e[46]=Q):Q=e[46];let $;return e[47]!==U||e[48]!==Q||e[49]!==R?($=(0,s.jsxs)(`div`,{className:o.Root,children:[R,U,Q]}),e[47]=U,e[48]=Q,e[49]=R,e[50]=$):$=e[50],$}function l(e){return e.lookRight}function u(e){return e.lookLeft}function d(e){return e.lookDown}function f(e){return e.lookUp}function p(e){return e.down}function m(e){return e.up}function h(e){return e.right}function g(e){return e.left}function _(e){return e.backward}function v(e){return e.forward}function y(e){return e.liveReady}export{c as KeyboardOverlay};
import{n as e,t}from"./jsx-runtime-BpGWiA-R.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import"./mission-CgOJ5O6t.js";import"./engineStore-DYTudHqF.js";import{n}from"./KeyboardControls-BqqT6pch.js";import{f as r,h as i}from"./index-BngaOpHI.js";var a=e(),o={Root:`_Root_uktvs_1`,Column:`_Column_uktvs_13`,Row:`_Row_uktvs_20`,Spacer:`_Spacer_uktvs_26`,Key:`_Key_uktvs_30`,Arrow:`_Arrow_uktvs_53`},s=t();function c(){let e=(0,a.c)(51),t=r(),c=i(y),b=n(v),x=n(_),S=n(g),C=n(h),w=n(m),T=n(p),E=n(f),D=n(d),O=n(u),k=n(l);if(t&&t.source!==`live`||t?.source===`live`&&!c)return null;let A;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,s.jsx)(`div`,{className:o.Spacer}),e[0]=A):A=e[0];let j;e[1]===b?j=e[2]:(j=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":b,children:`W`}),e[1]=b,e[2]=j);let M;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(M=(0,s.jsx)(`div`,{className:o.Spacer}),e[3]=M):M=e[3];let N;e[4]===j?N=e[5]:(N=(0,s.jsxs)(`div`,{className:o.Row,children:[A,j,M]}),e[4]=j,e[5]=N);let P;e[6]===S?P=e[7]:(P=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":S,children:`A`}),e[6]=S,e[7]=P);let F;e[8]===x?F=e[9]:(F=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":x,children:`S`}),e[8]=x,e[9]=F);let I;e[10]===C?I=e[11]:(I=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":C,children:`D`}),e[10]=C,e[11]=I);let L;e[12]!==P||e[13]!==F||e[14]!==I?(L=(0,s.jsxs)(`div`,{className:o.Row,children:[P,F,I]}),e[12]=P,e[13]=F,e[14]=I,e[15]=L):L=e[15];let R;e[16]!==N||e[17]!==L?(R=(0,s.jsxs)(`div`,{className:o.Column,children:[N,L]}),e[16]=N,e[17]=L,e[18]=R):R=e[18];let z;e[19]===Symbol.for(`react.memo_cache_sentinel`)?(z=(0,s.jsx)(`span`,{className:o.Arrow,children:``}),e[19]=z):z=e[19];let B;e[20]===w?B=e[21]:(B=(0,s.jsx)(`div`,{className:o.Row,children:(0,s.jsxs)(`div`,{className:o.Key,"data-pressed":w,children:[z,` Space`]})}),e[20]=w,e[21]=B);let V;e[22]===Symbol.for(`react.memo_cache_sentinel`)?(V=(0,s.jsx)(`span`,{className:o.Arrow,children:``}),e[22]=V):V=e[22];let H;e[23]===T?H=e[24]:(H=(0,s.jsx)(`div`,{className:o.Row,children:(0,s.jsxs)(`div`,{className:o.Key,"data-pressed":T,children:[V,` Shift`]})}),e[23]=T,e[24]=H);let U;e[25]!==B||e[26]!==H?(U=(0,s.jsxs)(`div`,{className:o.Column,children:[B,H]}),e[25]=B,e[26]=H,e[27]=U):U=e[27];let W;e[28]===Symbol.for(`react.memo_cache_sentinel`)?(W=(0,s.jsx)(`div`,{className:o.Spacer}),e[28]=W):W=e[28];let G;e[29]===E?G=e[30]:(G=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":E,children:``}),e[29]=E,e[30]=G);let K;e[31]===Symbol.for(`react.memo_cache_sentinel`)?(K=(0,s.jsx)(`div`,{className:o.Spacer}),e[31]=K):K=e[31];let q;e[32]===G?q=e[33]:(q=(0,s.jsxs)(`div`,{className:o.Row,children:[W,G,K]}),e[32]=G,e[33]=q);let J;e[34]===O?J=e[35]:(J=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":O,children:``}),e[34]=O,e[35]=J);let Y;e[36]===D?Y=e[37]:(Y=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":D,children:``}),e[36]=D,e[37]=Y);let X;e[38]===k?X=e[39]:(X=(0,s.jsx)(`div`,{className:o.Key,"data-pressed":k,children:``}),e[38]=k,e[39]=X);let Z;e[40]!==J||e[41]!==Y||e[42]!==X?(Z=(0,s.jsxs)(`div`,{className:o.Row,children:[J,Y,X]}),e[40]=J,e[41]=Y,e[42]=X,e[43]=Z):Z=e[43];let Q;e[44]!==q||e[45]!==Z?(Q=(0,s.jsxs)(`div`,{className:o.Column,children:[q,Z]}),e[44]=q,e[45]=Z,e[46]=Q):Q=e[46];let $;return e[47]!==U||e[48]!==Q||e[49]!==R?($=(0,s.jsxs)(`div`,{className:o.Root,children:[R,U,Q]}),e[47]=U,e[48]=Q,e[49]=R,e[50]=$):$=e[50],$}function l(e){return e.lookRight}function u(e){return e.lookLeft}function d(e){return e.lookDown}function f(e){return e.lookUp}function p(e){return e.down}function m(e){return e.up}function h(e){return e.right}function g(e){return e.left}function _(e){return e.backward}function v(e){return e.forward}function y(e){return e.liveReady}export{c as KeyboardOverlay};

View file

@ -1 +0,0 @@
._GuiMarkup_jg4va_1{white-space:pre-wrap;font-size:14px;line-height:1.5}._GuiMarkup_jg4va_1 a{color:inherit;text-decoration:underline}._Bullet_jg4va_12{margin-left:.5em;margin-right:.5em}._Dialog_6c89x_1{color:#b0d5c9;-webkit-user-select:text;user-select:text;-webkit-touch-callout:default;background:#142526cc;border:1px solid #41838b99;border-radius:4px;outline:none;max-width:calc(100dvw - 40px);max-height:calc(100dvh - 40px);font-size:14px;line-height:1.5;position:relative;overflow:hidden;box-shadow:0 0 50px #0006,inset 0 0 60px #01070d99}._Overlay_6c89x_20{z-index:10;background:#000000b3;justify-content:center;align-items:center;padding:20px;display:flex;position:fixed;inset:0}._DialogButton_6c89x_31{color:#99fff1;text-shadow:0 -1px 1px #0006;cursor:pointer;background:linear-gradient(#30a497cc,#1f9688cc 33%,#218377cc 67%,#046564cc);border:1px solid #387c74cc;border-top-color:#57b7b9cc;border-radius:4px;padding:4px 18px;font-family:inherit;font-size:14px;font-weight:500;box-shadow:inset 0 0 4px #02808e80}._DialogButton_6c89x_31:hover:not(:disabled){color:#b1fff5;border:1px solid #409188e6;border-top-color:#5ac6c2e6;box-shadow:inset 0 0 4px #02808e80,0 0 5px #3effbf80}._DialogButton_6c89x_31:active:not(:disabled){transform:translateY(1px)}._DialogButton_6c89x_31:disabled{opacity:.4;cursor:not-allowed}._Secondary_6c89x_70{box-shadow:none;color:#a2e2cfcc;text-shadow:none;background:0 0;border:1px solid #387c74cc}._Secondary_6c89x_70:hover:not(:disabled){color:#a9ffe5cc;border:1px solid #3f9087e6}._Actions_6c89x_84{align-items:center;gap:10px;display:flex}@media (width<=719px){._Dialog_6c89x_1{border-radius:0;max-width:calc(100dvw - 20px);max-height:calc(100dvh - 20px)}}@media (width<=639px){._Overlay_6c89x_20{padding:10px}}._Dialog_1kbms_1{grid-template-rows:1fr auto;grid-template-columns:100%;width:800px;height:600px;display:grid}._Body_1kbms_14{grid-template-rows:100%;grid-template-columns:1fr auto;min-height:0;display:grid;overflow:hidden}._Left_1kbms_22{padding:24px 28px;overflow-y:auto}._PreviewImage_1kbms_27{border-left:1px solid #00bedc40;height:100%;display:block}._PreviewImageFloating_1kbms_33{float:right;clear:right;width:auto;max-width:30%;max-height:260px;margin:0 0 16px 20px;display:block}._Title_1kbms_43{color:#7dffff;text-shadow:0 1px 6px #0006;margin:0;font-size:26px;font-weight:500}._MapMeta_1kbms_51{flex-wrap:wrap;gap:8px 16px;margin-bottom:4px;font-size:15px;font-weight:400;display:flex}._MapPlanet_1kbms_61{color:#dbcaa8b3}._MapQuote_1kbms_65{border-left:2px solid #00bedc59;margin:16px 0;padding:0 0 0 14px;font-style:italic}._MapQuote_1kbms_65 p{white-space:pre-line;margin:0 0 4px}._MapQuote_1kbms_65 cite{color:#d7edcb80;font-size:12px;font-style:normal;display:block}._MapBlurb_1kbms_84{margin:0 0 16px;font-size:13px}._Section_1kbms_89{margin-top:20px}._SectionTitle_1kbms_93{color:#7dffff;letter-spacing:.04em;text-transform:uppercase;text-shadow:0 0 16px #00d2f040;margin:0 0 8px;font-size:16px;font-weight:500}._MusicTrack_1kbms_103{color:#d7edcb80;align-items:center;gap:6px;margin-top:16px;font-size:14px;font-style:italic;display:flex}._MusicTrack_1kbms_103[data-playing=true]{color:#f7fdd8b3}._MusicButton_1kbms_117{cursor:pointer;color:#557663;opacity:.5;background:0 0;border:0;border-radius:20px;flex-shrink:0;place-content:center;width:32px;height:32px;padding:0;font-size:20px;font-style:normal;line-height:1;display:grid}._MusicTrack_1kbms_103[data-playing=true] ._MusicButton_1kbms_117{color:#6dffaa;opacity:1}._MusicTrack_1kbms_103[data-playing=true] ._MusicButton_1kbms_117:hover{opacity:.7}._Footer_1kbms_144{background:#021415b3;border-top:1px solid #00bedc40;flex-shrink:0;align-items:center;gap:16px;padding:10px 12px;display:flex}._Hint_1kbms_158{color:#c9dcd84d;margin-left:auto;font-size:12px}._MusicTrackName_1kbms_164{text-transform:capitalize}@media (width<=719px){._Body_1kbms_14{display:block;overflow:auto}._Hint_1kbms_158{display:none}._Left_1kbms_22{width:100%;height:auto;margin:0;padding:16px 20px;overflow:auto}._PreviewImage_1kbms_27{width:auto;height:auto;margin:16px auto}._CloseButton_1kbms_154{width:220px;height:36px;margin:0 auto}}

View file

@ -1,5 +1,5 @@
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{t as i}from"./useQuery-CIsyQEQv.js";import{c as a}from"./manifest-DfHcIJuP.js";import"./logger-CC5j_O4o.js";import"./mission-CgOJ5O6t.js";import{K as o,q as s}from"./index-CmEWnrr6.js";import{i as c,l,n as u}from"./loaders-YyTXpfdm.js";var d=t(),f=e(n(),1),p={GuiMarkup:`_GuiMarkup_jg4va_1`,Bullet:`_Bullet_jg4va_12`},m=r(),h=new Set([`spop`,`spush`,`lmargin`,`font`,`color`,`bitmap`,`a`,`/a`]);function g(e){return e.split(/<([^><]+)>/g).map((e,t)=>{if(t%2==0)return e?{type:`text`,value:e}:null;{let[t,...n]=e.split(`:`);return h.has(t.toLowerCase())?{type:`tag`,name:t,args:n}:{type:`text`,value:`<${e}>`}}}).filter(e=>e!=null)}function _(e){let[t,n]=e;return{fontDescription:t,fontSize:n?Math.max(11,Math.min(parseInt(n.trim(),10),16)):void 0}}function v(e){let t=g(e),n={type:`span`,source:`root`,style:{},children:[]},r=n,i=[r],a=e=>e.children!=null&&e.children.some(e=>typeof e==`string`||a(e));for(let e of t)switch(e.type){case`text`:r.children.push(e.value);break;case`tag`:switch(e.name){case`spush`:{let e={type:`span`,source:`spush`,style:{},children:[]};r.children.push(e),r=e,i.push(r);break}case`spop`:if(r.source!==`root`){let e=i.pop();for(;e.source!==`spush`;)e=i.pop();r=i[i.length-1]}break;case`lmargin`:break;case`font`:{let t=_(e.args).fontSize;if(!a(r))r.style.fontSize=t;else{let e={type:`span`,source:`spush`,style:{fontSize:t},children:[]};r.children.push(e),r=e,i.push(r)}break}case`color`:if(!a(r))r.style.color=`#${e.args[0].trim()}`;else{let t={type:`span`,source:`spush`,style:{color:`#${e.args[0].trim()}`},children:[]};r.children.push(t),r=t,i.push(r)}break;case`bitmap`:{let t={type:`bitmap`,value:e.args[0]};r.children.push(t);break}case`a`:{let t=e.args[0].trim().split(` `),n={type:`a`,source:`a`,value:`http://${t.length===2&&t[0]===`wwwlink`?t[1]:t[0]}`,style:{},children:[]};r.children.push(n),r=n,i.push(r);break}case`/a`:{let e=i.pop();for(;e.source!==`a`;)e=i.pop();r=i[i.length-1];break}}}return y(n)}function y(e){switch(e.type){case`span`:return f.createElement(`span`,{style:Object.keys(e.style).length===0?void 0:e.style},...e.children.map(e=>typeof e==`string`?e:y(e)));case`a`:return f.createElement(`a`,{href:e.value,style:Object.keys(e.style).length===0?void 0:e.style,rel:`noopener noreferrer`,target:`_blank`},...e.children.map(e=>typeof e==`string`?e:y(e)));case`bitmap`:return(0,m.jsx)(S,{name:e.value})}}var b=new Map;function x(e){if(b.has(e))return b.get(e);let t;try{t=c(a(`textures/gui/${e}`))}catch{t=null}return b.set(e,t),t}function S(e){let t=(0,d.c)(5),{name:n}=e,r;t[0]===n?r=t[1]:(r=x(n),t[0]=n,t[1]=r);let i=r;if(i){let e;return t[2]===i?e=t[3]:(e=(0,m.jsx)(`img`,{src:i,alt:``,className:p.Bitmap}),t[2]=i,t[3]=e),e}if(/bullet/i.test(n)){let e;return t[4]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,m.jsx)(`span`,{className:p.Bullet,children:``}),t[4]=e):e=t[4],e}return null}var C=/<(?:font|color|bitmap|just|lmargin|a):/i;function w(e){return C.test(e)}function T(e,t){let n=t.toUpperCase();return e.split(`
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{t as i}from"./useQuery-Cql8MWsA.js";import{c as a}from"./manifest-NjKKupeg.js";import"./logger-CC5j_O4o.js";import"./mission-CgOJ5O6t.js";import{K as o,q as s}from"./index-BngaOpHI.js";import{i as c,l,n as u}from"./loaders-Ba8dC3nL.js";var d=t(),f=e(n(),1),p={GuiMarkup:`_GuiMarkup_jg4va_1`,Bullet:`_Bullet_jg4va_12`},m=r(),h=new Set([`spop`,`spush`,`lmargin`,`font`,`color`,`bitmap`,`a`,`/a`]);function g(e){return e.split(/<([^><]+)>/g).map((e,t)=>{if(t%2==0)return e?{type:`text`,value:e}:null;{let[t,...n]=e.split(`:`);return h.has(t.toLowerCase())?{type:`tag`,name:t,args:n}:{type:`text`,value:`<${e}>`}}}).filter(e=>e!=null)}function _(e){let[t,n]=e;return{fontDescription:t,fontSize:n?Math.max(11,Math.min(parseInt(n.trim(),10),16)):void 0}}function v(e){let t=g(e),n={type:`span`,source:`root`,style:{},children:[]},r=n,i=[r],a=e=>e.children!=null&&e.children.some(e=>typeof e==`string`||a(e));for(let e of t)switch(e.type){case`text`:r.children.push(e.value);break;case`tag`:switch(e.name){case`spush`:{let e={type:`span`,source:`spush`,style:{},children:[]};r.children.push(e),r=e,i.push(r);break}case`spop`:if(r.source!==`root`){let e=i.pop();for(;e.source!==`spush`;)e=i.pop();r=i[i.length-1]}break;case`lmargin`:break;case`font`:{let t=_(e.args).fontSize;if(!a(r))r.style.fontSize=t;else{let e={type:`span`,source:`spush`,style:{fontSize:t},children:[]};r.children.push(e),r=e,i.push(r)}break}case`color`:if(!a(r))r.style.color=`#${e.args[0].trim()}`;else{let t={type:`span`,source:`spush`,style:{color:`#${e.args[0].trim()}`},children:[]};r.children.push(t),r=t,i.push(r)}break;case`bitmap`:{let t={type:`bitmap`,value:e.args[0]};r.children.push(t);break}case`a`:{let t=e.args[0].trim().split(` `),n={type:`a`,source:`a`,value:`http://${t.length===2&&t[0]===`wwwlink`?t[1]:t[0]}`,style:{},children:[]};r.children.push(n),r=n,i.push(r);break}case`/a`:{let e=i.pop();for(;e.source!==`a`;)e=i.pop();r=i[i.length-1];break}}}return y(n)}function y(e){switch(e.type){case`span`:return f.createElement(`span`,{style:Object.keys(e.style).length===0?void 0:e.style},...e.children.map(e=>typeof e==`string`?e:y(e)));case`a`:return f.createElement(`a`,{href:e.value,style:Object.keys(e.style).length===0?void 0:e.style,rel:`noopener noreferrer`,target:`_blank`},...e.children.map(e=>typeof e==`string`?e:y(e)));case`bitmap`:return(0,m.jsx)(S,{name:e.value})}}var b=new Map;function x(e){if(b.has(e))return b.get(e);let t;try{t=c(a(`textures/gui/${e}`))}catch{t=null}return b.set(e,t),t}function S(e){let t=(0,d.c)(5),{name:n}=e,r;t[0]===n?r=t[1]:(r=x(n),t[0]=n,t[1]=r);let i=r;if(i){let e;return t[2]===i?e=t[3]:(e=(0,m.jsx)(`img`,{src:i,alt:``,className:p.Bitmap}),t[2]=i,t[3]=e),e}if(/bullet/i.test(n)){let e;return t[4]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,m.jsx)(`span`,{className:p.Bullet,children:``}),t[4]=e):e=t[4],e}return null}var C=/<(?:font|color|bitmap|just|lmargin|a):/i;function w(e){return C.test(e)}function T(e,t){let n=t.toUpperCase();return e.split(`
`).flatMap(e=>{let t=e.match(/^\[([^\]]+)\]/);return t&&!t[1].toUpperCase().split(/\s+/).includes(n)?[]:[e.replace(/^\[[^\]]+\]/,``)]}).join(`
`)}function E(e){let t=(0,d.c)(4),{markup:n}=e,r;t[0]===n?r=t[1]:(r=v(n),t[0]=n,t[1]=r);let i=r,a;return t[2]===i?a=t[3]:(a=(0,m.jsx)(`div`,{className:p.GuiMarkup,children:i}),t[2]=i,t[3]=a),a}var D={Dialog:`_Dialog_1kbms_1 _Dialog_6c89x_1`,Overlay:`_Overlay_1kbms_10 _Overlay_6c89x_20`,Body:`_Body_1kbms_14`,Left:`_Left_1kbms_22`,PreviewImage:`_PreviewImage_1kbms_27`,PreviewImageFloating:`_PreviewImageFloating_1kbms_33`,Title:`_Title_1kbms_43`,MapMeta:`_MapMeta_1kbms_51`,MapPlanet:`_MapPlanet_1kbms_61`,MapQuote:`_MapQuote_1kbms_65`,MapBlurb:`_MapBlurb_1kbms_84`,Section:`_Section_1kbms_89`,SectionTitle:`_SectionTitle_1kbms_93`,MusicTrack:`_MusicTrack_1kbms_103`,MusicButton:`_MusicButton_1kbms_117`,Footer:`_Footer_1kbms_144`,CloseButton:`_CloseButton_1kbms_154 _DialogButton_6c89x_31`,Hint:`_Hint_1kbms_158`,MusicTrackName:`_MusicTrackName_1kbms_164`};function ee(e){let t=(0,d.c)(2),n;return t[0]===e?n=t[1]:(n={queryKey:[`parsedMission`,e],queryFn:()=>l(e)},t[0]=e,t[1]=n),i(n)}function te(e){for(let t of e.body){if(t.type!==`ObjectDeclaration`)continue;let{instanceName:e,body:n}=t;if(e&&e.type===`Identifier`&&e.name.toLowerCase()===`missiongroup`){let e={};for(let t of n){if(t.type!==`Assignment`)continue;let{target:n,value:r}=t;n.type===`Identifier`&&r.type===`StringLiteral`&&(e[n.name.toLowerCase()]=r.value)}return e}}return{}}function ne(e,t){if(e)try{return c(a(`textures/gui/${e}`))}catch{}try{return c(a(`textures/gui/Load_${t}`))}catch{}return null}function re(e){let t=(0,d.c)(7),{src:n,alt:r,className:i}=e,a=i===void 0?D.PreviewImage:i,[o,s]=(0,f.useState)(null),c,l;if(t[0]===n?(c=t[1],l=t[2]):(c=()=>{let e=!1,t;return fetch(n).then(j).then(A).then(k).then(n=>{e||!n||(t=URL.createObjectURL(n),s(t))}).catch(O),()=>{e=!0,t&&URL.revokeObjectURL(t)}},l=[n],t[0]=n,t[1]=c,t[2]=l),(0,f.useEffect)(c,l),!o)return null;let u;return t[3]!==r||t[4]!==a||t[5]!==o?(u=(0,m.jsx)(`img`,{src:o,alt:r,className:a}),t[3]=r,t[4]=a,t[5]=o,t[6]=u):u=t[6],u}function O(){}function k(e){return new Promise(t=>{let n=document.createElement(`canvas`);n.width=e.width,n.height=e.height,n.getContext(`2d`)?.drawImage(e,0,0),e.close(),n.toBlob(t)})}function A(e){return createImageBitmap(e,{colorSpaceConversion:`none`})}function j(e){return e.blob()}function ie(e){let t=(0,d.c)(22),{track:n}=e,[r,i]=(0,f.useState)(!1),[a,c]=(0,f.useState)(!0),l=(0,f.useRef)(null),p;t[0]===n?p=t[1]:(p=n.toLowerCase(),t[0]=n,t[1]=p);let h=`${u}music/${p}.mp3`,g,_;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(g=()=>{let e=l.current;if(e)return()=>{e.pause()}},_=[],t[2]=g,t[3]=_):(g=t[2],_=t[3]),(0,f.useEffect)(g,_);let v;t[4]===r?v=t[5]:(v=()=>{let e=l.current;e&&(r?e.pause():e.play().catch(()=>c(!1)))},t[4]=r,t[5]=v);let y=v,b,x,S;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(b=()=>i(!0),x=()=>i(!1),S=()=>c(!1),t[6]=b,t[7]=x,t[8]=S):(b=t[6],x=t[7],S=t[8]);let C;t[9]===h?C=t[10]:(C=(0,m.jsx)(`audio`,{ref:l,src:h,loop:!0,onPlay:b,onPause:x,onError:S}),t[9]=h,t[10]=C);let w;t[11]===n?w=t[12]:(w=(0,m.jsx)(`span`,{className:D.MusicTrackName,children:n}),t[11]=n,t[12]=w);let T;t[13]!==a||t[14]!==r||t[15]!==y?(T=a&&(0,m.jsx)(`button`,{className:D.MusicButton,onClick:y,"aria-label":r?`Pause music`:`Play music`,children:r?(0,m.jsx)(s,{}):(0,m.jsx)(o,{})}),t[13]=a,t[14]=r,t[15]=y,t[16]=T):T=t[16];let E;return t[17]!==r||t[18]!==T||t[19]!==C||t[20]!==w?(E=(0,m.jsxs)(`div`,{className:D.MusicTrack,"data-playing":r,children:[C,w,T]}),t[17]=r,t[18]=T,t[19]=C,t[20]=w,t[21]=E):E=t[21],E}function M(e){let t=(0,d.c)(100),{onClose:n,missionName:r,missionType:i}=e,{data:a}=ee(r),o=(0,f.useRef)(null),s,c;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(s=()=>{o.current?.focus();try{document.exitPointerLock()}catch{}},c=[],t[0]=s,t[1]=c):(s=t[0],c=t[1]),(0,f.useEffect)(s,c);let l,u;t[2]===n?(l=t[3],u=t[4]):(l=()=>{let e=e=>{if(e.key===`Escape`)n();else if(e.key===`k`&&(e.metaKey||e.ctrlKey)){n();return}e.stopImmediatePropagation()},t=se;return window.addEventListener(`keydown`,e,{capture:!0}),window.addEventListener(`keyup`,t,{capture:!0}),()=>{window.removeEventListener(`keydown`,e,{capture:!0}),window.removeEventListener(`keyup`,t,{capture:!0})}},u=[n],t[2]=n,t[3]=l,t[4]=u),(0,f.useEffect)(l,u);let p;t[5]===a?p=t[6]:(p=a?te(a.ast):{},t[5]=a,t[6]=p);let h=p,g;t[7]!==r||t[8]!==a?(g=a?ne(a.bitmap,r):null,t[7]=r,t[8]=a,t[9]=g):g=t[9];let _=g,v=a?.displayName??r,y;t[10]===i?y=t[11]:(y=i.toLowerCase(),t[10]=i,t[11]=y);let b=y===`singleplayer`,x=h.musictrack,S,C,O,k,A,j,M,N,P,F,I,L,R,z,B,V,H,U;if(t[12]!==_||t[13]!==v||t[14]!==b||t[15]!==i||t[16]!==n||t[17]!==a){let e=a?.missionString?T(a.missionString,i):null,r,s,c,l;if(t[36]!==a?.missionQuote){if(l=a?.missionQuote?.trim()??``,s=w(l),c=``,r=``,!s)for(let e of l.split(`
`)}function E(e){let t=(0,d.c)(4),{markup:n}=e,r;t[0]===n?r=t[1]:(r=v(n),t[0]=n,t[1]=r);let i=r,a;return t[2]===i?a=t[3]:(a=(0,m.jsx)(`div`,{className:p.GuiMarkup,children:i}),t[2]=i,t[3]=a),a}var D={Dialog:`_Dialog_tbn5d_1 _Dialog_6c89x_1`,Overlay:`_Overlay_tbn5d_10 _Overlay_6c89x_20`,Body:`_Body_tbn5d_14`,Left:`_Left_tbn5d_22`,PreviewImage:`_PreviewImage_tbn5d_29`,PreviewImageFloating:`_PreviewImageFloating_tbn5d_35`,Title:`_Title_tbn5d_45`,MapMeta:`_MapMeta_tbn5d_53`,MapPlanet:`_MapPlanet_tbn5d_63`,MapQuote:`_MapQuote_tbn5d_67`,MapBlurb:`_MapBlurb_tbn5d_86`,Section:`_Section_tbn5d_91`,SectionTitle:`_SectionTitle_tbn5d_95`,MusicTrack:`_MusicTrack_tbn5d_105`,MusicButton:`_MusicButton_tbn5d_119`,Footer:`_Footer_tbn5d_146`,CloseButton:`_CloseButton_tbn5d_158 _DialogButton_6c89x_31`,Hint:`_Hint_tbn5d_162`,MusicTrackName:`_MusicTrackName_tbn5d_168`};function ee(e){let t=(0,d.c)(2),n;return t[0]===e?n=t[1]:(n={queryKey:[`parsedMission`,e],queryFn:()=>l(e)},t[0]=e,t[1]=n),i(n)}function te(e){for(let t of e.body){if(t.type!==`ObjectDeclaration`)continue;let{instanceName:e,body:n}=t;if(e&&e.type===`Identifier`&&e.name.toLowerCase()===`missiongroup`){let e={};for(let t of n){if(t.type!==`Assignment`)continue;let{target:n,value:r}=t;n.type===`Identifier`&&r.type===`StringLiteral`&&(e[n.name.toLowerCase()]=r.value)}return e}}return{}}function ne(e,t){if(e)try{return c(a(`textures/gui/${e}`))}catch{}try{return c(a(`textures/gui/Load_${t}`))}catch{}return null}function re(e){let t=(0,d.c)(7),{src:n,alt:r,className:i}=e,a=i===void 0?D.PreviewImage:i,[o,s]=(0,f.useState)(null),c,l;if(t[0]===n?(c=t[1],l=t[2]):(c=()=>{let e=!1,t;return fetch(n).then(j).then(A).then(k).then(n=>{e||!n||(t=URL.createObjectURL(n),s(t))}).catch(O),()=>{e=!0,t&&URL.revokeObjectURL(t)}},l=[n],t[0]=n,t[1]=c,t[2]=l),(0,f.useEffect)(c,l),!o)return null;let u;return t[3]!==r||t[4]!==a||t[5]!==o?(u=(0,m.jsx)(`img`,{src:o,alt:r,className:a}),t[3]=r,t[4]=a,t[5]=o,t[6]=u):u=t[6],u}function O(){}function k(e){return new Promise(t=>{let n=document.createElement(`canvas`);n.width=e.width,n.height=e.height,n.getContext(`2d`)?.drawImage(e,0,0),e.close(),n.toBlob(t)})}function A(e){return createImageBitmap(e,{colorSpaceConversion:`none`})}function j(e){return e.blob()}function ie(e){let t=(0,d.c)(22),{track:n}=e,[r,i]=(0,f.useState)(!1),[a,c]=(0,f.useState)(!0),l=(0,f.useRef)(null),p;t[0]===n?p=t[1]:(p=n.toLowerCase(),t[0]=n,t[1]=p);let h=`${u}music/${p}.mp3`,g,_;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(g=()=>{let e=l.current;if(e)return()=>{e.pause()}},_=[],t[2]=g,t[3]=_):(g=t[2],_=t[3]),(0,f.useEffect)(g,_);let v;t[4]===r?v=t[5]:(v=()=>{let e=l.current;e&&(r?e.pause():e.play().catch(()=>c(!1)))},t[4]=r,t[5]=v);let y=v,b,x,S;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(b=()=>i(!0),x=()=>i(!1),S=()=>c(!1),t[6]=b,t[7]=x,t[8]=S):(b=t[6],x=t[7],S=t[8]);let C;t[9]===h?C=t[10]:(C=(0,m.jsx)(`audio`,{ref:l,src:h,loop:!0,onPlay:b,onPause:x,onError:S}),t[9]=h,t[10]=C);let w;t[11]===n?w=t[12]:(w=(0,m.jsx)(`span`,{className:D.MusicTrackName,children:n}),t[11]=n,t[12]=w);let T;t[13]!==a||t[14]!==r||t[15]!==y?(T=a&&(0,m.jsx)(`button`,{className:D.MusicButton,onClick:y,"aria-label":r?`Pause music`:`Play music`,children:r?(0,m.jsx)(s,{}):(0,m.jsx)(o,{})}),t[13]=a,t[14]=r,t[15]=y,t[16]=T):T=t[16];let E;return t[17]!==r||t[18]!==T||t[19]!==C||t[20]!==w?(E=(0,m.jsxs)(`div`,{className:D.MusicTrack,"data-playing":r,children:[C,w,T]}),t[17]=r,t[18]=T,t[19]=C,t[20]=w,t[21]=E):E=t[21],E}function M(e){let t=(0,d.c)(100),{onClose:n,missionName:r,missionType:i}=e,{data:a}=ee(r),o=(0,f.useRef)(null),s,c;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(s=()=>{o.current?.focus();try{document.exitPointerLock()}catch{}},c=[],t[0]=s,t[1]=c):(s=t[0],c=t[1]),(0,f.useEffect)(s,c);let l,u;t[2]===n?(l=t[3],u=t[4]):(l=()=>{let e=e=>{if(e.key===`Escape`)n();else if(e.key===`k`&&(e.metaKey||e.ctrlKey)){n();return}e.stopImmediatePropagation()},t=se;return window.addEventListener(`keydown`,e,{capture:!0}),window.addEventListener(`keyup`,t,{capture:!0}),()=>{window.removeEventListener(`keydown`,e,{capture:!0}),window.removeEventListener(`keyup`,t,{capture:!0})}},u=[n],t[2]=n,t[3]=l,t[4]=u),(0,f.useEffect)(l,u);let p;t[5]===a?p=t[6]:(p=a?te(a.ast):{},t[5]=a,t[6]=p);let h=p,g;t[7]!==r||t[8]!==a?(g=a?ne(a.bitmap,r):null,t[7]=r,t[8]=a,t[9]=g):g=t[9];let _=g,v=a?.displayName??r,y;t[10]===i?y=t[11]:(y=i.toLowerCase(),t[10]=i,t[11]=y);let b=y===`singleplayer`,x=h.musictrack,S,C,O,k,A,j,M,N,P,F,I,L,R,z,B,V,H,U;if(t[12]!==_||t[13]!==v||t[14]!==b||t[15]!==i||t[16]!==n||t[17]!==a){let e=a?.missionString?T(a.missionString,i):null,r,s,c,l;if(t[36]!==a?.missionQuote){if(l=a?.missionQuote?.trim()??``,s=w(l),c=``,r=``,!s)for(let e of l.split(`
`)){let t=e.trim();t.match(/^--[^-]/)?r=t.replace(/^-+\s*/,``).trim():t&&(c+=(c?`
`:``)+t)}t[36]=a?.missionQuote,t[37]=r,t[38]=s,t[39]=c,t[40]=l}else r=t[37],s=t[38],c=t[39],l=t[40];B=D.Overlay,V=n,M=o,N=D.Dialog,P=oe,F=ae,I=`dialog`,L=`true`,R=`Map Information`,z=-1,j=D.Body,H=D.Left,t[41]!==_||t[42]!==v||t[43]!==b?(U=_&&b&&(0,m.jsx)(re,{className:D.PreviewImageFloating,src:_,alt:`${v} preview`},_),t[41]=_,t[42]=v,t[43]=b,t[44]=U):U=t[44],t[45]===v?S=t[46]:(S=(0,m.jsx)(`h1`,{className:D.Title,children:v}),t[45]=v,t[46]=S);let u;t[47]===a?u=t[48]:(u=a?.planetName&&(0,m.jsx)(`span`,{className:D.MapPlanet,children:a.planetName}),t[47]=a,t[48]=u),t[49]===u?C=t[50]:(C=(0,m.jsx)(`div`,{className:D.MapMeta,children:u}),t[49]=u,t[50]=C),t[51]!==r||t[52]!==s||t[53]!==c||t[54]!==l?(O=s?(0,m.jsx)(`blockquote`,{className:D.MapQuote,children:(0,m.jsx)(E,{markup:l})}):c?(0,m.jsxs)(`blockquote`,{className:D.MapQuote,children:[(0,m.jsx)(`p`,{children:c}),r&&(0,m.jsxs)(`cite`,{children:[` `,r]})]}):null,t[51]=r,t[52]=s,t[53]=c,t[54]=l,t[55]=O):O=t[55],t[56]===a?k=t[57]:(k=a?.missionBlurb&&(0,m.jsx)(`div`,{className:D.MapBlurb,children:w(a.missionBlurb)?(0,m.jsx)(E,{markup:a.missionBlurb.trim()}):a.missionBlurb.trim()}),t[56]=a,t[57]=k),A=e&&e.trim()&&(0,m.jsx)(`div`,{className:D.Section,children:(0,m.jsx)(E,{markup:e})}),t[12]=_,t[13]=v,t[14]=b,t[15]=i,t[16]=n,t[17]=a,t[18]=S,t[19]=C,t[20]=O,t[21]=k,t[22]=A,t[23]=j,t[24]=M,t[25]=N,t[26]=P,t[27]=F,t[28]=I,t[29]=L,t[30]=R,t[31]=z,t[32]=B,t[33]=V,t[34]=H,t[35]=U}else S=t[18],C=t[19],O=t[20],k=t[21],A=t[22],j=t[23],M=t[24],N=t[25],P=t[26],F=t[27],I=t[28],L=t[29],R=t[30],z=t[31],B=t[32],V=t[33],H=t[34],U=t[35];let W;t[58]===a?W=t[59]:(W=a?.missionBriefing&&(0,m.jsxs)(`div`,{className:D.Section,children:[(0,m.jsx)(`h2`,{className:D.SectionTitle,children:`Mission Briefing`}),(0,m.jsx)(E,{markup:a.missionBriefing})]}),t[58]=a,t[59]=W);let G;t[60]===x?G=t[61]:(G=x&&(0,m.jsx)(ie,{track:x}),t[60]=x,t[61]=G);let K;t[62]!==S||t[63]!==C||t[64]!==O||t[65]!==k||t[66]!==A||t[67]!==W||t[68]!==G||t[69]!==H||t[70]!==U?(K=(0,m.jsxs)(`div`,{className:H,children:[U,S,C,O,k,A,W,G]}),t[62]=S,t[63]=C,t[64]=O,t[65]=k,t[66]=A,t[67]=W,t[68]=G,t[69]=H,t[70]=U,t[71]=K):K=t[71];let q;t[72]!==_||t[73]!==v||t[74]!==b?(q=_&&!b&&(0,m.jsx)(re,{src:_,alt:`${v} preview`},_),t[72]=_,t[73]=v,t[74]=b,t[75]=q):q=t[75];let J;t[76]!==j||t[77]!==K||t[78]!==q?(J=(0,m.jsxs)(`div`,{className:j,children:[K,q]}),t[76]=j,t[77]=K,t[78]=q,t[79]=J):J=t[79];let Y;t[80]===n?Y=t[81]:(Y=(0,m.jsx)(`button`,{className:D.CloseButton,onClick:n,children:`Close`}),t[80]=n,t[81]=Y);let X;t[82]===Symbol.for(`react.memo_cache_sentinel`)?(X=(0,m.jsx)(`span`,{className:D.Hint,children:`Esc to close`}),t[82]=X):X=t[82];let Z;t[83]===Y?Z=t[84]:(Z=(0,m.jsxs)(`div`,{className:D.Footer,children:[Y,X]}),t[83]=Y,t[84]=Z);let Q;t[85]!==M||t[86]!==N||t[87]!==P||t[88]!==F||t[89]!==I||t[90]!==L||t[91]!==R||t[92]!==z||t[93]!==J||t[94]!==Z?(Q=(0,m.jsxs)(`div`,{ref:M,className:N,onClick:P,onKeyDown:F,role:I,"aria-modal":L,"aria-label":R,tabIndex:z,children:[J,Z]}),t[85]=M,t[86]=N,t[87]=P,t[88]=F,t[89]=I,t[90]=L,t[91]=R,t[92]=z,t[93]=J,t[94]=Z,t[95]=Q):Q=t[95];let $;return t[96]!==B||t[97]!==V||t[98]!==Q?($=(0,m.jsx)(`div`,{className:B,onClick:V,children:Q}),t[96]=B,t[97]=V,t[98]=Q,t[99]=$):$=t[99],$}function ae(e){return e.stopPropagation()}function oe(e){return e.stopPropagation()}function se(e){e.stopImmediatePropagation()}export{M as MapInfoDialog};

View file

@ -0,0 +1 @@
._GuiMarkup_jg4va_1{white-space:pre-wrap;font-size:14px;line-height:1.5}._GuiMarkup_jg4va_1 a{color:inherit;text-decoration:underline}._Bullet_jg4va_12{margin-left:.5em;margin-right:.5em}._Dialog_6c89x_1{color:#b0d5c9;-webkit-user-select:text;user-select:text;-webkit-touch-callout:default;background:#142526cc;border:1px solid #41838b99;border-radius:4px;outline:none;max-width:calc(100dvw - 40px);max-height:calc(100dvh - 40px);font-size:14px;line-height:1.5;position:relative;overflow:hidden;box-shadow:0 0 50px #0006,inset 0 0 60px #01070d99}._Overlay_6c89x_20{z-index:10;background:#000000b3;justify-content:center;align-items:center;padding:20px;display:flex;position:fixed;inset:0}._DialogButton_6c89x_31{color:#99fff1;text-shadow:0 -1px 1px #0006;cursor:pointer;background:linear-gradient(#30a497cc,#1f9688cc 33%,#218377cc 67%,#046564cc);border:1px solid #387c74cc;border-top-color:#57b7b9cc;border-radius:4px;padding:4px 18px;font-family:inherit;font-size:14px;font-weight:500;box-shadow:inset 0 0 4px #02808e80}._DialogButton_6c89x_31:hover:not(:disabled){color:#b1fff5;border:1px solid #409188e6;border-top-color:#5ac6c2e6;box-shadow:inset 0 0 4px #02808e80,0 0 5px #3effbf80}._DialogButton_6c89x_31:active:not(:disabled){transform:translateY(1px)}._DialogButton_6c89x_31:disabled{opacity:.4;cursor:not-allowed}._Secondary_6c89x_70{box-shadow:none;color:#a2e2cfcc;text-shadow:none;background:0 0;border:1px solid #387c74cc}._Secondary_6c89x_70:hover:not(:disabled){color:#a9ffe5cc;border:1px solid #3f9087e6}._Actions_6c89x_84{align-items:center;gap:10px;display:flex}@media (width<=719px){._Dialog_6c89x_1{border-radius:0;max-width:calc(100dvw - 20px);max-height:calc(100dvh - 20px)}}@media (width<=639px){._Overlay_6c89x_20{padding:10px}}._Dialog_tbn5d_1{grid-template-rows:1fr auto;grid-template-columns:100%;width:800px;height:600px;display:grid}._Body_tbn5d_14{grid-template-rows:100%;grid-template-columns:1fr auto;min-height:0;display:grid;overflow:hidden}._Left_tbn5d_22{z-index:1;padding:24px 28px;position:relative;overflow-y:auto}._PreviewImage_tbn5d_29{border-left:1px solid #00bedc40;height:100%;display:block}._PreviewImageFloating_tbn5d_35{float:right;clear:right;width:auto;max-width:30%;max-height:260px;margin:0 0 16px 20px;display:block}._Title_tbn5d_45{color:#7dffff;text-shadow:0 1px 6px #0006;margin:0;font-size:26px;font-weight:500}._MapMeta_tbn5d_53{flex-wrap:wrap;gap:8px 16px;margin-bottom:4px;font-size:15px;font-weight:400;display:flex}._MapPlanet_tbn5d_63{color:#dbcaa8b3}._MapQuote_tbn5d_67{border-left:2px solid #00bedc59;margin:16px 0;padding:0 0 0 14px;font-style:italic}._MapQuote_tbn5d_67 p{white-space:pre-line;margin:0 0 4px}._MapQuote_tbn5d_67 cite{color:#d7edcb80;font-size:12px;font-style:normal;display:block}._MapBlurb_tbn5d_86{margin:0 0 16px;font-size:13px}._Section_tbn5d_91{margin-top:20px}._SectionTitle_tbn5d_95{color:#7dffff;letter-spacing:.04em;text-transform:uppercase;text-shadow:0 0 16px #00d2f040;margin:0 0 8px;font-size:16px;font-weight:500}._MusicTrack_tbn5d_105{color:#d7edcb80;align-items:center;gap:6px;margin-top:16px;font-size:14px;font-style:italic;display:flex}._MusicTrack_tbn5d_105[data-playing=true]{color:#f7fdd8b3}._MusicButton_tbn5d_119{cursor:pointer;color:#557663;opacity:.5;background:0 0;border:0;border-radius:20px;flex-shrink:0;place-content:center;width:32px;height:32px;padding:0;font-size:20px;font-style:normal;line-height:1;display:grid}._MusicTrack_tbn5d_105[data-playing=true] ._MusicButton_tbn5d_119{color:#6dffaa;opacity:1}._MusicTrack_tbn5d_105[data-playing=true] ._MusicButton_tbn5d_119:hover{opacity:.7}._Footer_tbn5d_146{z-index:1;background:#021415b3;border-top:1px solid #00bedc40;flex-shrink:0;align-items:center;gap:16px;padding:10px 12px;display:flex;position:relative}._Hint_tbn5d_162{color:#c9dcd84d;margin-left:auto;font-size:12px}._MusicTrackName_tbn5d_168{text-transform:capitalize}@media (width<=719px){._Body_tbn5d_14{grid-template:"body"1fr/1fr;overflow:auto}._Hint_tbn5d_162{display:none}._Left_tbn5d_22{background:linear-gradient(#0009,#0000);grid-area:body;margin:0;padding:16px 20px}._PreviewImage_tbn5d_29{z-index:0;opacity:.9;border:0;grid-area:body;width:100%;height:auto;position:relative}._CloseButton_tbn5d_158{width:220px;height:36px;margin:0 auto}}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
._PlayerHUD_5937t_1{z-index:1;pointer-events:none;position:absolute;inset:0}._Compass_5937t_11{flex-shrink:0;width:64px;height:64px;position:absolute;top:10px;right:10px}._CompassRing_5937t_20{image-rendering:auto;width:100%;height:100%;position:absolute;top:0;left:0}._CompassNSEW_5937t_29{width:100%;height:100%;image-rendering:pixelated;position:absolute;top:0;left:0}._CompassClock_5937t_38{color:#c8f0e6e6;text-shadow:0 0 4px #000c;pointer-events:none;white-space:nowrap;font-size:10px;font-weight:600;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}._Bars_5937t_51{flex-direction:column;align-items:flex-end;gap:3px;width:120px;max-width:20%;display:flex;position:absolute;top:20px;right:82px}._BarTrack_5937t_63{background:#00000080;border:1px solid #ffffff26;width:100%;height:10px;overflow:hidden}._BarFillHealth_5937t_71{background:#2ecc40;height:100%;transition:width .15s ease-out}._BarFillEnergy_5937t_77{background:#0af;height:100%;transition:width .15s ease-out}._WeaponHUD_5937t_85{flex-direction:column;gap:2px;display:flex;position:absolute;top:50%;right:6px;transform:translateY(-50%)}._WeaponHUD_5937t_85 ._PackInvItem_5937t_95[data-active=false]{opacity:.6}@media (height<=699px){._WeaponHUD_5937t_85 ._PackInvItem_5937t_95[data-active=false]{display:none}}._WeaponSeparator_5937t_105{height:6px}._TeamScores_5937t_111{border-collapse:collapse;border:1px solid #80ffc826;font-size:12px;position:absolute;bottom:6px;left:6px}@media (width<=499px),(pointer:coarse){._TeamScores_5937t_111{display:none}}._ObserverCount_5937t_126{color:#c1e4d8;text-shadow:0 0 2px #0009;padding:4px 6px;font-size:10px;display:block;position:absolute;bottom:100%}._TeamRow_5937t_136{background:#00323ca6;flex:1 0 auto}._TeamRow_5937t_136+._TeamRow_5937t_136{border-top:1px solid #80ffc826}._TeamName_5937t_145{min-width:6em;padding:5px 6px;font-size:12px;font-weight:500}._TeamNameFriendly_5937t_152{color:#2de46a}._TeamNameEnemy_5937t_157{color:#79cbd4}._TeamScore_5937t_111{color:#fff;text-align:center;border-left:1px solid #80ffc826;padding:0 10px;font-weight:500}._TeamCount_5937t_170{color:#7d9b96;text-align:center;padding:0 6px;font-size:11px}._PackInventoryHUD_5937t_179{align-items:center;gap:4px;display:flex;position:absolute;bottom:6px;right:6px}@media (width<=499px),(pointer:coarse){._PackInventoryHUD_5937t_179{display:none}}._PackInvItem_5937t_95{background:#00323ca6;border:1px solid #80ffc826;flex-direction:column;justify-content:center;align-items:center;gap:1px;padding:4px;display:flex}._PackInvItem_5937t_95[data-active=true]{border-color:#80ffc899;box-shadow:0 0 8px #80ffc866}._PackInvIcon_5937t_210{image-rendering:pixelated;display:block}._PackInvCount_5937t_215{color:#bfe;text-align:center;min-width:12px;font-size:11px}._PackInvInfinity_5937t_222{image-rendering:pixelated;opacity:.8;display:block}._Reticle_5937t_230{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}._ReticleImage_5937t_237{opacity:.85;width:64px;height:64px;image-rendering:pixelated}._ReticleDot_5937t_244{background:#2ecc40b3;border-radius:50%;width:4px;height:4px;box-shadow:0 0 4px #2ecc4080}._ChatContainer_1ax2f_1{pointer-events:auto;border:1px solid #2cacb566;flex-direction:column;width:400px;max-width:50%;max-height:25%;display:flex;position:absolute;top:6px;left:6px}._ChatWindow_1ax2f_14{-webkit-user-select:text;user-select:text;scrollbar-width:thin;scrollbar-color:#2cacb566 transparent;background:#00323ca6;min-height:4em;max-height:12.5em;padding:6px;font-size:12px;line-height:1.25;overflow-y:auto}@media (width<=699px){._ChatWindow_1ax2f_14{font-size:11px}}._ChatMessage_1ax2f_34{color:#2cacb5;padding:2px 0}._ChatColor0_1ax2f_41{color:#2cacb5}._ChatColor1_1ax2f_44{color:#04eb69}._ChatColor2_1ax2f_47{color:#dbc880}._ChatColor3_1ax2f_50{color:#4dfd5f}._ChatColor4_1ax2f_53{color:#28e7f0}._ChatColor5_1ax2f_56{color:#c8c832}._ChatColor6_1ax2f_59{color:#c8c8c8}._ChatColor7_1ax2f_62{color:#dcdc14}._ChatColor8_1ax2f_65{color:#9696fa}._ChatColor9_1ax2f_68{color:#3cdc96}

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
._PlayerHUD_1hc5e_1{z-index:1;pointer-events:none;position:absolute;inset:0}._TopRight_1hc5e_11{align-items:flex-start;gap:6px;display:flex;position:absolute;top:10px;right:10px}._Compass_1hc5e_20{flex-shrink:0;width:64px;height:64px;position:relative}._CompassRing_1hc5e_27{image-rendering:auto;width:100%;height:100%;position:absolute;top:0;left:0}._CompassNSEW_1hc5e_36{width:100%;height:100%;image-rendering:pixelated;position:absolute;top:0;left:0}._CompassClock_1hc5e_45{color:#c8f0e6e6;text-shadow:0 0 4px #000c;pointer-events:none;white-space:nowrap;font-size:10px;font-weight:600;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}._Bars_1hc5e_58{flex-direction:column;gap:3px;padding-top:10px;display:flex}._BarTrack_1hc5e_65{background:#00000080;border:1px solid #ffffff26;width:120px;height:10px;overflow:hidden}._BarFillHealth_1hc5e_73{background:#2ecc40;height:100%;transition:width .15s ease-out}._BarFillEnergy_1hc5e_79{background:#0af;height:100%;transition:width .15s ease-out}._WeaponHUD_1hc5e_87{flex-direction:column;gap:2px;display:flex;position:absolute;top:50%;right:6px;transform:translateY(-50%)}._WeaponSeparator_1hc5e_97{height:6px}._TeamScores_1hc5e_103{border-collapse:collapse;border:1px solid #80ffc826;font-size:12px;position:absolute;bottom:6px;left:6px}._ObserverCount_1hc5e_112{color:#c1e4d8;text-shadow:0 0 2px #0009;padding:4px 6px;font-size:10px;display:block;position:absolute;bottom:100%}._TeamRow_1hc5e_122{background:#00323ca6;flex:1 0 auto}._TeamRow_1hc5e_122+._TeamRow_1hc5e_122{border-top:1px solid #80ffc826}._TeamName_1hc5e_131{min-width:6em;padding:5px 6px;font-size:12px;font-weight:500}._TeamNameFriendly_1hc5e_138{color:#2de46a}._TeamNameEnemy_1hc5e_143{color:#79cbd4}._TeamScore_1hc5e_103{color:#fff;text-align:center;border-left:1px solid #80ffc826;padding:0 10px;font-weight:500}._TeamCount_1hc5e_156{color:#7d9b96;text-align:center;padding:0 6px;font-size:11px}._PackInventoryHUD_1hc5e_165{align-items:center;gap:4px;display:flex;position:absolute;bottom:6px;right:6px}._PackInvItem_1hc5e_174{background:#00323ca6;border:1px solid #80ffc826;flex-direction:column;justify-content:center;align-items:center;gap:1px;padding:4px;display:flex}._PackInvItemActive_1hc5e_185{border-color:#80ffc880;box-shadow:0 0 6px #80ffc84d}._PackInvItemDim_1hc5e_190{opacity:.5}._PackInvIcon_1hc5e_194{image-rendering:pixelated;display:block}._PackInvCount_1hc5e_199{color:#bfe;text-align:center;min-width:12px;font-size:11px}._PackInvInfinity_1hc5e_206{image-rendering:pixelated;opacity:.8;display:block}._Reticle_1hc5e_214{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}._ReticleImage_1hc5e_221{opacity:.85;width:64px;height:64px;image-rendering:pixelated}._ReticleDot_1hc5e_228{background:#2ecc40b3;border-radius:50%;width:4px;height:4px;box-shadow:0 0 4px #2ecc4080}._ChatContainer_24i6p_1{pointer-events:auto;border:1px solid #2cacb566;flex-direction:column;width:400px;max-width:50%;max-height:25%;display:flex;position:absolute;top:6px;left:6px}._ChatWindow_24i6p_14{-webkit-user-select:text;user-select:text;scrollbar-width:thin;scrollbar-color:#2cacb566 transparent;background:#00323ca6;min-height:4em;max-height:12.5em;padding:6px;font-size:12px;line-height:1.25;overflow-y:auto}._ChatMessage_24i6p_28{color:#2cacb5;padding:2px 0}._ChatColor0_24i6p_35{color:#2cacb5}._ChatColor1_24i6p_38{color:#04eb69}._ChatColor2_24i6p_41{color:#dbc880}._ChatColor3_24i6p_44{color:#4dfd5f}._ChatColor4_24i6p_47{color:#28e7f0}._ChatColor5_24i6p_50{color:#c8c832}._ChatColor6_24i6p_53{color:#c8c8c8}._ChatColor7_24i6p_56{color:#dcdc14}._ChatColor8_24i6p_59{color:#9696fa}._ChatColor9_24i6p_62{color:#3cdc96}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{i}from"./react-three-fiber.esm-IOIyqSDz.js";import"./SettingsProvider-BTNRdL6b.js";import{_ as a,h as o,m as s}from"./GenericShape-BwYzFQrS.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import{Dt as c,Ht as l,xt as u,y as d}from"./three.module-BCXZgYUA.js";import"./mission-CgOJ5O6t.js";import"./engineStore-DYTudHqF.js";import{t as f}from"./Texture-D0BO6ArI.js";import{p}from"./loaders-YyTXpfdm.js";import"./FloatingLabel-CKXJ8qNh.js";import"./globalFogUniforms-BmkrmymO.js";var m=t(),h=e(n(),1),g=r(),_=new l,v=new l,y=new l,b=new l,x=new l,S=new l,C=new l(0,1,0);function w(e){let t=(0,m.c)(14),{entity:n}=e,{visual:r}=n,i;t[0]===r.texture?i=t[1]:(i=p(r.texture),t[0]=r.texture,t[1]=i);let a=f(i,T),o=Array.isArray(a)?a[0]:a,s;t[2]!==r.color.b||t[3]!==r.color.g||t[4]!==r.color.r?(s=new d().setRGB(r.color.r,r.color.g,r.color.b,c),t[2]=r.color.b,t[3]=r.color.g,t[4]=r.color.r,t[5]=s):s=t[5];let l=s,u;t[6]===r.size?u=t[7]:(u=[r.size,r.size,1],t[6]=r.size,t[7]=u);let h;t[8]!==l||t[9]!==o?(h=(0,g.jsx)(`spriteMaterial`,{map:o,color:l,transparent:!0,blending:2,depthWrite:!1,toneMapped:!1}),t[8]=l,t[9]=o,t[10]=h):h=t[10];let _;return t[11]!==u||t[12]!==h?(_=(0,g.jsx)(`sprite`,{scale:u,children:h}),t[11]=u,t[12]=h,t[13]=_):_=t[13],_}function T(e){o(Array.isArray(e)?e[0]:e)}function E(e){let t=(0,m.c)(29),{entity:n}=e,{visual:r}=n,o=(0,h.useRef)(null),c=(0,h.useRef)(null),l=(0,h.useRef)(null),d;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(d=new u,t[0]=d):d=t[0];let w=(0,h.useRef)(d),T;t[1]===r.texture?T=t[2]:(T=p(r.texture),t[1]=r.texture,t[2]=T);let E=r.crossTexture??r.texture,O;t[3]===E?O=t[4]:(O=p(E),t[3]=E,t[4]=O);let k;t[5]!==T||t[6]!==O?(k=[T,O],t[5]=T,t[6]=O,t[7]=k):k=t[7];let A=f(k,D),j;t[8]===A?j=t[9]:(j=Array.isArray(A)?A:[A,A],t[8]=A,t[9]=j);let[M,N]=j,P;t[10]!==n.direction||t[11]!==n.keyframes?.[0]||t[12]!==r.crossSize||t[13]!==r.crossViewAng||t[14]!==r.renderCross||t[15]!==r.tracerLength||t[16]!==r.tracerWidth?(P=e=>{let{camera:t}=e,i=o.current,u=c.current;if(!i||!u)return;let d=n.keyframes?.[0],f=d?.position,p=n.direction??d?.velocity;if(!f||!p){i.visible=!1,l.current&&(l.current.visible=!1);return}if(a(p,_),_.lengthSq()<1e-8){i.visible=!1,l.current&&(l.current.visible=!1);return}_.normalize(),i.visible=!0,a(f,S),v.copy(S).sub(t.position),y.crossVectors(v,_),y.lengthSq()<1e-8&&(y.crossVectors(C,_),y.lengthSq()<1e-8&&y.set(1,0,0)),y.normalize().multiplyScalar(r.tracerWidth);let m=r.tracerLength*.5;b.copy(_).multiplyScalar(-m),x.copy(_).multiplyScalar(m);let h=u.array;h[0]=b.x+y.x,h[1]=b.y+y.y,h[2]=b.z+y.z,h[3]=b.x-y.x,h[4]=b.y-y.y,h[5]=b.z-y.z,h[6]=x.x-y.x,h[7]=x.y-y.y,h[8]=x.z-y.z,h[9]=x.x+y.x,h[10]=x.y+y.y,h[11]=x.z+y.z,u.needsUpdate=!0;let g=l.current;if(!g)return;if(!r.renderCross){g.visible=!1;return}v.normalize();let T=_.dot(v);if(T>-r.crossViewAng&&T<r.crossViewAng){g.visible=!1;return}g.visible=!0,s(_,w.current),g.quaternion.copy(w.current),g.scale.setScalar(r.crossSize)},t[10]=n.direction,t[11]=n.keyframes?.[0],t[12]=r.crossSize,t[13]=r.crossViewAng,t[14]=r.renderCross,t[15]=r.tracerLength,t[16]=r.tracerWidth,t[17]=P):P=t[17],i(P);let F;t[18]===Symbol.for(`react.memo_cache_sentinel`)?(F=(0,g.jsx)(`bufferAttribute`,{ref:c,attach:`attributes-position`,args:[new Float32Array(12),3]}),t[18]=F):F=t[18];let I;t[19]===Symbol.for(`react.memo_cache_sentinel`)?(I=(0,g.jsx)(`bufferAttribute`,{attach:`attributes-uv`,args:[new Float32Array([0,0,0,1,1,1,1,0]),2]}),t[19]=I):I=t[19];let L;t[20]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,g.jsxs)(`bufferGeometry`,{children:[F,I,(0,g.jsx)(`bufferAttribute`,{attach:`index`,args:[new Uint16Array([0,1,2,0,2,3]),1]})]}),t[20]=L):L=t[20];let R;t[21]===M?R=t[22]:(R=(0,g.jsxs)(`mesh`,{ref:o,children:[L,(0,g.jsx)(`meshBasicMaterial`,{map:M,transparent:!0,blending:2,side:2,depthWrite:!1,toneMapped:!1})]}),t[21]=M,t[22]=R);let z;t[23]!==N||t[24]!==r.renderCross?(z=r.renderCross?(0,g.jsxs)(`mesh`,{ref:l,children:[(0,g.jsxs)(`bufferGeometry`,{children:[(0,g.jsx)(`bufferAttribute`,{attach:`attributes-position`,args:[new Float32Array([-.5,0,-.5,.5,0,-.5,.5,0,.5,-.5,0,.5]),3]}),(0,g.jsx)(`bufferAttribute`,{attach:`attributes-uv`,args:[new Float32Array([0,0,0,1,1,1,1,0]),2]}),(0,g.jsx)(`bufferAttribute`,{attach:`index`,args:[new Uint16Array([0,1,2,0,2,3]),1]})]}),(0,g.jsx)(`meshBasicMaterial`,{map:N,transparent:!0,blending:2,side:2,depthWrite:!1,toneMapped:!1})]}):null,t[23]=N,t[24]=r.renderCross,t[25]=z):z=t[25];let B;return t[26]!==R||t[27]!==z?(B=(0,g.jsxs)(g.Fragment,{children:[R,z]}),t[26]=R,t[27]=z,t[28]=B):B=t[28],B}function D(e){let t=Array.isArray(e)?e:[e];for(let e of t)o(e)}export{w as SpriteProjectile,E as TracerProjectile};
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{i}from"./react-three-fiber.esm-IOIyqSDz.js";import"./SettingsProvider-Dls8-Ecn.js";import{_ as a,h as o,m as s}from"./GenericShape-BVUP2Hr-.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import{Dt as c,Ht as l,xt as u,y as d}from"./three.module-BCXZgYUA.js";import"./mission-CgOJ5O6t.js";import"./engineStore-DYTudHqF.js";import{t as f}from"./Texture-D0BO6ArI.js";import{p}from"./loaders-Ba8dC3nL.js";import"./FloatingLabel-DtfOOmmG.js";import"./globalFogUniforms-BmkrmymO.js";var m=t(),h=e(n(),1),g=r(),_=new l,v=new l,y=new l,b=new l,x=new l,S=new l,C=new l(0,1,0);function w(e){let t=(0,m.c)(14),{entity:n}=e,{visual:r}=n,i;t[0]===r.texture?i=t[1]:(i=p(r.texture),t[0]=r.texture,t[1]=i);let a=f(i,T),o=Array.isArray(a)?a[0]:a,s;t[2]!==r.color.b||t[3]!==r.color.g||t[4]!==r.color.r?(s=new d().setRGB(r.color.r,r.color.g,r.color.b,c),t[2]=r.color.b,t[3]=r.color.g,t[4]=r.color.r,t[5]=s):s=t[5];let l=s,u;t[6]===r.size?u=t[7]:(u=[r.size,r.size,1],t[6]=r.size,t[7]=u);let h;t[8]!==l||t[9]!==o?(h=(0,g.jsx)(`spriteMaterial`,{map:o,color:l,transparent:!0,blending:2,depthWrite:!1,toneMapped:!1}),t[8]=l,t[9]=o,t[10]=h):h=t[10];let _;return t[11]!==u||t[12]!==h?(_=(0,g.jsx)(`sprite`,{scale:u,children:h}),t[11]=u,t[12]=h,t[13]=_):_=t[13],_}function T(e){o(Array.isArray(e)?e[0]:e)}function E(e){let t=(0,m.c)(29),{entity:n}=e,{visual:r}=n,o=(0,h.useRef)(null),c=(0,h.useRef)(null),l=(0,h.useRef)(null),d;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(d=new u,t[0]=d):d=t[0];let w=(0,h.useRef)(d),T;t[1]===r.texture?T=t[2]:(T=p(r.texture),t[1]=r.texture,t[2]=T);let E=r.crossTexture??r.texture,O;t[3]===E?O=t[4]:(O=p(E),t[3]=E,t[4]=O);let k;t[5]!==T||t[6]!==O?(k=[T,O],t[5]=T,t[6]=O,t[7]=k):k=t[7];let A=f(k,D),j;t[8]===A?j=t[9]:(j=Array.isArray(A)?A:[A,A],t[8]=A,t[9]=j);let[M,N]=j,P;t[10]!==n.direction||t[11]!==n.keyframes?.[0]||t[12]!==r.crossSize||t[13]!==r.crossViewAng||t[14]!==r.renderCross||t[15]!==r.tracerLength||t[16]!==r.tracerWidth?(P=e=>{let{camera:t}=e,i=o.current,u=c.current;if(!i||!u)return;let d=n.keyframes?.[0],f=d?.position,p=n.direction??d?.velocity;if(!f||!p){i.visible=!1,l.current&&(l.current.visible=!1);return}if(a(p,_),_.lengthSq()<1e-8){i.visible=!1,l.current&&(l.current.visible=!1);return}_.normalize(),i.visible=!0,a(f,S),v.copy(S).sub(t.position),y.crossVectors(v,_),y.lengthSq()<1e-8&&(y.crossVectors(C,_),y.lengthSq()<1e-8&&y.set(1,0,0)),y.normalize().multiplyScalar(r.tracerWidth);let m=r.tracerLength*.5;b.copy(_).multiplyScalar(-m),x.copy(_).multiplyScalar(m);let h=u.array;h[0]=b.x+y.x,h[1]=b.y+y.y,h[2]=b.z+y.z,h[3]=b.x-y.x,h[4]=b.y-y.y,h[5]=b.z-y.z,h[6]=x.x-y.x,h[7]=x.y-y.y,h[8]=x.z-y.z,h[9]=x.x+y.x,h[10]=x.y+y.y,h[11]=x.z+y.z,u.needsUpdate=!0;let g=l.current;if(!g)return;if(!r.renderCross){g.visible=!1;return}v.normalize();let T=_.dot(v);if(T>-r.crossViewAng&&T<r.crossViewAng){g.visible=!1;return}g.visible=!0,s(_,w.current),g.quaternion.copy(w.current),g.scale.setScalar(r.crossSize)},t[10]=n.direction,t[11]=n.keyframes?.[0],t[12]=r.crossSize,t[13]=r.crossViewAng,t[14]=r.renderCross,t[15]=r.tracerLength,t[16]=r.tracerWidth,t[17]=P):P=t[17],i(P);let F;t[18]===Symbol.for(`react.memo_cache_sentinel`)?(F=(0,g.jsx)(`bufferAttribute`,{ref:c,attach:`attributes-position`,args:[new Float32Array(12),3]}),t[18]=F):F=t[18];let I;t[19]===Symbol.for(`react.memo_cache_sentinel`)?(I=(0,g.jsx)(`bufferAttribute`,{attach:`attributes-uv`,args:[new Float32Array([0,0,0,1,1,1,1,0]),2]}),t[19]=I):I=t[19];let L;t[20]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,g.jsxs)(`bufferGeometry`,{children:[F,I,(0,g.jsx)(`bufferAttribute`,{attach:`index`,args:[new Uint16Array([0,1,2,0,2,3]),1]})]}),t[20]=L):L=t[20];let R;t[21]===M?R=t[22]:(R=(0,g.jsxs)(`mesh`,{ref:o,children:[L,(0,g.jsx)(`meshBasicMaterial`,{map:M,transparent:!0,blending:2,side:2,depthWrite:!1,toneMapped:!1})]}),t[21]=M,t[22]=R);let z;t[23]!==N||t[24]!==r.renderCross?(z=r.renderCross?(0,g.jsxs)(`mesh`,{ref:l,children:[(0,g.jsxs)(`bufferGeometry`,{children:[(0,g.jsx)(`bufferAttribute`,{attach:`attributes-position`,args:[new Float32Array([-.5,0,-.5,.5,0,-.5,.5,0,.5,-.5,0,.5]),3]}),(0,g.jsx)(`bufferAttribute`,{attach:`attributes-uv`,args:[new Float32Array([0,0,0,1,1,1,1,0]),2]}),(0,g.jsx)(`bufferAttribute`,{attach:`index`,args:[new Uint16Array([0,1,2,0,2,3]),1]})]}),(0,g.jsx)(`meshBasicMaterial`,{map:N,transparent:!0,blending:2,side:2,depthWrite:!1,toneMapped:!1})]}):null,t[23]=N,t[24]=r.renderCross,t[25]=z):z=t[25];let B;return t[26]!==R||t[27]!==z?(B=(0,g.jsxs)(g.Fragment,{children:[R,z]}),t[26]=R,t[27]=z,t[28]=B):B=t[28],B}function D(e){let t=Array.isArray(e)?e:[e];for(let e of t)o(e)}export{w as SpriteProjectile,E as TracerProjectile};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
._Dialog_6c89x_1{color:#b0d5c9;-webkit-user-select:text;user-select:text;-webkit-touch-callout:default;background:#142526cc;border:1px solid #41838b99;border-radius:4px;outline:none;max-width:calc(100dvw - 40px);max-height:calc(100dvh - 40px);font-size:14px;line-height:1.5;position:relative;overflow:hidden;box-shadow:0 0 50px #0006,inset 0 0 60px #01070d99}._Overlay_6c89x_20{z-index:10;background:#000000b3;justify-content:center;align-items:center;padding:20px;display:flex;position:fixed;inset:0}._DialogButton_6c89x_31{color:#99fff1;text-shadow:0 -1px 1px #0006;cursor:pointer;background:linear-gradient(#30a497cc,#1f9688cc 33%,#218377cc 67%,#046564cc);border:1px solid #387c74cc;border-top-color:#57b7b9cc;border-radius:4px;padding:4px 18px;font-family:inherit;font-size:14px;font-weight:500;box-shadow:inset 0 0 4px #02808e80}._DialogButton_6c89x_31:hover:not(:disabled){color:#b1fff5;border:1px solid #409188e6;border-top-color:#5ac6c2e6;box-shadow:inset 0 0 4px #02808e80,0 0 5px #3effbf80}._DialogButton_6c89x_31:active:not(:disabled){transform:translateY(1px)}._DialogButton_6c89x_31:disabled{opacity:.4;cursor:not-allowed}._Secondary_6c89x_70{box-shadow:none;color:#a2e2cfcc;text-shadow:none;background:0 0;border:1px solid #387c74cc}._Secondary_6c89x_70:hover:not(:disabled){color:#a9ffe5cc;border:1px solid #3f9087e6}._Actions_6c89x_84{align-items:center;gap:10px;display:flex}@media (width<=719px){._Dialog_6c89x_1{border-radius:0;max-width:calc(100dvw - 20px);max-height:calc(100dvh - 20px)}}@media (width<=639px){._Overlay_6c89x_20{padding:10px}}._Dialog_4agrm_1{grid-template-rows:auto 1fr auto;grid-template-columns:100%;width:860px;height:560px;display:grid}._Header_4agrm_14{border-bottom:1px solid #00bedc40;align-items:center;gap:12px;padding:12px 16px 10px;display:flex}._Title_4agrm_22{color:#7dffff;text-shadow:0 1px 6px #0006;flex:1;margin:0;font-size:18px;font-weight:500}._HiddenRadio_4agrm_31{opacity:0;z-index:-1;pointer-events:none;width:0;height:0;position:absolute;overflow:hidden}._RefreshButton_4agrm_41{padding:3px 14px;font-size:12px}._ServerCount_4agrm_47{color:#c9dcd866;font-size:12px}._TableWrapper_4agrm_52{min-height:0;overflow-y:auto}._Table_4agrm_52{border-collapse:collapse;-webkit-user-select:none;user-select:none;width:100%;min-height:0;font-size:13px}._Table_4agrm_52 th{z-index:1;text-align:left;cursor:pointer;-webkit-user-select:none;user-select:none;letter-spacing:.04em;text-transform:uppercase;color:#7dffff99;background:#0a191af2;border-bottom:1px solid #00bedc33;padding:6px 12px;font-size:11px;font-weight:500;position:sticky;top:0}._Table_4agrm_52 th:hover{color:#7dffff}._Table_4agrm_52 th:nth-child(2),._Table_4agrm_52 td:nth-child(2),._Table_4agrm_52 th:nth-child(3),._Table_4agrm_52 td:nth-child(3){text-align:right}._Table_4agrm_52 td{z-index:0;white-space:nowrap;text-overflow:ellipsis;border-bottom:1px solid #ffffff0a;max-width:340px;padding:3px 12px;font-weight:500;position:relative;overflow:hidden}._Table_4agrm_52 td._EmptyServer_4agrm_105{opacity:.4}._Table_4agrm_52 tbody tr:not(._Empty_4agrm_105){cursor:pointer}._Table_4agrm_52 tbody tr:not(._Empty_4agrm_105):hover{background:#41838b1f}._Table_4agrm_52 tbody tr:has(input:checked){color:#1e2828;background:#5dffe1e6!important}._PasswordIcon_4agrm_122{color:#ffc83c99;margin-right:4px;font-size:11px}._Empty_4agrm_105 td{text-align:center;color:#c9dcd84d;font-style:italic;padding:32px 12px!important}._Footer_4agrm_135{background:#021415b3;border-top:1px solid #00bedc40;flex-shrink:0;justify-content:space-between;align-items:center;gap:16px;padding:10px 12px;display:flex}._JoinButton_4agrm_146{min-width:100px}._WarriorField_4agrm_155{align-items:center;gap:8px;display:flex}._WarriorLabel_4agrm_161{color:#7dffff99;font-size:12px;font-weight:500}._WarriorInput_4agrm_167{color:#b0d5c9;background:#00323ccc;border:1px solid #41838b80;border-radius:2px;outline:none;width:130px;padding:4px 6px;font-family:inherit;font-size:13px}._WarriorInput_4agrm_167:focus{border-color:#7dffff99}._WarriorInput_4agrm_167::placeholder{color:#c9dcd84d}._Hint_4agrm_187{color:#c9dcd84d;margin:0 auto;font-size:12px}@media (width<=719px){._Hint_4agrm_187{display:none}._Table_4agrm_52 td{max-width:200px}._CloseButton_4agrm_151{margin-left:auto}}@media (width<=539px){._Footer_4agrm_135{flex-direction:column;gap:8px}._Actions_4agrm_193{width:100%}._WarriorLabel_4agrm_161{font-size:14px}._WarriorInput_4agrm_167{min-width:12em;font-size:16px}._JoinButton_4agrm_146,._CloseButton_4agrm_151{flex:1 0 auto;height:32px}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n}from"./jsx-runtime-BpGWiA-R.js";import{i as r,o as i}from"./react-three-fiber.esm-IOIyqSDz.js";import{r as a}from"./SettingsProvider-BTNRdL6b.js";import"./traditional-ec-lUAFC.js";import{o,r as s}from"./index-CmEWnrr6.js";var c=t(),l=e(n(),1),u=.004,d=2.5,f=.08,p=.15,m=.15;function h(){let e=(0,c.c)(17),{speedMultiplier:t,touchMode:n,invertDrag:h,invertJoystick:_}=a(),v=i(g),{moveState:y,lookState:b}=o(),x=s(),S=(0,l.useRef)(null),C;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(C={x:0,y:0},e[0]=C):C=e[0];let w=(0,l.useRef)(C),T;e[1]===h?T=e[2]:(T=()=>h,e[1]=h,e[2]=T);let E=(0,l.useEffectEvent)(T),D=(0,l.useRef)(0),O=(0,l.useRef)(0),k;e[3]!==E||e[4]!==v.domElement||e[5]!==n?(k=()=>{if(n!==`moveLookStick`)return;let e=v.domElement,t=e=>{if(S.current===null)for(;0<e.changedTouches.length;){let t=e.changedTouches[0];S.current=t.identifier,w.current={x:t.clientX,y:t.clientY};break}},r=e=>{if(S.current!==null)for(let t=0;t<e.changedTouches.length;t++){let n=e.changedTouches[t];if(n.identifier===S.current){let e=n.clientX-w.current.x,t=n.clientY-w.current.y;w.current={x:n.clientX,y:n.clientY};let r=E()?1:-1;D.current+=r*e*u,O.current+=r*t*u;break}}},i=e=>{for(let t=0;t<e.changedTouches.length;t++)if(e.changedTouches[t].identifier===S.current){S.current=null;break}};return e.addEventListener(`touchstart`,t,{passive:!0}),e.addEventListener(`touchmove`,r,{passive:!0}),e.addEventListener(`touchend`,i,{passive:!0}),e.addEventListener(`touchcancel`,i,{passive:!0}),()=>{e.removeEventListener(`touchstart`,t),e.removeEventListener(`touchmove`,r),e.removeEventListener(`touchend`,i),e.removeEventListener(`touchcancel`,i),S.current=null}},e[3]=E,e[4]=v.domElement,e[5]=n,e[6]=k):k=e[6];let A;e[7]!==v.domElement||e[8]!==n?(A=[v.domElement,n],e[7]=v.domElement,e[8]=n,e[9]=A):A=e[9],(0,l.useEffect)(k,A);let j;return e[10]!==_||e[11]!==b.current||e[12]!==y.current||e[13]!==x||e[14]!==t||e[15]!==n?(j=(e,r)=>{let{force:i,angle:a}=y.current,{force:o,angle:s}=b.current,c=D.current,l=O.current;D.current=0,O.current=0;let u=0,h=0;if(n===`dualStick`){if(o>p){let e=(o-p)/(1-p),t=Math.cos(s),n=Math.sin(s),i=_?1:-1;c-=i*t*e*d*r,l+=i*n*e*d*r}if(i>f){let e=(i-f)/(1-f),n=Math.cos(a),r=Math.sin(a);u=Math.max(-1,Math.min(1,n*e*t)),h=Math.max(-1,Math.min(1,r*e*t))}}else if(n===`moveLookStick`&&i>0&&(h=Math.max(-1,Math.min(1,.5*t)),i>=m)){let e=Math.cos(a),t=Math.sin(a),n=(i-m)/(1-m),o=_?1:-1;c-=o*e*n*d*.5*r,l+=o*t*n*d*.5*r}!(c!==0||l!==0)&&!(u!==0||h!==0)||x({deltaYaw:c,deltaPitch:l,x:u,y:h,z:0,triggers:[],delta:r})},e[10]=_,e[11]=b.current,e[12]=y.current,e[13]=x,e[14]=t,e[15]=n,e[16]=j):j=e[16],r(j),null}function g(e){return e.gl}export{h as TouchHandler};
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n}from"./jsx-runtime-BpGWiA-R.js";import{i as r,o as i}from"./react-three-fiber.esm-IOIyqSDz.js";import{r as a}from"./SettingsProvider-Dls8-Ecn.js";import"./traditional-ec-lUAFC.js";import{o,r as s}from"./index-BngaOpHI.js";var c=t(),l=e(n(),1),u=.004,d=2.5,f=.08,p=.15,m=.15;function h(){let e=(0,c.c)(17),{speedMultiplier:t,touchMode:n,invertDrag:h,invertJoystick:_}=a(),v=i(g),{moveState:y,lookState:b}=o(),x=s(),S=(0,l.useRef)(null),C;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(C={x:0,y:0},e[0]=C):C=e[0];let w=(0,l.useRef)(C),T;e[1]===h?T=e[2]:(T=()=>h,e[1]=h,e[2]=T);let E=(0,l.useEffectEvent)(T),D=(0,l.useRef)(0),O=(0,l.useRef)(0),k;e[3]!==E||e[4]!==v.domElement||e[5]!==n?(k=()=>{if(n!==`moveLookStick`)return;let e=v.domElement,t=e=>{if(S.current===null)for(;0<e.changedTouches.length;){let t=e.changedTouches[0];S.current=t.identifier,w.current={x:t.clientX,y:t.clientY};break}},r=e=>{if(S.current!==null)for(let t=0;t<e.changedTouches.length;t++){let n=e.changedTouches[t];if(n.identifier===S.current){let e=n.clientX-w.current.x,t=n.clientY-w.current.y;w.current={x:n.clientX,y:n.clientY};let r=E()?1:-1;D.current+=r*e*u,O.current+=r*t*u;break}}},i=e=>{for(let t=0;t<e.changedTouches.length;t++)if(e.changedTouches[t].identifier===S.current){S.current=null;break}};return e.addEventListener(`touchstart`,t,{passive:!0}),e.addEventListener(`touchmove`,r,{passive:!0}),e.addEventListener(`touchend`,i,{passive:!0}),e.addEventListener(`touchcancel`,i,{passive:!0}),()=>{e.removeEventListener(`touchstart`,t),e.removeEventListener(`touchmove`,r),e.removeEventListener(`touchend`,i),e.removeEventListener(`touchcancel`,i),S.current=null}},e[3]=E,e[4]=v.domElement,e[5]=n,e[6]=k):k=e[6];let A;e[7]!==v.domElement||e[8]!==n?(A=[v.domElement,n],e[7]=v.domElement,e[8]=n,e[9]=A):A=e[9],(0,l.useEffect)(k,A);let j;return e[10]!==_||e[11]!==b.current||e[12]!==y.current||e[13]!==x||e[14]!==t||e[15]!==n?(j=(e,r)=>{let{force:i,angle:a}=y.current,{force:o,angle:s}=b.current,c=D.current,l=O.current;D.current=0,O.current=0;let u=0,h=0;if(n===`dualStick`){if(o>p){let e=(o-p)/(1-p),t=Math.cos(s),n=Math.sin(s),i=_?1:-1;c-=i*t*e*d*r,l+=i*n*e*d*r}if(i>f){let e=(i-f)/(1-f),n=Math.cos(a),r=Math.sin(a);u=Math.max(-1,Math.min(1,n*e*t)),h=Math.max(-1,Math.min(1,r*e*t))}}else if(n===`moveLookStick`&&i>0&&(h=Math.max(-1,Math.min(1,.5*t)),i>=m)){let e=Math.cos(a),t=Math.sin(a),n=(i-m)/(1-m),o=_?1:-1;c-=o*e*n*d*.5*r,l+=o*t*n*d*.5*r}!(c!==0||l!==0)&&!(u!==0||h!==0)||x({deltaYaw:c,deltaPitch:l,x:u,y:h,z:0,triggers:[],delta:r})},e[10]=_,e[11]=b.current,e[12]=y.current,e[13]=x,e[14]=t,e[15]=n,e[16]=j):j=e[16],r(j),null}function g(e){return e.gl}export{h as TouchHandler};

View file

@ -1,2 +1,2 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/nipplejs-B4bk15S1.js","assets/chunk-DECur_0Z.js"])))=>i.map(i=>d[i]);
import{r as e}from"./chunk-DECur_0Z.js";import{r as t,t as n}from"./jsx-runtime-BpGWiA-R.js";import{r}from"./SettingsProvider-BTNRdL6b.js";import{t as i}from"./preload-helper-4WkklRMx.js";import{o as a}from"./index-CmEWnrr6.js";var o=e(t(),1),s={Joystick:`_Joystick_155b9_1`,Left:`_Left_155b9_11 _Joystick_155b9_1`,Right:`_Right_155b9_17 _Joystick_155b9_1`},c=n();function l(e){let t=e.querySelector(`.back`);t&&(t.style.background=`rgba(3, 79, 76, 0.6)`,t.style.border=`1px solid rgba(0, 219, 223, 0.5)`,t.style.boxShadow=`inset 0 0 10px rgba(0, 0, 0, 0.7)`);let n=e.querySelector(`.front`);n&&(n.style.background=`radial-gradient(circle at 50% 50%, rgba(23, 247, 198, 0.9) 0%, rgba(9, 184, 170, 0.95) 100%)`,n.style.border=`2px solid rgba(255, 255, 255, 0.4)`,n.style.boxShadow=`0 2px 4px rgba(0, 0, 0, 0.5), 0 1px 1px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15), inset 0 -1px 2px rgba(0, 0, 0, 0.3)`)}function u(){let{touchMode:t}=r(),[n,u]=(0,o.useState)(null),[d,f]=(0,o.useState)(null),{moveState:p,lookState:m,setMoveState:h,setLookState:g}=a();(0,o.useEffect)(()=>{if(!n)return;let t=null,r=!1;return i(()=>import(`./nipplejs-B4bk15S1.js`).then(t=>e(t.default,1)).then(e=>{r||(t=e.default.create({zone:n,mode:`static`,position:{left:`70px`,bottom:`70px`},size:120,restOpacity:.9,dynamicPage:!0}),l(n),t.on(`move`,(e,t)=>{h({angle:t.angle.radian,force:Math.min(1,t.force)})}),t.on(`end`,()=>{h({force:0})}))}),__vite__mapDeps([0,1])),()=>{r=!0,t?.destroy()}},[p,n,h]),(0,o.useEffect)(()=>{if(!d)return;let t=null,n=!1;return i(()=>import(`./nipplejs-B4bk15S1.js`).then(t=>e(t.default,1)).then(e=>{n||(t=e.default.create({zone:d,mode:`static`,position:{right:`70px`,bottom:`70px`},size:120,restOpacity:.9,dynamicPage:!0}),l(d),t.on(`move`,(e,t)=>{g({angle:t.angle.radian,force:Math.min(1,t.force)})}),t.on(`end`,()=>{g({force:0})}))}),__vite__mapDeps([0,1])),()=>{n=!0,t?.destroy()}},[m,d,g]);let _=()=>{document.activeElement instanceof HTMLElement&&document.activeElement.blur()};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(`div`,{ref:u,className:t===`dualStick`?s.Left:s.Joystick,onContextMenu:e=>e.preventDefault(),onTouchStart:_},t),t===`dualStick`?(0,c.jsx)(`div`,{ref:f,className:s.Right,onContextMenu:e=>e.preventDefault(),onTouchStart:_}):null]})}export{u as TouchJoystick};
import{r as e}from"./chunk-DECur_0Z.js";import{r as t,t as n}from"./jsx-runtime-BpGWiA-R.js";import{r}from"./SettingsProvider-Dls8-Ecn.js";import{t as i}from"./preload-helper-4WkklRMx.js";import{o as a}from"./index-BngaOpHI.js";var o=e(t(),1),s={Joystick:`_Joystick_155b9_1`,Left:`_Left_155b9_11 _Joystick_155b9_1`,Right:`_Right_155b9_17 _Joystick_155b9_1`},c=n();function l(e){let t=e.querySelector(`.back`);t&&(t.style.background=`rgba(3, 79, 76, 0.6)`,t.style.border=`1px solid rgba(0, 219, 223, 0.5)`,t.style.boxShadow=`inset 0 0 10px rgba(0, 0, 0, 0.7)`);let n=e.querySelector(`.front`);n&&(n.style.background=`radial-gradient(circle at 50% 50%, rgba(23, 247, 198, 0.9) 0%, rgba(9, 184, 170, 0.95) 100%)`,n.style.border=`2px solid rgba(255, 255, 255, 0.4)`,n.style.boxShadow=`0 2px 4px rgba(0, 0, 0, 0.5), 0 1px 1px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15), inset 0 -1px 2px rgba(0, 0, 0, 0.3)`)}function u(){let{touchMode:t}=r(),[n,u]=(0,o.useState)(null),[d,f]=(0,o.useState)(null),{moveState:p,lookState:m,setMoveState:h,setLookState:g}=a();(0,o.useEffect)(()=>{if(!n)return;let t=null,r=!1;return i(()=>import(`./nipplejs-B4bk15S1.js`).then(t=>e(t.default,1)).then(e=>{r||(t=e.default.create({zone:n,mode:`static`,position:{left:`70px`,bottom:`70px`},size:120,restOpacity:.9,dynamicPage:!0}),l(n),t.on(`move`,(e,t)=>{h({angle:t.angle.radian,force:Math.min(1,t.force)})}),t.on(`end`,()=>{h({force:0})}))}),__vite__mapDeps([0,1])),()=>{r=!0,t?.destroy()}},[p,n,h]),(0,o.useEffect)(()=>{if(!d)return;let t=null,n=!1;return i(()=>import(`./nipplejs-B4bk15S1.js`).then(t=>e(t.default,1)).then(e=>{n||(t=e.default.create({zone:d,mode:`static`,position:{right:`70px`,bottom:`70px`},size:120,restOpacity:.9,dynamicPage:!0}),l(d),t.on(`move`,(e,t)=>{g({angle:t.angle.radian,force:Math.min(1,t.force)})}),t.on(`end`,()=>{g({force:0})}))}),__vite__mapDeps([0,1])),()=>{n=!0,t?.destroy()}},[m,d,g]);let _=()=>{document.activeElement instanceof HTMLElement&&document.activeElement.blur()};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(`div`,{ref:u,className:t===`dualStick`?s.Left:s.Joystick,onContextMenu:e=>e.preventDefault(),onTouchStart:_},t),t===`dualStick`?(0,c.jsx)(`div`,{ref:f,className:s.Right,onContextMenu:e=>e.preventDefault(),onTouchStart:_}):null]})}export{u as TouchJoystick};

View file

@ -1,4 +1,4 @@
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{i,o as a}from"./react-three-fiber.esm-IOIyqSDz.js";import{a as o,i as s}from"./SettingsProvider-BTNRdL6b.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import{Et as c,ht as l,kt as u,tt as d,y as f}from"./three.module-BCXZgYUA.js";import"./mission-CgOJ5O6t.js";import{t as p}from"./extends-_1DzYWEQ.js";import{t as m}from"./Texture-D0BO6ArI.js";import{C as ee,S as te,w as ne}from"./index-CmEWnrr6.js";import{p as h}from"./loaders-YyTXpfdm.js";import{a as g,c as _,f as v,t as y}from"./globalFogUniforms-BmkrmymO.js";var b=e(n());function x(e,t){let n=e+`Geometry`;return b.forwardRef(({args:e,children:r,...i},a)=>{let o=b.useRef(null);return b.useImperativeHandle(a,()=>o.current),b.useLayoutEffect(()=>void t?.(o.current)),b.createElement(`mesh`,p({ref:o},i),b.createElement(n,{attach:`geometry`,args:e}),r)})}var re=x(`box`),S=t(),C=`
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{i,o as a}from"./react-three-fiber.esm-IOIyqSDz.js";import{a as o,i as s}from"./SettingsProvider-Dls8-Ecn.js";import"./logger-CC5j_O4o.js";import"./traditional-ec-lUAFC.js";import{Et as c,ht as l,kt as u,tt as d,y as f}from"./three.module-BCXZgYUA.js";import"./mission-CgOJ5O6t.js";import{t as p}from"./extends-_1DzYWEQ.js";import{t as m}from"./Texture-D0BO6ArI.js";import{C as ee,S as te,w as ne}from"./index-BngaOpHI.js";import{p as h}from"./loaders-Ba8dC3nL.js";import{a as g,c as _,f as v,t as y}from"./globalFogUniforms-BmkrmymO.js";var b=e(n());function x(e,t){let n=e+`Geometry`;return b.forwardRef(({args:e,children:r,...i},a)=>{let o=b.useRef(null);return b.useImperativeHandle(a,()=>o.current),b.useLayoutEffect(()=>void t?.(o.current)),b.createElement(`mesh`,p({ref:o},i),b.createElement(n,{attach:`geometry`,args:e}),r)})}var re=x(`box`),S=t(),C=`
#include <fog_pars_vertex>
#ifdef USE_FOG

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
import{c as e,d as t,n,s as r,t as i}from"./manifest-NjKKupeg.js";import{t as a}from"./logger-CC5j_O4o.js";import{a as o}from"./mission-CgOJ5O6t.js";function s(e){return e.split(/(?:\r\n|\r|\n)/g).map(e=>e.trim()).filter(Boolean).filter(e=>!e.startsWith(`;`)).map(e=>{let t=e.match(/^(.+)\s(\d+)$/);if(t){let e=parseInt(t[2],10);return{name:t[1],frameCount:e}}else return{name:e,frameCount:1}})}var c=256;function l(e){let t=new DataView(e),n=0,r=t.getUint8(n++),i=new Uint16Array(c*c),a=[],o=e=>{let r=``;for(let i=0;i<e;i++){let e=t.getUint8(n+i);if(e===0)break;r+=String.fromCharCode(e)}return n+=e,r};for(let e=0;e<c*c;e++){let r=t.getUint16(n,!0);n+=2,i[e]=r}n+=256*256;let s=i;for(let e=0;e<8;e++){let r=t.getUint8(n++),i=o(r);e<6&&r>0&&a.push(i)}let l=[];for(let e of a){let e=new Uint8Array(c*c);for(let r=0;r<c*c;r++)e[r]=t.getUint8(n++);l.push(e)}return{version:r,textureNames:a,heightMap:s,alphaMaps:l}}var u=a(`loaders`),d=`/t2-mapper`,f=`${d}/base/`,p=`${d}/magenta.png`;function m(e,t){let n;try{n=i(e)}catch(n){if(t)return u.warn(`Resource "%s" not found — rendering fallback`,e),t;throw n}let[a,o]=r(n);return a?`${f}@vl2/${a}/${o}`:`${f}${o}`}function h(e){return m(`interiors/${e}`).replace(/\.dif$/i,`.glb`)}function g(e){return m(`shapes/${e}`).replace(/\.dts$/i,`.glb`)}function _(t){return t=t.replace(/^terrain\./,``),m(e(`textures/terrain/${t}`),p)}function v(n,r){let i=t(r).split(`/`);return m(e(`${i.length>1?i.slice(0,-1).join(`/`)+`/`:``}${n}`),p)}function y(t){return m(e(`textures/${t}`),p)}function b(e){return m(`audio/${e}`).replace(/\.wav$/i,`.m4a`)}async function x(e){let t=m(`textures/${e}`);return(await(await fetch(t)).text()).split(/(?:\r\n|\r|\n)/).map(e=>{if(e=e.trim(),!e.startsWith(`;`))return e}).filter(Boolean)}async function S(e){let t=n(e),r=await(await fetch(m(t.resourcePath))).arrayBuffer(),i;try{i=new TextDecoder(`utf-8`,{fatal:!0}).decode(r)}catch{i=new TextDecoder(`windows-1252`).decode(r)}return i=i.replaceAll(`<EFBFBD>`,`'`),o(i)}async function C(e){let t=m(`terrains/${e}`);u.debug(`Fetching terrain: %s`,t);let n=await fetch(t);if(!n.ok)throw Error(`[loadTerrain] Failed to fetch ${t}: ${n.status} ${n.statusText}`);let r=await n.arrayBuffer();return u.debug(`Loaded terrain %s: %d bytes`,e,r.byteLength),l(r)}async function w(e){let t=m(e);return s(await(await fetch(t)).text())}export{v as a,w as c,g as d,_ as f,m as i,S as l,f as n,h as o,y as p,b as r,x as s,p as t,C as u};

View file

@ -1 +0,0 @@
import{c as e,n as t,s as n,t as r,u as i}from"./manifest-DfHcIJuP.js";import{t as a}from"./logger-CC5j_O4o.js";import{a as o}from"./mission-CgOJ5O6t.js";function s(e){return e.split(/(?:\r\n|\r|\n)/g).map(e=>e.trim()).filter(Boolean).filter(e=>!e.startsWith(`;`)).map(e=>{let t=e.match(/^(.+)\s(\d+)$/);if(t){let e=parseInt(t[2],10);return{name:t[1],frameCount:e}}else return{name:e,frameCount:1}})}var c=256;function l(e){let t=new DataView(e),n=0,r=t.getUint8(n++),i=new Uint16Array(c*c),a=[],o=e=>{let r=``;for(let i=0;i<e;i++){let e=t.getUint8(n+i);if(e===0)break;r+=String.fromCharCode(e)}return n+=e,r};for(let e=0;e<c*c;e++){let r=t.getUint16(n,!0);n+=2,i[e]=r}n+=256*256;let s=i;for(let e=0;e<8;e++){let r=t.getUint8(n++),i=o(r);e<6&&r>0&&a.push(i)}let l=[];for(let e of a){let e=new Uint8Array(c*c);for(let r=0;r<c*c;r++)e[r]=t.getUint8(n++);l.push(e)}return{version:r,textureNames:a,heightMap:s,alphaMaps:l}}var u=a(`loaders`),d=`/t2-mapper`,f=`${d}/base/`,p=`${d}/magenta.png`;function m(e,t){let i;try{i=r(e)}catch(n){if(t)return u.warn(`Resource "%s" not found — rendering fallback`,e),t;throw n}let[a,o]=n(i);return a?`${f}@vl2/${a}/${o}`:`${f}${o}`}function h(e){return m(`interiors/${e}`).replace(/\.dif$/i,`.glb`)}function g(e){return m(`shapes/${e}`).replace(/\.dts$/i,`.glb`)}function _(t){return t=t.replace(/^terrain\./,``),m(e(`textures/terrain/${t}`),p)}function v(t,n){let r=i(n).split(`/`);return m(e(`${r.length>1?r.slice(0,-1).join(`/`)+`/`:``}${t}`),p)}function y(t){return m(e(`textures/${t}`),p)}function b(e){return m(`audio/${e}`).replace(/\.wav$/i,`.m4a`)}async function x(e){let t=m(`textures/${e}`);return(await(await fetch(t)).text()).split(/(?:\r\n|\r|\n)/).map(e=>{if(e=e.trim(),!e.startsWith(`;`))return e}).filter(Boolean)}async function S(e){let n=t(e),r=await(await fetch(m(n.resourcePath))).arrayBuffer(),i;try{i=new TextDecoder(`utf-8`,{fatal:!0}).decode(r)}catch{i=new TextDecoder(`windows-1252`).decode(r)}return i=i.replaceAll(`<EFBFBD>`,`'`),o(i)}async function C(e){let t=m(`terrains/${e}`);u.debug(`Fetching terrain: %s`,t);let n=await fetch(t);if(!n.ok)throw Error(`[loadTerrain] Failed to fetch ${t}: ${n.status} ${n.statusText}`);let r=await n.arrayBuffer();return u.debug(`Loaded terrain %s: %d bytes`,e,r.byteLength),l(r)}async function w(e){let t=m(e);return s(await(await fetch(t)).text())}export{v as a,w as c,g as d,_ as f,m as i,S as l,f as n,h as o,y as p,b as r,x as s,p as t,C as u};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
import{r as e,t}from"./useBaseQuery-D6DCMYV6.js";function n(n,r){return t(n,e,r)}export{n as t};

View file

@ -0,0 +1 @@
import{r as e,t}from"./useBaseQuery-DK4WLBLs.js";function n(n,r){return t(n,e,r)}export{n as t};

View file

@ -10,7 +10,7 @@
<meta name="description" content="Tribes 2 forever." />
<link rel="icon" type="image/png" href="/t2-mapper/icon.png" />
<link rel="preconnect" href="https://www.gstatic.com" crossorigin />
<script type="module" crossorigin src="/t2-mapper/assets/index-CmEWnrr6.js"></script>
<script type="module" crossorigin src="/t2-mapper/assets/index-BngaOpHI.js"></script>
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/chunk-DECur_0Z.js">
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/preload-helper-4WkklRMx.js">
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/logger-CC5j_O4o.js">
@ -21,10 +21,10 @@
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/KeyboardControls-BqqT6pch.js">
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/three.module-BCXZgYUA.js">
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/react-three-fiber.esm-IOIyqSDz.js">
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/manifest-DfHcIJuP.js">
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/SettingsProvider-BTNRdL6b.js">
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/manifest-NjKKupeg.js">
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/SettingsProvider-Dls8-Ecn.js">
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/iconBase-BCRUFbxq.js">
<link rel="stylesheet" crossorigin href="/t2-mapper/assets/index-Bj8v-HTr.css">
<link rel="stylesheet" crossorigin href="/t2-mapper/assets/index-0DffZSbP.css">
</head>
<body>
<div id="root"></div>

8
env.d.ts vendored Normal file
View file

@ -0,0 +1,8 @@
/** Vite-style import.meta.env, shared across app and node tsconfigs. */
interface ImportMetaEnv {
readonly VITE_PUBLIC_LOG?: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

View file

@ -19,5 +19,15 @@ export default defineConfig([
ecmaVersion: 2020,
globals: globals.browser,
},
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{ args: "none", caughtErrors: "none", varsIgnorePattern: "^_" },
],
"react-hooks/set-state-in-effect": "off",
"react-refresh/only-export-components": "warn",
"react-hooks/immutability": "warn",
},
},
]);

1
generated/TorqueScript.d.ts vendored Normal file
View file

@ -0,0 +1 @@
export function parse(input: string, options?: Record<string, unknown>): any;

View file

@ -27,7 +27,7 @@
"test-connect": "node --env-file-if-exists=.env.development.local --import=tsx/esm scripts/test-connect.ts",
"test:watch": "vitest",
"test": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --build --noEmit"
},
"dependencies": {
"@ariakit/react": "^0.4.23",

View file

@ -35,7 +35,11 @@ export class BitStreamWriter {
}
writeFlag(value: boolean): void {
if (this.bitNum >= this.maxBitNum) return;
if (this.bitNum >= this.maxBitNum) {
throw new RangeError(
`BitStreamWriter overflow: writeFlag at position ${this.bitNum}, max ${this.maxBitNum}`,
);
}
if (value) {
this.data[this.bitNum >> 3] |= 1 << (this.bitNum & 0x7);
} else {
@ -47,6 +51,11 @@ export class BitStreamWriter {
/** Write N bits from an unsigned integer, LSB-first. */
writeInt(value: number, bitCount: number): void {
if (bitCount === 0) return;
if (this.bitNum + bitCount > this.maxBitNum) {
throw new RangeError(
`BitStreamWriter overflow: need ${bitCount} bits at position ${this.bitNum}, max ${this.maxBitNum}`,
);
}
value = value >>> 0;
for (let i = 0; i < bitCount; i++) {
if (value & (1 << i)) {
@ -117,6 +126,11 @@ export class BitStreamWriter {
/** Write raw bits from a Uint8Array. */
writeBitsBuffer(data: Uint8Array, bitCount: number): void {
if (this.bitNum + bitCount > this.maxBitNum) {
throw new RangeError(
`BitStreamWriter overflow: need ${bitCount} bits at position ${this.bitNum}, max ${this.maxBitNum}`,
);
}
for (let i = 0; i < bitCount; i++) {
const byteIndex = i >> 3;
const bitIndex = i & 0x7;

View file

@ -80,6 +80,11 @@ export class GameConnection extends EventEmitter<GameConnectionEvents> {
/** Warrior name to send in the ConnectRequest. */
private warriorName: string;
/** The server address as "host:port". */
get address(): string {
return `${this.host}:${this.port}`;
}
constructor(address: string, options?: { warriorName?: string }) {
super();
const [host, portStr] = address.split(":");
@ -373,7 +378,6 @@ export class GameConnection extends EventEmitter<GameConnectionEvents> {
}
}
/** Handle ConnectReject. */
/** Handle ConnectReject (type 34): U8(34) + U32(serverSeq) + U32(clientSeq) + HuffString(reason). */
private handleConnectReject(msg: Buffer): void {
if (msg.length < 9) return;
@ -413,6 +417,16 @@ export class GameConnection extends EventEmitter<GameConnectionEvents> {
/** Handle a data protocol packet (established connection). */
private handleDataPacket(msg: Buffer): void {
// Ignore data packets before the connection is fully established.
// They arrive in the window between socket creation and ConnectAccept
// and would confuse both the browser parser and our ack tracking.
if (
this._status !== "connected" &&
this._status !== "authenticating"
) {
return;
}
const data = new Uint8Array(msg.buffer, msg.byteOffset, msg.byteLength);
this.dataPacketCount++;
@ -482,11 +496,11 @@ export class GameConnection extends EventEmitter<GameConnectionEvents> {
);
}
// Measure RTT from the acked sequence's send timestamp.
const sendTime = this.sendTimestamps.get(highestAck);
// Measure RTT from the acked sequence's send timestamp (full 32-bit key).
const sendTime = this.sendTimestamps.get(result.highestAck);
if (sendTime) {
const rtt = Date.now() - sendTime;
this.sendTimestamps.delete(highestAck);
this.sendTimestamps.delete(result.highestAck);
// Exponential moving average (alpha=0.5 for responsive updates).
this.smoothedPing =
this.smoothedPing === 0 ? rtt : this.smoothedPing * 0.5 + rtt * 0.5;
@ -732,9 +746,10 @@ export class GameConnection extends EventEmitter<GameConnectionEvents> {
moves: ClientMoveData[],
moveStartIndex: number,
): void {
// Record send time for RTT measurement.
const nextSeq9 = (this.protocol.lastSendSeq + 1) & 0x1ff;
this.sendTimestamps.set(nextSeq9, Date.now());
// Record send time for RTT measurement using the full 32-bit sequence
// (not the 9-bit wire value) to avoid stale timestamps after wrap.
const nextSeqFull = (this.protocol.lastSendSeq + 1) >>> 0;
this.sendTimestamps.set(nextSeqFull, Date.now());
// Absorb any new pending events into the send queue.
for (const event of this.pendingEvents.splice(0)) {

View file

@ -152,7 +152,8 @@ async function queryServers(addresses: string[]): Promise<ServerInfo[]> {
}
});
socket.on("error", () => {
socket.on("error", (err) => {
masterLog.warn({ err }, "Socket error during Phase 1");
clearTimeout(timeout);
resolve();
});
@ -176,7 +177,8 @@ async function queryServers(addresses: string[]): Promise<ServerInfo[]> {
.map(([addr]) => addr);
if (compatibleAddrs.length > 0) {
socket.removeAllListeners("message");
// Clear all Phase 1 listeners (including stale error handler).
socket.removeAllListeners();
masterLog.debug(
{ count: compatibleAddrs.length },
@ -186,6 +188,12 @@ async function queryServers(addresses: string[]): Promise<ServerInfo[]> {
await new Promise<void>((resolve) => {
const timeout = setTimeout(() => resolve(), PHASE_TIMEOUT_MS);
socket.on("error", (err) => {
masterLog.warn({ err }, "Socket error during Phase 2");
clearTimeout(timeout);
resolve();
});
socket.on("message", (msg, rinfo) => {
const addr = resolveAddr(rinfo);
if (msg[0] === 20) {

View file

@ -1,5 +1,6 @@
import { BitStreamWriter } from "./BitStreamWriter.js";
import { packNetString, writeString } from "./HuffmanWriter.js";
import { connLog } from "./logger.js";
const DataPacket = 0;
const PingPacket = 1;
@ -68,13 +69,17 @@ export class ConnectionProtocol {
this._sendCount++;
if (this._sendCount <= 30 || this._sendCount % 50 === 0) {
const typeName =
packetType === 0 ? "data" : packetType === 1 ? "ping" : "ack";
console.log(
`[proto] SEND #${this._sendCount} seq=${this.lastSendSeq} ` +
`highestAck=${this.lastSeqRecvd} type=${typeName} ` +
`ackBytes=${ackByteCount} mask=0x${mask.toString(16).padStart(8, "0")} ` +
`(${mask.toString(2).replace(/^0+/, "") || "0"})`,
connLog.debug(
{
n: this._sendCount,
seq: this.lastSendSeq,
ack: this.lastSeqRecvd,
type: packetType === 0 ? "data" : packetType === 1 ? "ping" : "ack",
ackBytes: ackByteCount,
mask: `0x${mask.toString(16).padStart(8, "0")}`,
},
"Sent packet #%d",
this._sendCount,
);
}
@ -89,12 +94,12 @@ export class ConnectionProtocol {
connectSeqBit: number;
ackByteCount: number;
ackMask: number;
}): { accepted: boolean; dispatchData: boolean } {
}): { accepted: boolean; dispatchData: boolean; highestAck: number } {
if (header.connectSeqBit !== (this.connectSequence & 1)) {
return { accepted: false, dispatchData: false };
return { accepted: false, dispatchData: false, highestAck: 0 };
}
if (header.ackByteCount > 4 || header.packetType > 2) {
return { accepted: false, dispatchData: false };
return { accepted: false, dispatchData: false, highestAck: 0 };
}
let seqNumber =
@ -103,7 +108,7 @@ export class ConnectionProtocol {
seqNumber = (seqNumber + 0x200) >>> 0;
}
if (this.lastSeqRecvd + 0x1f < seqNumber) {
return { accepted: false, dispatchData: false };
return { accepted: false, dispatchData: false, highestAck: 0 };
}
let highestAck =
@ -112,7 +117,7 @@ export class ConnectionProtocol {
highestAck = (highestAck + 0x200) >>> 0;
}
if (this.lastSendSeq < highestAck) {
return { accepted: false, dispatchData: false };
return { accepted: false, dispatchData: false, highestAck: 0 };
}
const seqShift = (seqNumber - this.lastSeqRecvd) & 0x1f;
@ -144,7 +149,7 @@ export class ConnectionProtocol {
this.lastSeqRecvd !== seqNumber && header.packetType === DataPacket;
this.lastSeqRecvd = seqNumber;
return { accepted: true, dispatchData };
return { accepted: true, dispatchData, highestAck };
}
/** Build a ping response packet. */

View file

@ -87,7 +87,11 @@ setInterval(() => {
wsClients,
gameConns,
);
}, 10_000);
if (gameConns > 0) {
const addrs = [...activeGameConnections].map((c) => c.address);
relayLog.debug({ connections: addrs }, "Active game connections: %s", addrs.join(", "));
}
}, 60_000);
wss.on("connection", (ws) => {
relayLog.info("Browser client connected");
@ -120,13 +124,14 @@ wss.on("connection", (ws) => {
gameConnection.setMapName(cachedServer.mapName);
}
const conn = gameConnection;
gameConnection.on("status", (status, statusMessage) => {
relayLog.info(
{
status,
statusMessage,
connectSequence: gameConnection?.connectSequence,
mapName: gameConnection?.mapName,
connectSequence: conn.connectSequence,
mapName: conn.mapName,
},
"Game connection status changed",
);
@ -152,13 +157,19 @@ wss.on("connection", (ws) => {
type: "status",
status: "connecting",
message: `${statusMessage} — retrying (${retryCount}/${MAX_RETRIES})...`,
connectSequence: gameConnection?.connectSequence,
mapName: gameConnection?.mapName,
connectSequence: conn.connectSequence,
mapName: conn.mapName,
});
retryTimer = setTimeout(() => {
retryTimer = null;
if (lastJoinAddress === address && ws.readyState === WebSocket.OPEN) {
connectToServer(ws, address, lastWarriorName);
connectToServer(ws, address, lastWarriorName).catch((err) => {
relayLog.error({ err }, "Retry connection failed");
sendToClient(ws, {
type: "error",
message: `Reconnect failed: ${err instanceof Error ? err.message : err}`,
});
});
}
}, RETRY_DELAY_MS);
return;
@ -168,8 +179,8 @@ wss.on("connection", (ws) => {
type: "status",
status,
message: statusMessage,
connectSequence: gameConnection?.connectSequence,
mapName: gameConnection?.mapName,
connectSequence: conn.connectSequence,
mapName: conn.mapName,
});
});
@ -206,10 +217,10 @@ wss.on("connection", (ws) => {
gameConnection.on("close", () => {
relayLog.info("Game connection closed");
if (gameConnection) {
activeGameConnections.delete(gameConnection);
activeGameConnections.delete(conn);
if (gameConnection === conn) {
gameConnection = null;
}
gameConnection = null;
});
await gameConnection.connect();
@ -241,7 +252,6 @@ wss.on("connection", (ws) => {
}
if (gameConnection) {
gameConnection.disconnect();
gameConnection = null;
}
});
@ -336,6 +346,7 @@ wss.on("connection", (ws) => {
},
"Computing CRC from game files",
);
// Fire-and-forget: computeAndSendCRC has its own try/catch.
gameConnection.computeAndSendCRC(
message.seed,
message.field2,

View file

@ -191,8 +191,8 @@ for (const rel of playerModels) {
`${name}: rhand node="${rhNode.name}" translation=(${translation.map((v: number) => v.toFixed(3)).join(", ")}) (no mesh centroid)`,
);
}
} catch (e: any) {
console.log(`${name}: error - ${e.message}`);
} catch (e) {
console.log(`${path.basename(rel, ".glb")}: error - ${(e as Error).message}`);
}
}

View file

@ -17,7 +17,7 @@ async function run({ onlyNew }: { onlyNew: boolean }) {
if (onlyNew) {
try {
await fs.stat(glbFile);
} catch (err) {
} catch (err: any) {
if (err.code === "ENOENT") {
inputFiles.push(inFile);
}

View file

@ -17,7 +17,7 @@ async function run({ onlyNew }: { onlyNew: boolean }) {
if (onlyNew) {
try {
await fs.stat(glbFile);
} catch (err) {
} catch (err: any) {
if (err.code === "ENOENT") {
inputFiles.push(inFile);
}

View file

@ -5,7 +5,7 @@ async function run() {
const glbFile = inFile.replace(/\.dif$/, ".glb");
try {
await fs.stat(glbFile);
} catch (err) {
} catch (err: any) {
if (err.code === "ENOENT") {
console.log(inFile);
} else {

View file

@ -5,7 +5,7 @@ async function run() {
const glbFile = inFile.replace(/\.dts$/, ".glb");
try {
await fs.stat(glbFile);
} catch (err) {
} catch (err: any) {
if (err.code === "ENOENT") {
console.log(inFile);
} else {

View file

@ -23,13 +23,14 @@ async function run() {
console.error("Cannot specify --list (-l) with other options.");
return 1;
}
// @ts-expect-error JSON import resolved at runtime by tsx
const manifest = (await import("../public/manifest.json")).default;
const fileNames = Object.keys(manifest);
console.log(
fileNames
.map((f) => f.match(/^textures\/skins\/(.+)\.ifl$/))
.filter(Boolean)
.map((match) => match[1])
.map((match) => match![1])
.join("\n"),
);
return;

View file

@ -1,17 +0,0 @@
import fs from "node:fs";
import { inspect } from "node:util";
import { parseInteriorBuffer } from "@/src/interior";
const interiorFile = process.argv[2];
const interiorBuffer = fs.readFileSync(interiorFile);
const interiorArrayBuffer = interiorBuffer.buffer.slice(
interiorBuffer.byteOffset,
interiorBuffer.byteOffset + interiorBuffer.byteLength,
);
console.log(
inspect(parseInteriorBuffer(interiorArrayBuffer), {
colors: true,
depth: Infinity,
}),
);

View file

@ -28,7 +28,7 @@ async function run() {
getResourceList()
.map((f) => f.match(/^terrains\/(.+)\.ter$/))
.filter(Boolean)
.map((match) => path.basename(getLocalFilePath(match[0]), ".ter"))
.map((match) => path.basename(getLocalFilePath(match![0]), ".ter"))
.join("\n"),
);
return;

View file

@ -190,4 +190,4 @@ async function run({
}
}
run({ typeList, propertyList, valuesOnly: values.values });
run({ typeList, propertyList, valuesOnly: values.values ?? false });

View file

@ -78,8 +78,8 @@ page.on("console", async (msg) => {
console.log(`[browser ${prefix}] ${parts.join(" ")}`);
});
page.on("pageerror", (err: Error) => {
console.error(`[browser EXCEPTION] ${err.message}`);
page.on("pageerror", (err: unknown) => {
console.error(`[browser EXCEPTION] ${(err as Error).message}`);
});
// Set up settings before navigating.
@ -106,8 +106,8 @@ await page.keyboard.press("Escape");
await sleep(100);
// Hide controls from screenshots.
await page.$eval("#controls", (el: HTMLElement) => {
el.style.visibility = "hidden";
await page.$eval("#controls", (el) => {
(el as HTMLElement).style.visibility = "hidden";
});
// Upload the demo file via the hidden file input.

View file

@ -81,8 +81,8 @@ await page.keyboard.press("Escape");
await sleep(50);
// Hide controls from screenshots while keeping them selectable
await page.$eval("#controls", (el: HTMLElement) => {
el.style.visibility = "hidden";
await page.$eval("#controls", (el) => {
(el as HTMLElement).style.visibility = "hidden";
});
// Wait for mission to load

View file

@ -295,7 +295,7 @@ async function main() {
// Step 2: Download credentials (retry on network errors)
console.log("Downloading account credentials...");
let credentials: { certificate: string; encryptedKey: string };
let credentials!: { certificate: string; encryptedKey: string };
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
credentials = await downloadAccount(authAddress, username, pw);

View file

@ -3,7 +3,7 @@ import { ReactNode } from "react";
import { IoCaretForward } from "react-icons/io5";
import styles from "./Accordion.module.css";
export function AccordionGroup(props) {
export function AccordionGroup(props: RadixAccordion.AccordionMultipleProps) {
return <RadixAccordion.Root className={styles.AccordionGroup} {...props} />;
}

View file

@ -106,7 +106,7 @@ export function resolveAudioProfile(
? rawFilename
: `${rawFilename}.wav`;
const descId = profileBlock.description as number | null;
const descId = profileBlock!.description as number | null;
const descBlock = descId != null ? getDb(descId) : undefined;
const is3D = (descBlock?.is3D as boolean) ?? true;
const isLooping = (descBlock?.isLooping as boolean) ?? false;

View file

@ -38,7 +38,11 @@ export function CamerasProvider({ children }: { children: ReactNode }) {
const camera = useThree((state) => state.camera);
const [cameraIndex, setCameraIndex] = useState(-1);
const [cameraMap, setCameraMap] = useState<Record<string, CameraEntry>>({});
const [initialViewState, setInitialViewState] = useState(() => ({
const [initialViewState, setInitialViewState] = useState<{
initialized: boolean;
position: Vector3 | null;
quarternion: Quaternion | null;
}>(() => ({
initialized: false,
position: null,
quarternion: null,

View file

@ -25,6 +25,12 @@
scrollbar-color: rgba(44, 172, 181, 0.4) transparent;
}
@media (max-width: 699px) {
.ChatWindow {
font-size: 11px;
}
}
.ChatMessage {
/* Default to \c0 (GuiChatHudProfile fontColor) for untagged messages. */
color: rgb(44, 172, 181);

View file

@ -26,7 +26,7 @@ export function CopyCoordinatesButton({
}: {
cameraRef: RefObject<Camera | null>;
missionName: string;
missionType: string;
missionType?: string;
disabled?: boolean;
}) {
const { fogEnabled } = useSettings();
@ -34,7 +34,7 @@ export function CopyCoordinatesButton({
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const handleCopyLink = useCallback(async () => {
clearTimeout(timerRef.current);
if (timerRef.current) clearTimeout(timerRef.current);
const camera = cameraRef.current;
if (!camera) return;
const hash = encodeViewHash(camera);

View file

@ -131,7 +131,7 @@ function ForceFieldMesh({
* Used by the unified EntityRenderer does NOT read from TorqueObject/datablock.
*/
export function ForceFieldBare({ entity }: { entity: ForceFieldBareEntity }) {
const data = entity.forceFieldData;
const data = entity.forceFieldData!;
const scale = data.dimensions;
const textureUrls = useMemo(

View file

@ -222,7 +222,7 @@ const IflTexture = memo(function IflTexture({
const iflPath = `textures/${resourcePath}.ifl`;
const texture = useIflTexture(iflPath);
const isOrganic = shapeName && isOrganicShape(shapeName);
const isOrganic = !!(shapeName && isOrganicShape(shapeName));
const customMaterial = useMemo(
() =>
@ -316,7 +316,7 @@ const StaticTexture = memo(function StaticTexture({
return resourcePath ? textureToUrl(resourcePath) : FALLBACK_TEXTURE_URL;
}, [resourcePath, shapeName]);
const isOrganic = shapeName && isOrganicShape(shapeName);
const isOrganic = !!(shapeName && isOrganicShape(shapeName));
const isTranslucent = flagNames.has("Translucent");
const anisotropy = useAnisotropy();

View file

@ -85,7 +85,7 @@ export function parseMarkup(input: string) {
for (const token of tokens) {
switch (token.type) {
case "text":
topEl.children.push(token.value);
topEl.children!.push(token.value);
break;
case "tag":
switch (token.name) {
@ -96,16 +96,16 @@ export function parseMarkup(input: string) {
style: {},
children: [],
};
topEl.children.push(span);
topEl.children!.push(span);
topEl = span;
stack.push(topEl);
break;
}
case "spop": {
if (topEl.source !== "root") {
let lastPop = stack.pop();
let lastPop = stack.pop()!;
while (lastPop.source !== "spush") {
lastPop = stack.pop();
lastPop = stack.pop()!;
}
topEl = stack[stack.length - 1];
}
@ -131,7 +131,7 @@ export function parseMarkup(input: string) {
case "font": {
const fontSize = parseFontArgs(token.args).fontSize;
if (!isUsed(topEl)) {
topEl.style.fontSize = fontSize;
topEl.style!.fontSize = fontSize;
} else {
const fontNode: Node = {
type: "span",
@ -139,7 +139,7 @@ export function parseMarkup(input: string) {
style: { fontSize },
children: [],
};
topEl.children.push(fontNode);
topEl.children!.push(fontNode);
topEl = fontNode;
stack.push(topEl);
}
@ -147,7 +147,7 @@ export function parseMarkup(input: string) {
}
case "color":
if (!isUsed(topEl)) {
topEl.style.color = `#${token.args[0].trim()}`;
topEl.style!.color = `#${token.args[0].trim()}`;
} else {
const colorNode: Node = {
type: "span",
@ -155,7 +155,7 @@ export function parseMarkup(input: string) {
style: { color: `#${token.args[0].trim()}` },
children: [],
};
topEl.children.push(colorNode);
topEl.children!.push(colorNode);
topEl = colorNode;
stack.push(topEl);
}
@ -165,7 +165,7 @@ export function parseMarkup(input: string) {
type: "bitmap",
value: token.args[0],
};
topEl.children.push(bitmap);
topEl.children!.push(bitmap);
break;
}
case "a": {
@ -179,15 +179,15 @@ export function parseMarkup(input: string) {
style: {},
children: [],
};
topEl.children.push(link);
topEl.children!.push(link);
topEl = link;
stack.push(topEl);
break;
}
case "/a": {
let lastPop = stack.pop();
let lastPop = stack.pop()!;
while (lastPop.source !== "a") {
lastPop = stack.pop();
lastPop = stack.pop()!;
}
topEl = stack[stack.length - 1];
break;
@ -204,9 +204,9 @@ function nodeToJsx(node: Node): React.ReactNode {
return React.createElement(
"span",
{
style: Object.keys(node.style).length === 0 ? undefined : node.style,
style: Object.keys(node.style!).length === 0 ? undefined : node.style,
},
...node.children.map((child) =>
...node.children!.map((child) =>
typeof child === "string" ? child : nodeToJsx(child),
),
);
@ -215,11 +215,11 @@ function nodeToJsx(node: Node): React.ReactNode {
"a",
{
href: node.value,
style: Object.keys(node.style).length === 0 ? undefined : node.style,
style: Object.keys(node.style!).length === 0 ? undefined : node.style,
rel: "noopener noreferrer",
target: "_blank",
},
...node.children.map((child) =>
...node.children!.map((child) =>
typeof child === "string" ? child : nodeToJsx(child),
),
);

View file

@ -35,15 +35,15 @@ export const InspectorControls = memo(function InspectorControls({
invalidateRef,
}: {
missionName: string;
missionType: string;
missionType?: string;
onOpenMapInfo: () => void;
onOpenScoreScreen?: () => void;
onOpenServerBrowser?: () => void;
onChooseMap?: () => void;
onCancelChoosingMap?: () => void;
choosingMap?: boolean;
cameraRef: RefObject<Camera>;
invalidateRef: RefObject<() => void>;
cameraRef: RefObject<Camera | null>;
invalidateRef: RefObject<(() => void) | null>;
}) {
const isTouch = useTouchDevice();
const dataSource = useDataSource();

View file

@ -262,7 +262,7 @@ export const InteriorInstance = memo(function InteriorInstance({
/>
}
onError={(error) => {
log.error("Failed to load %s: %s", scene.interiorFile, error.message);
log.error("Failed to load %s: %s", scene.interiorFile, (error as Error).message);
}}
>
<DebugSuspense

View file

@ -1,11 +1,7 @@
import { BsFillLightningChargeFill } from "react-icons/bs";
import { useLiveSelector, selectPing } from "../state/liveConnectionStore";
import { useLiveSelector } from "../state/liveConnectionStore";
import styles from "./JoinServerButton.module.css";
function formatPing(ms: number): string {
return `${ms.toLocaleString()} ms`;
}
export function JoinServerButton({
isActive,
onOpenServerBrowser,
@ -14,8 +10,6 @@ export function JoinServerButton({
onOpenServerBrowser: () => void;
}) {
const gameStatus = useLiveSelector((s) => s.gameStatus);
// const serverName = useLiveSelector((s) => s.serverName);
const ping = useLiveSelector(selectPing);
const disconnectServer = useLiveSelector((s) => s.disconnectServer);
const isLive = gameStatus === "connected";
@ -45,16 +39,9 @@ export function JoinServerButton({
<>
<span className={styles.TextLabel}>Live</span>
<span className={styles.ButtonHint}>
{isConnecting
? "Connecting…"
: ping != null
? formatPing(ping)
: "Join a game"}
{isConnecting ? "Connecting…" : isLive ? "Connected" : "Join a game"}
</span>
</>
{/* {isLive && ping != null && (
<span className={styles.PingLabel}>{formatPing(ping)}</span>
)} */}
</button>
);
}

View file

@ -1,5 +1,5 @@
import { useKeyboardControls } from "@react-three/drei";
import { Controls } from "./MouseAndKeyboardHandler";
import { type ControlName } from "./MouseAndKeyboardHandler";
import { useRecording } from "./RecordingProvider";
import { useLiveSelector } from "../state/liveConnectionStore";
import styles from "./KeyboardOverlay.module.css";
@ -7,16 +7,16 @@ import styles from "./KeyboardOverlay.module.css";
export function KeyboardOverlay() {
const recording = useRecording();
const liveReady = useLiveSelector((s) => s.liveReady);
const forward = useKeyboardControls<Controls>((s) => s.forward);
const backward = useKeyboardControls<Controls>((s) => s.backward);
const left = useKeyboardControls<Controls>((s) => s.left);
const right = useKeyboardControls<Controls>((s) => s.right);
const up = useKeyboardControls<Controls>((s) => s.up);
const down = useKeyboardControls<Controls>((s) => s.down);
const lookUp = useKeyboardControls<Controls>((s) => s.lookUp);
const lookDown = useKeyboardControls<Controls>((s) => s.lookDown);
const lookLeft = useKeyboardControls<Controls>((s) => s.lookLeft);
const lookRight = useKeyboardControls<Controls>((s) => s.lookRight);
const forward = useKeyboardControls<ControlName>((s) => s.forward);
const backward = useKeyboardControls<ControlName>((s) => s.backward);
const left = useKeyboardControls<ControlName>((s) => s.left);
const right = useKeyboardControls<ControlName>((s) => s.right);
const up = useKeyboardControls<ControlName>((s) => s.up);
const down = useKeyboardControls<ControlName>((s) => s.down);
const lookUp = useKeyboardControls<ControlName>((s) => s.lookUp);
const lookDown = useKeyboardControls<ControlName>((s) => s.lookDown);
const lookLeft = useKeyboardControls<ControlName>((s) => s.lookLeft);
const lookRight = useKeyboardControls<ControlName>((s) => s.lookRight);
// Show when no recording (map browsing) or during live mode once ready.
// Hidden during demo playback and during live map transitions.

View file

@ -20,6 +20,8 @@
}
.Left {
position: relative;
z-index: 1;
overflow-y: auto;
padding: 24px 28px;
}
@ -142,6 +144,8 @@
}
.Footer {
position: relative;
z-index: 1;
display: flex;
align-items: center;
gap: 16px;
@ -167,7 +171,9 @@
@media (max-width: 719px) {
.Body {
display: block;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
grid-template-areas: "body";
overflow: auto;
}
@ -176,17 +182,24 @@
}
.Left {
width: 100%;
height: auto;
grid-area: body;
margin: 0;
overflow: auto;
padding: 16px 20px;
background: linear-gradient(
to bottom,
rgba(0, 0, 0, 0.6),
rgba(0, 0, 0, 0)
);
}
.PreviewImage {
width: auto;
position: relative;
grid-area: body;
width: 100%;
height: auto;
margin: 16px auto;
border: 0;
z-index: 0;
opacity: 0.9;
}
.CloseButton {

View file

@ -38,9 +38,11 @@
z-index: 1;
}
.CancelButton:hover {
background: rgba(255, 255, 255, 0.1);
color: #fff;
@media (hover: hover) {
.CancelButton:hover {
background: rgba(255, 255, 255, 0.1);
color: #fff;
}
}
.Sidebar {
@ -102,6 +104,10 @@
opacity: 0.6;
}
.ToggleSidebarButton:active {
opacity: 1;
}
.ToggleSidebarButton[data-orientation="top"] {
display: none;
min-height: 48px;
@ -109,8 +115,10 @@
margin: 0;
}
.ToggleSidebarButton:not(:disabled):hover {
opacity: 1;
@media (hover: hover) {
.ToggleSidebarButton:not(:disabled):hover {
opacity: 1;
}
}
.ToggleSidebarButton svg {

View file

@ -3,7 +3,6 @@ import {
useState,
useEffect,
useCallback,
startTransition,
Suspense,
useRef,
lazy,
@ -224,7 +223,7 @@ export function MapInspector() {
aria-label={sidebarOpen ? "Close sidebar" : "Open sidebar"}
title={sidebarOpen ? "Close sidebar" : "Open sidebar"}
onClick={(event) => {
startTransition(() => setSidebarOpen((open) => !open));
setSidebarOpen((open) => !open);
}}
>
{sidebarOpen ? <LuPanelTopClose /> : <LuPanelTopOpen />}
@ -236,7 +235,7 @@ export function MapInspector() {
aria-label={sidebarOpen ? "Close sidebar" : "Open sidebar"}
title={sidebarOpen ? "Close sidebar" : "Open sidebar"}
onClick={(event) => {
startTransition(() => setSidebarOpen((open) => !open));
setSidebarOpen((open) => !open);
}}
>
{sidebarOpen ? <LuPanelLeftClose /> : <LuPanelLeftOpen />}
@ -247,7 +246,7 @@ export function MapInspector() {
<Activity mode={!hasStreamData || choosingMap ? "visible" : "hidden"}>
<MissionSelect
value={choosingMap ? "" : missionName}
missionType={choosingMap ? "" : missionType}
missionType={choosingMap ? "" : missionType ?? ""}
onChange={changeMission}
autoFocus={choosingMap}
onCancel={handleCancelChoosingMap}
@ -267,32 +266,30 @@ export function MapInspector() {
</header>
{sidebarOpen ? <div className={styles.Backdrop} /> : null}
<Activity mode={sidebarOpen ? "visible" : "hidden"}>
<ViewTransition>
<div
className={styles.Sidebar}
onKeyDown={(e) => e.stopPropagation()}
onPointerDown={(e) => e.stopPropagation()}
onClick={(e) => e.stopPropagation()}
data-open={sidebarOpen}
>
<InspectorControls
missionName={missionName}
missionType={missionType}
choosingMap={choosingMap}
cameraRef={cameraRef}
invalidateRef={invalidateRef}
onOpenMapInfo={handleOpenMapInfo}
onOpenScoreScreen={
hasStreamData ? handleOpenScoreScreen : undefined
}
onOpenServerBrowser={
features.live ? handleOpenServerBrowser : undefined
}
onChooseMap={handleChooseMap}
onCancelChoosingMap={handleCancelChoosingMap}
/>
</div>
</ViewTransition>
<div
className={styles.Sidebar}
onKeyDown={(e) => e.stopPropagation()}
onPointerDown={(e) => e.stopPropagation()}
onClick={(e) => e.stopPropagation()}
data-open={sidebarOpen}
>
<InspectorControls
missionName={missionName}
missionType={missionType}
choosingMap={choosingMap}
cameraRef={cameraRef}
invalidateRef={invalidateRef}
onOpenMapInfo={handleOpenMapInfo}
onOpenScoreScreen={
hasStreamData ? handleOpenScoreScreen : undefined
}
onOpenServerBrowser={
features.live ? handleOpenServerBrowser : undefined
}
onChooseMap={handleChooseMap}
onCancelChoosingMap={handleCancelChoosingMap}
/>
</div>
</Activity>
<InputProvider>
<div className={styles.Content}>

View file

@ -179,7 +179,7 @@ export const Mission = memo(function Mission({
const missionContext = useMemo(
() => ({
metadata: parsedMission,
metadata: parsedMission!,
missionType,
}),
[parsedMission, missionType],

View file

@ -58,7 +58,7 @@ const dirGroupNames: Record<string, string> = {
interface MissionItem {
resourcePath: string;
missionName: string;
displayName: string;
displayName: string | null;
sourcePath: string;
groupName: string | null;
missionTypes: string[];
@ -244,7 +244,7 @@ export function MissionSelect({
? filteredResults.missions.length === 0
: filteredResults.groups.length === 0;
const renderItem = (mission) => {
const renderItem = (mission: MissionItem) => {
return (
<ComboboxItem
key={mission.missionName}

View file

@ -11,27 +11,29 @@ import { useCameras } from "./CamerasProvider";
import { useInputContext } from "./InputContext";
import { useTouchDevice } from "./useTouchDevice";
export enum Controls {
forward = "forward",
backward = "backward",
left = "left",
right = "right",
up = "up",
down = "down",
lookUp = "lookUp",
lookDown = "lookDown",
lookLeft = "lookLeft",
lookRight = "lookRight",
camera1 = "camera1",
camera2 = "camera2",
camera3 = "camera3",
camera4 = "camera4",
camera5 = "camera5",
camera6 = "camera6",
camera7 = "camera7",
camera8 = "camera8",
camera9 = "camera9",
}
export const Controls = {
forward: "forward",
backward: "backward",
left: "left",
right: "right",
up: "up",
down: "down",
lookUp: "lookUp",
lookDown: "lookDown",
lookLeft: "lookLeft",
lookRight: "lookRight",
camera1: "camera1",
camera2: "camera2",
camera3: "camera3",
camera4: "camera4",
camera5: "camera5",
camera6: "camera6",
camera7: "camera7",
camera8: "camera8",
camera9: "camera9",
} as const;
export type ControlName = (typeof Controls)[keyof typeof Controls];
export const KEYBOARD_CONTROLS = [
{ name: Controls.forward, keys: ["KeyW"] },
@ -103,7 +105,7 @@ export function MouseAndKeyboardHandler() {
invertDrag,
} = useControls();
const { onInput, mode } = useInputContext();
const [subscribe, getKeys] = useKeyboardControls<Controls>();
const [subscribe, getKeys] = useKeyboardControls<ControlName>();
const camera = useThree((state) => state.camera);
const gl = useThree((state) => state.gl);
const { nextCamera, setCameraIndex, cameraCount } = useCameras();

View file

@ -8,17 +8,10 @@
pointer-events: none;
}
.TopRight {
.Compass {
position: absolute;
top: 10px;
right: 10px;
display: flex;
align-items: flex-start;
gap: 6px;
}
.Compass {
position: relative;
width: 64px;
height: 64px;
flex-shrink: 0;
@ -56,14 +49,19 @@
}
.Bars {
position: absolute;
top: 20px;
right: 82px;
width: 120px;
max-width: 20%;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 3px;
padding-top: 10px;
}
.BarTrack {
width: 120px;
width: 100%;
height: 10px;
background: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.15);
@ -94,6 +92,16 @@
gap: 2px;
}
.WeaponHUD .PackInvItem[data-active="false"] {
opacity: 0.6;
}
@media (max-height: 699px) {
.WeaponHUD .PackInvItem[data-active="false"] {
display: none;
}
}
.WeaponSeparator {
height: 6px;
}
@ -109,6 +117,12 @@
border-collapse: collapse;
}
@media (max-width: 499px), (pointer: coarse) {
.TeamScores {
display: none;
}
}
.ObserverCount {
position: absolute;
bottom: calc(100%);
@ -171,6 +185,12 @@
gap: 4px;
}
@media (max-width: 499px), (pointer: coarse) {
.PackInventoryHUD {
display: none;
}
}
.PackInvItem {
display: flex;
flex-direction: column;
@ -182,13 +202,9 @@
gap: 1px;
}
.PackInvItemActive {
border-color: rgba(128, 255, 200, 0.5);
box-shadow: 0 0 6px rgba(128, 255, 200, 0.3);
}
.PackInvItemDim {
opacity: 0.5;
.PackInvItem[data-active="true"] {
border-color: rgba(128, 255, 200, 0.6);
box-shadow: 0 0 8px rgba(128, 255, 200, 0.4);
}
.PackInvIcon {

View file

@ -3,7 +3,6 @@ import { textureToUrl } from "../loaders";
import type { StreamEntity, TeamScore, WeaponsHudSlot } from "../stream/types";
import styles from "./PlayerHUD.module.css";
import { ChatWindow } from "./ChatWindow";
import { LuUsers } from "react-icons/lu";
const COMPASS_URL = textureToUrl("gui/hud_new_compass");
const NSEW_URL = textureToUrl("gui/hud_new_NSEW");
@ -160,9 +159,7 @@ function WeaponSlotIcon({
if (!info) return null;
const isInfinite = slot.ammo < 0;
return (
<div
className={`${styles.PackInvItem} ${isSelected ? styles.PackInvItemActive : styles.PackInvItemDim}`}
>
<div className={styles.PackInvItem} data-active={isSelected}>
<img
src={WEAPON_HUD_ICON_URLS.get(slot.index)!}
alt={info.label}
@ -259,7 +256,9 @@ function TeamScores() {
)}
{sorted.map((team: TeamScore) => {
const isFriendly =
playerSensorGroup > 0 && team.teamId === playerSensorGroup;
playerSensorGroup != null &&
playerSensorGroup > 0 &&
team.teamId === playerSensorGroup;
const name =
team.name ||
(DEFAULT_TEAM_NAMES[team.teamId] ?? `Team ${team.teamId}`);
@ -376,7 +375,8 @@ function PackAndInventoryHUD() {
<div className={styles.PackInventoryHUD}>
{packIconUrl && (
<div
className={`${styles.PackInvItem} ${backpackHud!.active ? styles.PackInvItemActive : ""}`}
className={styles.PackInvItem}
data-active={backpackHud!.active ?? false}
>
<img src={packIconUrl} alt="" className={styles.PackInvIcon} />
<span className={styles.PackInvCount}>
@ -409,18 +409,17 @@ export function PlayerHUD() {
const hasControlPlayer = useEngineSelector(
(state) => !!state.playback.streamSnapshot?.controlPlayerGhostId,
);
return (
<div className={styles.PlayerHUD}>
<ChatWindow />
<div className={styles.TopRight}>
{hasControlPlayer && (
<div className={styles.Bars}>
<HealthBar />
<EnergyBar />
</div>
)}
<Compass />
</div>
{hasControlPlayer && (
<div className={styles.Bars}>
<HealthBar />
<EnergyBar />
</div>
)}
<Compass />
{hasControlPlayer && (
<>
<WeaponHUD />

View file

@ -87,11 +87,16 @@ interface ActionAnimEntry {
*
* The engine builds its action list as:
* 1. Table actions (0-7): found by searching for aliased names (root, run, etc.)
* 2. Non-table actions (8+): remaining sequences in TSShapeConstructor order.
* 2. Non-table actions (8+): ALL remaining shape sequences in order.
*
* The shape's sequence array contains DTS-embedded sequences (e.g. JetFlare,
* Damage) BEFORE the TSShapeConstructor-loaded ones. These occupy non-table
* action slots and shift all TSShapeConstructor non-table indices up.
*/
function buildActionAnimMap(
sequences: string[],
shapePrefix: string,
embeddedNonTableCount: number = 0,
): Map<number, ActionAnimEntry> {
const result = new Map<number, ActionAnimEntry>();
@ -124,8 +129,9 @@ function buildActionAnimMap(
}
}
// Non-table actions: remaining entries in TSShapeConstructor order.
let actionIdx = NUM_TABLE_ACTION_ANIMS;
// Non-table actions: remaining entries in TSShapeConstructor order, offset
// by embedded non-table sequences that precede them in the shape.
let actionIdx = NUM_TABLE_ACTION_ANIMS + embeddedNonTableCount;
for (let pi = 0; pi < parsed.length; pi++) {
if (!tableEntryIndices.has(pi)) {
result.set(actionIdx, parsed[pi]);
@ -136,6 +142,52 @@ function buildActionAnimMap(
return result;
}
const TABLE_ACTION_NAME_SET = new Set(TABLE_ACTION_NAMES);
/**
* Count DTS-embedded sequences that occupy non-table action slots. The engine's
* shape sequence array starts with embedded sequences (e.g. JetFlare, Damage)
* before TSShapeConstructor sequences. We detect them by comparing the GLB's
* `dts_sequence_names` metadata with TSShapeConstructor-derived clip names.
*/
function countEmbeddedNonTableSequences(
scene: Group,
tscSequences: string[],
shapePrefix: string,
): number {
const raw = scene.userData?.dts_sequence_names;
if (typeof raw !== "string") return 0;
let dtsNames: string[];
try {
dtsNames = JSON.parse(raw);
} catch {
return 0;
}
if (!Array.isArray(dtsNames) || dtsNames.length === 0) return 0;
// Build set of clip names derived from TSShapeConstructor DSQ entries.
const tscClipNames = new Set<string>();
for (const entry of tscSequences) {
const spaceIdx = entry.indexOf(" ");
if (spaceIdx === -1) continue;
const dsqFile = entry.slice(0, spaceIdx).toLowerCase();
if (!dsqFile.startsWith(shapePrefix) || !dsqFile.endsWith(".dsq")) continue;
const clipName = dsqFile.slice(shapePrefix.length, -4);
if (clipName) tscClipNames.add(clipName);
}
// Embedded sequences come first in the DTS. Count leading entries that don't
// match any TSShapeConstructor clip name, excluding any that are table actions.
let count = 0;
for (const name of dtsNames) {
if (tscClipNames.has(name.toLowerCase())) break;
if (!TABLE_ACTION_NAME_SET.has(name.toLowerCase())) {
count++;
}
}
return count;
}
/** Stop, disconnect, and remove a looping PositionalAudio from its parent. */
function stopLoopingSound(
soundRef: React.MutableRefObject<PositionalAudio | null>,
@ -245,8 +297,47 @@ export function PlayerModel({ entity }: { entity: PlayerEntity }) {
if (!sequences) return new Map<number, ActionAnimEntry>();
// Derive prefix: "heavy_male.dts" -> "heavy_male_"
const stem = sn.replace(/\.dts$/i, "");
return buildActionAnimMap(sequences, stem + "_");
}, [engineStore, shapeName]);
const prefix = stem + "_";
const embeddedNonTable = countEmbeddedNonTableSequences(
gltf.scene,
sequences,
prefix,
);
return buildActionAnimMap(sequences, prefix, embeddedNonTable);
}, [engineStore, shapeName, gltf.scene]);
// Build a map of animation alias → cyclic flag from DTS metadata.
// Non-cyclic sequences (fall, jet, jump, land) play once and clamp.
const seqCyclicByAlias = useMemo(() => {
const map = new Map<string, boolean>();
const rawNames = gltf.scene.userData?.dts_sequence_names;
const rawCyclic = gltf.scene.userData?.dts_sequence_cyclic;
if (typeof rawNames === "string" && typeof rawCyclic === "string") {
try {
const names: string[] = JSON.parse(rawNames);
const cyclic: boolean[] = JSON.parse(rawCyclic);
// Map clip names → cyclic.
const clipCyclic = new Map<string, boolean>();
for (let i = 0; i < names.length; i++) {
clipCyclic.set(names[i].toLowerCase(), cyclic[i] ?? true);
}
// Map aliases → cyclic via the alias→clip mapping.
if (shapeAliases) {
for (const [alias, clipName] of shapeAliases) {
const c = clipCyclic.get(clipName);
if (c != null) map.set(alias, c);
}
}
// Also include raw clip names so lookups by either name work.
for (const [name, c] of clipCyclic) {
if (!map.has(name)) map.set(name, c);
}
} catch {
/* ignore */
}
}
return map;
}, [gltf.scene, shapeAliases]);
useEffect(() => {
const actions = getAliasedActions(gltf.animations, mixer, shapeAliases);
@ -505,6 +596,17 @@ export function PlayerModel({ entity }: { entity: PlayerEntity }) {
const nextAction = actions.get(anim.animation.toLowerCase());
if (nextAction) {
// Set loop mode from the DTS cyclic flag. Non-cyclic sequences
// (fall, jet, jump, land) play once and hold their end pose.
const isCyclic = seqCyclicByAlias.get(anim.animation) ?? true;
if (isCyclic) {
nextAction.setLoop(LoopRepeat, Infinity);
nextAction.clampWhenFinished = false;
} else {
nextAction.setLoop(LoopOnce, 1);
nextAction.clampWhenFinished = true;
}
if (isPlaying && prevAction && prevAction !== nextAction) {
prevAction.fadeOut(ANIM_TRANSITION_TIME);
nextAction.reset().fadeIn(ANIM_TRANSITION_TIME).play();

View file

@ -23,7 +23,7 @@ const IFF_ENEMY_URL = textureToUrl("gui/hud_enemytriangle");
const _tmpVec = new Vector3();
const EMPTY_KEYFRAMES = [];
const EMPTY_KEYFRAMES: never[] = [];
/**
* Floating nameplate above a player model showing the entity name and a health

View file

@ -51,6 +51,7 @@
.TableWrapper {
overflow-y: auto;
overflow-x: hidden;
min-height: 0;
}
@ -58,6 +59,7 @@
width: 100%;
min-height: 0;
border-collapse: collapse;
table-layout: fixed;
font-size: 13px;
user-select: none;
}
@ -77,16 +79,65 @@
letter-spacing: 0.04em;
text-transform: uppercase;
color: rgba(125, 255, 255, 0.6);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.Table th:hover {
color: #7dffff;
}
.Table th:nth-child(2),
.Table td:nth-child(2),
.Table th:nth-child(3),
.Table td:nth-child(3) {
.Table th[data-column="server"] {
width: 26%;
}
.Table th[data-column="players"] {
width: 11%;
}
.Table th[data-column="ping"] {
width: 8%;
}
.Table th[data-column="map"] {
width: 22%;
}
.Table th[data-column="gameType"] {
width: 19%;
}
.Table th[data-column="mod"] {
width: 14%;
}
@media (max-width: 799px) {
.Table th[data-column="ping"],
.Table td[data-column="ping"] {
display: none;
}
}
@media (max-width: 699px) {
.CompactHidden {
display: none;
}
}
@media (max-width: 599px) {
.Table th[data-column="mod"],
.Table td[data-column="mod"] {
display: none;
}
}
@media (max-width: 499px) {
.Table th[data-column="gameType"],
.Table td[data-column="gameType"] {
display: none;
}
}
.Table th[data-column="players"],
.Table td[data-column="players"],
.Table th[data-column="ping"],
.Table td[data-column="ping"] {
text-align: right;
}
@ -98,7 +149,6 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 340px;
font-weight: 500;
}
@ -199,10 +249,6 @@
display: none;
}
.Table td {
max-width: 200px;
}
.CloseButton {
margin-left: auto;
}

View file

@ -102,12 +102,30 @@ export function ServerBrowser({ onClose }: { onClose: () => void }) {
<table className={styles.Table}>
<thead>
<tr>
<th onClick={() => handleSort("name")}>Server Name</th>
<th onClick={() => handleSort("playerCount")}>Players</th>
<th onClick={() => handleSort("ping")}>Ping</th>
<th onClick={() => handleSort("mapName")}>Map</th>
<th onClick={() => handleSort("gameType")}>Type</th>
<th onClick={() => handleSort("mod")}>Mod</th>
<th data-column="server" onClick={() => handleSort("name")}>
Server Name
</th>
<th
data-column="players"
onClick={() => handleSort("playerCount")}
>
Players
</th>
<th data-column="ping" onClick={() => handleSort("ping")}>
Ping
</th>
<th data-column="map" onClick={() => handleSort("mapName")}>
Map
</th>
<th
data-column="gameType"
onClick={() => handleSort("gameType")}
>
Type
</th>
<th data-column="mod" onClick={() => handleSort("mod")}>
Mod
</th>
</tr>
</thead>
<tbody>
@ -116,13 +134,12 @@ export function ServerBrowser({ onClose }: { onClose: () => void }) {
key={server.address}
onClick={() => {
setSelectedAddress(server.address);
const form = document.forms["serverList"];
const inputs: RadioNodeList =
form.elements["serverAddress"];
const form = document.forms.namedItem("serverList")!;
const inputs = form.elements.namedItem("serverAddress") as RadioNodeList;
const input = Array.from(inputs).find(
(input) => input.value === server.address,
);
input.focus();
input!.focus();
}}
onDoubleClick={() => {
setSelectedAddress(server.address);
@ -130,7 +147,7 @@ export function ServerBrowser({ onClose }: { onClose: () => void }) {
onClose();
}}
>
<td>
<td data-column="server">
<input
type="radio"
className={styles.HiddenRadio}
@ -152,17 +169,21 @@ export function ServerBrowser({ onClose }: { onClose: () => void }) {
? styles.EmptyServer
: undefined
}
data-column="players"
>
{server.playerCount}&thinsp;/&thinsp;{server.maxPlayers}
{server.playerCount}
<span className={styles.CompactHidden}>
&thinsp;/&thinsp;{server.maxPlayers}
</span>
</td>
<td>
<td data-column="ping">
{browserToRelayPing != null
? (server.ping + browserToRelayPing).toLocaleString()
: "\u2014"}
</td>
<td>{server.mapName}</td>
<td>{server.gameType}</td>
<td>{server.mod}</td>
<td data-column="map">{server.mapName}</td>
<td data-column="gameType">{server.gameType}</td>
<td data-column="mod">{server.mod}</td>
</tr>
))}
{sorted.length === 0 && !serversLoading && (

View file

@ -1,6 +1,8 @@
import {
createContext,
type Dispatch,
ReactNode,
type SetStateAction,
useCallback,
useContext,
useEffect,
@ -18,7 +20,7 @@ export const DEFAULT_MOUSE_SENSITIVITY = 32 / 16000; // 0.002
export const MIN_MOUSE_SENSITIVITY = 1 / 16000;
export const MAX_MOUSE_SENSITIVITY = 256 / 16000;
type StateSetter<T> = ReturnType<typeof useState<T>>[1];
type StateSetter<T> = Dispatch<SetStateAction<T>>;
export type TouchMode = "dualStick" | "moveLookStick";
@ -230,7 +232,7 @@ export function SettingsProvider({ children }: { children: ReactNode }) {
let savedSettings: PersistedSettings = {};
try {
savedSettings = JSON.parse(localStorage.getItem("settings")) || {};
savedSettings = JSON.parse(localStorage.getItem("settings") ?? "{}") || {};
} catch (err) {
// Ignore.
}

View file

@ -49,8 +49,8 @@ function getArmThread(weaponShape: string | undefined): string {
export function WeaponModel({ entity }: { entity: ShapeEntity }) {
const shapeName = entity.weaponShape;
const playerShapeName = entity.shapeName;
const playerGltf = useStaticShape(playerShapeName);
const weaponGltf = useStaticShape(shapeName);
const playerGltf = useStaticShape(playerShapeName!);
const weaponGltf = useStaticShape(shapeName!);
const mountTransform = useMemo(() => {
// Get Mount0 from the player's posed skeleton with arm animation applied.
@ -115,7 +115,7 @@ export function WeaponModel({ entity }: { entity: ShapeEntity }) {
);
return (
<ShapeInfoProvider object={torqueObject} shapeName={shapeName} type="Item">
<ShapeInfoProvider object={torqueObject} shapeName={shapeName!} type="Item">
<group
position={mountTransform.position}
quaternion={mountTransform.quaternion}
@ -212,7 +212,7 @@ function interpolateSize(
* with custom rendering for faceViewer, vis/IFL animation, and size keyframes.
*/
export function ExplosionShape({ entity }: { entity: ExplosionEntity }) {
const playback = streamPlaybackStore.getState().playback;
const playback = streamPlaybackStore.getState().playback!;
const gltf = useStaticShape(entity.shapeName!);
const anisotropy = useAnisotropy();
const groupRef = useRef<Group>(null);

View file

@ -143,13 +143,13 @@ function SkyBoxTexture({
<bufferGeometry>
<bufferAttribute
attach="attributes-position"
array={new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0])}
args={[new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0]), 3]}
count={3}
itemSize={3}
/>
<bufferAttribute
attach="attributes-uv"
array={new Float32Array([0, 0, 2, 0, 0, 2])}
args={[new Float32Array([0, 0, 2, 0, 0, 2]), 2]}
count={3}
itemSize={2}
/>
@ -299,12 +299,12 @@ export function SkyBox({
() =>
detailMapList
? [
textureToUrl(detailMapList[1]), // +x
textureToUrl(detailMapList[3]), // -x
textureToUrl(detailMapList[4]), // +y
textureToUrl(detailMapList[5]), // -y
textureToUrl(detailMapList[0]), // +z
textureToUrl(detailMapList[2]), // -z
textureToUrl(detailMapList[1]!), // +x
textureToUrl(detailMapList[3]!), // -x
textureToUrl(detailMapList[4]!), // +y
textureToUrl(detailMapList[5]!), // -y
textureToUrl(detailMapList[0]!), // +z
textureToUrl(detailMapList[2]!), // -z
]
: null,
[detailMapList],
@ -388,13 +388,13 @@ function SolidColorSky({
<bufferGeometry>
<bufferAttribute
attach="attributes-position"
array={new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0])}
args={[new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0]), 3]}
count={3}
itemSize={3}
/>
<bufferAttribute
attach="attributes-uv"
array={new Float32Array([0, 0, 2, 0, 0, 2])}
args={[new Float32Array([0, 0, 2, 0, 0, 2]), 2]}
count={3}
itemSize={2}
/>

View file

@ -21,6 +21,7 @@ import type {
StreamRecording,
StreamEntity,
StreamSnapshot,
StreamingPlayback,
} from "../stream/types";
import type { GameEntity } from "../state/gameEntityTypes";
import { isSceneEntity } from "../state/gameEntityTypes";
@ -108,7 +109,7 @@ export function StreamingController({
const prevTickSnapshotRef = useRef<StreamSnapshot | null>(null);
const currentTickSnapshotRef = useRef<StreamSnapshot | null>(null);
const eyeOffsetRef = useRef(new Vector3(0, DEFAULT_EYE_HEIGHT, 0));
const streamRef = useRef(recording.streamingPlayback ?? null);
const streamRef = useRef<StreamingPlayback | null>(recording.streamingPlayback ?? null);
const publishedSnapshotRef = useRef<StreamSnapshot | null>(null);
const entityMapRef = useRef<Map<string, GameEntity>>(new Map());
const lastSyncedSnapshotRef = useRef<StreamSnapshot | null>(null);
@ -160,17 +161,17 @@ export function StreamingController({
// Mutate render fields in-place on the existing entity object.
// Components read these imperatively in useFrame — no React
// re-render needed. This avoids store churn that starves Suspense.
mutateRenderFields(renderEntity, entity);
mutateRenderFields(renderEntity!, entity);
}
nextMap.set(entity.id, renderEntity);
nextMap.set(entity.id, renderEntity!);
// Keyframe update (mutable -- used for fallback position for
// retained explosion entities and per-frame reads in useFrame).
// Scene entities and None don't have keyframes.
if (isSceneEntity(renderEntity) || renderEntity.renderType === "None")
if (isSceneEntity(renderEntity!) || renderEntity!.renderType === "None")
continue;
const keyframes = renderEntity.keyframes!;
const keyframes = renderEntity!.keyframes!;
if (keyframes.length === 0) {
keyframes.push({
time: snapshot.timeSec,

View file

@ -2,6 +2,8 @@
flex: 1 1 auto;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 12px;
}
.MissionInfo {
@ -37,8 +39,8 @@
font-size: 12px;
line-height: calc(14 / 12);
text-align: right;
padding: 8px 12px;
margin: 0 0 0 auto;
padding: 8px 0;
margin-left: 4px;
}
.Attribution,
@ -87,3 +89,47 @@
margin-left: 0;
}
}
.Pulsing {
animation: blink 1.2s ease-out infinite;
}
.ConnectionPing {
display: inline-flex;
align-items: center;
font-size: 12px;
gap: 6px;
background: rgba(255, 255, 255, 0.1);
padding: 5px 8px;
border-radius: 12px;
}
.PingDot {
composes: Pulsing;
display: inline-block;
width: 6px;
height: 6px;
border-radius: 3px;
background: currentColor;
}
.ConnectionPing[data-quality="good"] .PingDot {
color: rgb(116, 255, 69);
}
.ConnectionPing[data-quality="fine"] .PingDot {
color: rgb(255, 158, 47);
}
.ConnectionPing[data-quality="poor"] .PingDot {
color: rgb(232, 63, 37);
}
@keyframes blink {
0% {
opacity: 1;
}
100% {
opacity: 0.25;
}
}

View file

@ -11,11 +11,13 @@ import {
import { engineStore } from "../state/engineStore";
import {
liveConnectionStore,
selectPing,
useLiveSelector,
} from "../state/liveConnectionStore";
import { useRecording } from "./RecordingProvider";
import { LuCircleArrowOutUpLeft } from "react-icons/lu";
import { BiSolidEject } from "react-icons/bi";
import { formatPing } from "../stringUtils";
import styles from "./StreamingMissionInfo.module.css";
export function StreamingMissionInfo() {
@ -34,6 +36,7 @@ export function StreamingMissionInfo() {
const isLiveConnected = useLiveSelector(
(s) => s.gameStatus === "connected" || s.gameStatus === "authenticating",
);
const ping = useLiveSelector(selectPing);
const handleEject = useCallback(() => {
engineStore.getState().setRecording(null);
@ -65,6 +68,14 @@ export function StreamingMissionInfo() {
</>
) : null}
</div>
{isLiveConnected && ping != null ? (
<span
className={styles.ConnectionPing}
data-quality={ping < 150 ? "good" : ping < 300 ? "fine" : "poor"}
>
<span className={styles.PingDot} /> {formatPing(ping)}
</span>
) : null}
<div className={styles.Metadata}>
{isLive ? (
isLiveConnected ? (
@ -82,7 +93,7 @@ export function StreamingMissionInfo() {
Recorded by <span className={styles.PlayerName}>{playerName}</span>{" "}
on{" "}
<span className={styles.RecordingDate}>
{datePart.replace(/-/g, " ")}
{datePart!.replace(/-/g, " ")}
</span>{" "}
at <span className={styles.RecordingDate}>{timePart}</span>
</div>

View file

@ -657,7 +657,7 @@ export const TerrainBlock = memo(function TerrainBlock({
visibilityMask={primaryVisibilityMask}
alphaTextures={sharedAlphaTextures}
detailTextureName={detailTexture}
lightmap={terrainLightmap}
lightmap={terrainLightmap ?? undefined}
/>
{/* Pooled tiles single InstancedMesh, matrices updated in useFrame.
All pooled tiles share the same geometry, material, and visibility mask.
@ -675,7 +675,7 @@ export const TerrainBlock = memo(function TerrainBlock({
textureNames={terrain.textureNames}
alphaTextures={sharedAlphaTextures}
detailTextureName={detailTexture}
lightmap={terrainLightmap}
lightmap={terrainLightmap ?? undefined}
/>
</instancedMesh>
</>

View file

@ -1,4 +1,4 @@
import { createContext, ReactNode, useContext, useMemo, useState } from "react";
import { createContext, type Dispatch, ReactNode, type SetStateAction, useContext, useMemo, useState } from "react";
/**
* Handle for querying terrain data.
@ -34,7 +34,7 @@ export interface TerrainHandle {
};
}
type StateSetter<T> = ReturnType<typeof useState<T>>[1];
type StateSetter<T> = Dispatch<SetStateAction<T>>;
interface TerrainContextValue {
terrain: TerrainHandle | null;

View file

@ -81,7 +81,7 @@ const BlendedTerrainTextures = memo(function BlendedTerrainTextures({
);
const onBeforeCompile = useCallback(
(shader) => {
(shader: any) => {
updateTerrainTextureShader({
shader,
baseTextures,
@ -105,6 +105,19 @@ const BlendedTerrainTextures = memo(function BlendedTerrainTextures({
],
);
// Build a unique program cache key so Three.js recompiles the shader when
// textures change between maps. Without this, onBeforeCompile may not be
// called because the program cache hash (from toString()) is identical.
const programCacheKey = useMemo(() => {
const parts = [
textureNames.join(","),
detailTextureUrl ?? "none",
lightmap ? lightmap.id : "nolm",
baseTextures.map((t: any) => t.id).join(","),
];
return parts.join("|");
}, [textureNames, detailTextureUrl, lightmap, baseTextures]);
// Ref for forcing shader recompilation
const materialRef = useRef<MeshLambertMaterial>(null);
@ -121,6 +134,16 @@ const BlendedTerrainTextures = memo(function BlendedTerrainTextures({
}
}, [debugMode]);
// Set customProgramCacheKey so Three.js distinguishes terrain shaders
// across different maps even when the shader structure is identical.
useEffect(() => {
const mat = materialRef.current;
if (mat) {
mat.customProgramCacheKey = () => programCacheKey;
mat.needsUpdate = true;
}
}, [programCacheKey]);
// Key for shader structure changes (detail texture, lightmap)
const materialKey = `${detailTextureUrl ? "detail" : "nodetail"}-${lightmap ? "lightmap" : "nolightmap"}`;

Some files were not shown because too many files have changed in this diff Show more