mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-07-11 14:34:51 +00:00
fix typecheck script, animations
This commit is contained in:
parent
642fce9c06
commit
ceb9fea9f4
120 changed files with 1308 additions and 911 deletions
|
|
@ -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};
|
||||
|
|
@ -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};
|
||||
|
|
@ -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};
|
||||
|
|
@ -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};
|
||||
|
|
@ -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};
|
||||
|
|
@ -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};
|
||||
|
|
@ -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};
|
||||
|
|
@ -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
526
docs/assets/GameView-Em-JPPZa.js
Normal file
526
docs/assets/GameView-Em-JPPZa.js
Normal file
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
|
|
@ -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};
|
||||
|
|
@ -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}}
|
||||
|
|
@ -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};
|
||||
1
docs/assets/MapInfoDialog-DEkKdREx.css
Normal file
1
docs/assets/MapInfoDialog-DEkKdREx.css
Normal 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
1
docs/assets/PlayerHUD-CGI92OIs.css
Normal file
1
docs/assets/PlayerHUD-CGI92OIs.css
Normal 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
|
|
@ -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}
|
||||
2
docs/assets/PlayerHUD-dFkGNy8m.js
Normal file
2
docs/assets/PlayerHUD-dFkGNy8m.js
Normal file
File diff suppressed because one or more lines are too long
1
docs/assets/PlayerModel-CHa5T5CY.js
Normal file
1
docs/assets/PlayerModel-CHa5T5CY.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -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
1
docs/assets/ServerBrowser-B86MUE1E.js
Normal file
1
docs/assets/ServerBrowser-B86MUE1E.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -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
1
docs/assets/ServerBrowser-CcgmsLn7.css
Normal file
1
docs/assets/ServerBrowser-CcgmsLn7.css
Normal file
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
|
|
@ -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};
|
||||
|
|
@ -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};
|
||||
|
|
@ -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
12
docs/assets/index-BngaOpHI.js
Normal file
12
docs/assets/index-BngaOpHI.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
docs/assets/loaders-Ba8dC3nL.js
Normal file
1
docs/assets/loaders-Ba8dC3nL.js
Normal 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};
|
||||
|
|
@ -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
|
|
@ -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};
|
||||
1
docs/assets/useQuery-Cql8MWsA.js
Normal file
1
docs/assets/useQuery-Cql8MWsA.js
Normal 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};
|
||||
|
|
@ -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
8
env.d.ts
vendored
Normal 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;
|
||||
}
|
||||
|
|
@ -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
1
generated/TorqueScript.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
export function parse(input: string, options?: Record<string, unknown>): any;
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}),
|
||||
);
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -190,4 +190,4 @@ async function run({
|
|||
}
|
||||
}
|
||||
|
||||
run({ typeList, propertyList, valuesOnly: values.values });
|
||||
run({ typeList, propertyList, valuesOnly: values.values ?? false });
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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} />;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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}>
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ export const Mission = memo(function Mission({
|
|||
|
||||
const missionContext = useMemo(
|
||||
() => ({
|
||||
metadata: parsedMission,
|
||||
metadata: parsedMission!,
|
||||
missionType,
|
||||
}),
|
||||
[parsedMission, missionType],
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 />
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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} / {server.maxPlayers}
|
||||
{server.playerCount}
|
||||
<span className={styles.CompactHidden}>
|
||||
 / {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 && (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue