@combos-fun/plugin-development-tool 0.0.52 → 0.0.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-skill.md +3 -1
- package/dist/plugin-development-tool.cjs.js +143 -19
- package/dist/plugin-development-tool.cjs.js.map +1 -1
- package/dist/plugin-development-tool.cjs.prod.js +1 -1
- package/dist/plugin-development-tool.d.ts +7 -1
- package/dist/plugin-development-tool.esm.js +143 -19
- package/dist/plugin-development-tool.esm.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("tslib"),t=require("@combos-fun/engine"),n=require("@combos-fun/inspector-decorator");const o="combos-development-tool:set-pick-mode",r="combos-development-tool:pick-mode-success",i="combos-development-tool:refresh",s="combos-development-tool:gameobject-selected",a="combos-development-tool:clear-selection",c="combos-development-tool:gameobject-deselected",l="combos-development-tool:apply-property",d="combos-development-tool:set-marker-overlay",h="combos-development-tool:marker-overlay-success";class u extends t.Component{constructor(){super(...arguments),this.payload={}}static{this.componentName="CombosDevelopmentToolTarget"}init(e){this.payload=e?.payload?{...e.payload}:{}}}function p(e,t=1){return`rgba(${e>>16&255}, ${e>>8&255}, ${255&e}, ${t})`}class m{constructor(e){this.ctx=e}clear(){this.ctx.beginPath()}roundRect(e,t,n,o,r=0){const i=this.ctx;if("function"==typeof i.roundRect)return void i.roundRect(e,t,n,o,r);const s=Math.max(0,Math.min(r,Math.min(n,o)/2));i.moveTo(e+s,t),i.lineTo(e+n-s,t),i.quadraticCurveTo(e+n,t,e+n,t+s),i.lineTo(e+n,t+o-s),i.quadraticCurveTo(e+n,t+o,e+n-s,t+o),i.lineTo(e+s,t+o),i.quadraticCurveTo(e,t+o,e,t+o-s),i.lineTo(e,t+s),i.quadraticCurveTo(e,t,e+s,t),i.closePath()}rect(e,t,n,o){this.ctx.rect(e,t,n,o)}circle(e,t,n){this.ctx.moveTo(e+n,t),this.ctx.arc(e,t,n,0,2*Math.PI)}poly(e,t=!0){if(!(e.length<4)){this.ctx.moveTo(e[0],e[1]);for(let t=2;t<e.length;t+=2)this.ctx.lineTo(e[t],e[t+1]);t&&this.ctx.closePath()}}fill(e){this.ctx.fillStyle=p(e.color,e.alpha??1),this.ctx.fill(),this.ctx.beginPath()}stroke(e){this.ctx.strokeStyle=p(e.color,e.alpha??1),this.ctx.lineWidth=e.width,this.ctx.stroke(),this.ctx.beginPath()}}const f=[{componentName:"Sound",badgeColor:9133302,glyph:"speaker"}],y=28;function g(e,t=f){for(const n of t)if(e.getComponent(n.componentName))return n;return null}const b=16777215;function v(e,t,n=28){if(function(e,t,n){e.clear(),e.roundRect(0,0,n,n,.22*n),e.fill({color:t.badgeColor,alpha:.92}),e.roundRect(0,0,n,n,.22*n),e.stroke({width:Math.max(1,.05*n),color:16777215,alpha:.6})}(e,t,n),"speaker"===t.glyph)!function(e,t){e.poly([.28*t,.4*t,.42*t,.4*t,.55*t,.26*t,.55*t,.74*t,.42*t,.6*t,.28*t,.6*t]),e.fill({color:b,alpha:.96}),e.rect(.62*t,.44*t,.045*t,.12*t),e.fill({color:b,alpha:.96}),e.rect(.71*t,.39*t,.045*t,.22*t),e.fill({color:b,alpha:.96})}(e,n);else!function(e,t){e.circle(.5*t,.5*t,.18*t),e.fill({color:b,alpha:.96})}(e,n)}const w=["knoffice.tech","converge.ai"];function O(e,t){if(t.includes("*"))return!0;if(0===t.length)return!1;let n;try{n=new URL(e)}catch{return!1}const o=e.toLowerCase(),r=n.hostname.toLowerCase();for(const e of t){const t=e.trim();if(!t)continue;if(t.includes("://")){if(o===t.toLowerCase())return!0;continue}const n=t.toLowerCase().replace(/^\./,"");if(r===n||r.endsWith(`.${n}`))return!0}return!1}function x(e){if(!e?.length)return[...w];if(e.includes("*"))return["*"];const t=new Set,n=[];for(const o of[...w,...e]){const e=o.trim();e&&!t.has(e)&&(t.add(e),n.push(e))}return n}function M(){if("undefined"==typeof document)return null;const e=document.createElement("canvas");e.setAttribute("data-combos-development-tool-overlay","true"),e.style.position="fixed",e.style.left="0",e.style.top="0",e.style.width="0",e.style.height="0",e.style.margin="0",e.style.padding="0",e.style.border="0",e.style.background="transparent",e.style.pointerEvents="none",e.style.touchAction="none",e.style.userSelect="none",e.style.zIndex="2147483000",e.style.display="none";const t=e.getContext("2d");if(!t)return null;let n=!1,o=!1;return{canvas:e,ctx:t,sync:n=>{!function(e,t){const n=e.parentElement??document.body;t.parentElement!==n&&n.appendChild(t)}(n,e);const r=n.getBoundingClientRect();if(r.width<=0||r.height<=0)return e.style.display="none",null;e.style.display=o?"block":"none",e.style.left=`${r.left}px`,e.style.top=`${r.top}px`,e.style.width=`${r.width}px`,e.style.height=`${r.height}px`;const i="undefined"!=typeof window&&window.devicePixelRatio||1,s=Math.max(1,Math.round(r.width*i)),a=Math.max(1,Math.round(r.height*i));return e.width===s&&e.height===a||(e.width=s,e.height=a),t.setTransform(i,0,0,i,0,0),{width:r.width,height:r.height}},setPickEnabled(t){n=t,e.style.pointerEvents=n?"auto":"none",e.style.cursor=n?"crosshair":"default"},setVisible(t){o=t,e.style.display=t?"block":"none"},destroy(){e.remove()}}}function E(e){return!!e&&"object"==typeof e&&"string"==typeof e.file}function S(e){return"string"==typeof e?"string":"number"==typeof e?"number":"boolean"==typeof e?"boolean":null!==e&&"object"==typeof e?"object":"unsupported"}function k(e,t=0){if(null==e)return e;if("number"==typeof e||"string"==typeof e||"boolean"==typeof e)return e;if(!(t>6)){if(Array.isArray(e))return e.map(e=>k(e,t+1));if("object"==typeof e){const n={};for(const[o,r]of Object.entries(e)){if("function"==typeof r)continue;const e=k(r,t+1);void 0!==e&&(n[o]=e)}return n}}}function T(e){const t=e.constructor,o=function(e){const t=Reflect.getMetadata(n.IDE_PROPERTY_METADATA,e)||{};return Object.keys(t).map(e=>({key:e,...t[e]}))}(t);return o.length>0?o:function(e){const t=e.IDEProps;return!t||Array.isArray(t)||"object"!=typeof t?[]:Object.keys(t).map(e=>{const n=t[e]||{};return{key:e,type:"string"==typeof n.type?n.type:void 0,step:"number"==typeof n.step?n.step:void 0,min:"number"==typeof n.min?n.min:void 0,max:"number"==typeof n.max?n.max:void 0,label:"string"==typeof n.label?n.label:void 0,description:"string"==typeof n.description?n.description:void 0,group:"string"==typeof n.group?n.group:void 0,editor:n.editor,enumOptions:Array.isArray(n.enumOptions)?n.enumOptions:void 0,unit:"string"==typeof n.unit?n.unit:void 0}})}(t)}function C(e,t){return e.editor?e.editor:"boolean"===t?"toggle":e.enumOptions?.length&&"string"===t?"enum":"number"===t?void 0!==e.min&&void 0!==e.max?"number-slider":"number-stepper":"string"===t?"text":void 0}function P(e){if(void 0!==e.min||void 0!==e.max||void 0!==e.step||void 0!==e.unit)return{min:e.min,max:e.max,step:e.step,unit:e.unit}}function _(e,t){if(e.label?.trim())return e.label.trim();const n=t[t.length-1];return n?function(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/_/g," ").replace(/^./,e=>e.toUpperCase())}(n):void 0}function R(e,t,n,o){const r=t.description?.trim();if(!r)return[];const i=S(o);if("unsupported"===i)return[];const s=t.type,a="size"===s||"object"===i&&null!==o&&"width"in o&&"height"in o;if("vector2"===s||"object"===i&&null!==o&&"x"in o&&"y"in o||a){const i=o,s=a?["width","height"]:["x","y"],c=_(t,n)??e,l=[];for(const o of s){const s=i[o],a=S(s);if("unsupported"===a||"object"===a)continue;const d=[...n,o];l.push({path:d,value:s,valueType:a,label:`${c} ${o.toUpperCase()}`,description:r,group:t.group??e,editorKind:C(t,a),numberMeta:P(t),persistTarget:"Transform"===e?"gameObjectConstructor":"component"})}return l}if("object"===i)return[];const c=_(t,n);return c?[{path:n,value:k(o),valueType:i,label:c,description:r,group:t.group??e,editorKind:C(t,i),enumOptions:t.enumOptions,numberMeta:P(t),persistTarget:"Transform"===e?"gameObjectConstructor":"component"}]:[]}function D(e){const t=e.name,n=T(e);if(0===n.length)return[];const o=[],r=e;for(const e of n){const n=r[e.key];"function"!=typeof n&&o.push(...R(t,e,[e.key],n))}return o}function j(e){const t=e.getComponent(u),n=t?.payload?.source;if(E(n))return{file:n.file,anchor:n.anchor??e.name}}function L(e){const t=e.components.filter(e=>"CombosDevelopmentToolTarget"!==e.name).map(e=>({componentName:e.name,fieldDescriptors:D(e)})).filter(e=>e.fieldDescriptors.length>0);return{id:e.id,name:e.name,components:t,source:j(e)}}function N(e,t,n,o){const r=e.getComponent(t);if(!r||!n.length)return!1;let i=r;for(let e=0;e<n.length-1;e++){const t=n[e];void 0!==i[t]&&null!==i[t]||(i[t]={}),i=i[t]}return i[n[n.length-1]]=o,!0}const A=new Set(["position","size","origin","anchor","scale","skew"]);function G(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const t=Number(e);return Number.isFinite(t)?t:void 0}}const B={Transform:function(e,t,n,o){const r=e.transform,i=r;if(1===n.length&&"rotation"===n[0]){const e=G(o);return void 0!==e&&(r.rotation=e,!0)}if(2===n.length&&A.has(n[0])){const t=n[0],r=n[1],s=G(o);if(void 0===s)return!1;const a=i[t];return!(!a||"object"!=typeof a)&&(a[r]=s,"position"===t&&(function(e){const t=e.getComponent("Physics");if(!t?.body)return;const{x:n,y:o}=e.transform.position;t.Body?.setPosition?t.Body.setPosition(t.body,{x:n,y:o}):(t.body.position.x=n,t.body.position.y=o)}(e),function(e){const t=e.getComponent("PlatformerMover");t&&(t.originX=e.transform.position.x,t.originY=e.transform.position.y)}(e)),!0)}return!1},Text:function(e,t,n,o){const r=t;if(1===n.length&&"text"===n[0])return r.text=String(o??""),!0;if(2===n.length&&"style"===n[0]){const e=n[1],t={...r.style??{},[e]:o};return r.style=t,!0}return!1},Sound:function(e,t,n,o){const r=t;if(1===n.length&&"volume"===n[0]||2===n.length&&"config"===n[0]&&"volume"===n[1]){const e=G(o);return void 0!==e&&(r.volume=e,!0)}return!1}};function I(e,t,n,o){const r=e.getComponent(t);if(!r||!n.length)return!1;const i=B[t];return!!i?.(e,r,n,o)||N(e,t,n,o)}function W(e){return{type:c,reason:e}}function V(e){return e}function F(e){return!(!e||"object"!=typeof e)&&e.type===a}function U(e,t){return{a:e.a*t.a+e.c*t.b,b:e.b*t.a+e.d*t.b,c:e.a*t.c+e.c*t.d,d:e.b*t.c+e.d*t.d,tx:e.a*t.tx+e.c*t.ty+e.tx,ty:e.b*t.tx+e.d*t.ty+e.ty}}function Y(e){const t=e.position.x+(e.parent?e.parent.size.width*e.anchor.x:0),n=e.position.y+(e.parent?e.parent.size.height*e.anchor.y:0),o=e.size.width*e.origin.x,r=e.size.height*e.origin.y,i=Math.cos(e.rotation),s=Math.sin(e.rotation),a=i*e.scale.x,c=s*e.scale.x,l=-s*e.scale.y,d=i*e.scale.y;return{a:a,b:c,c:l,d:d,tx:t-(o*a+r*l),ty:n-(o*c+r*d)}}function $(e){if(0===e.length)return null;let t=1/0,n=1/0,o=-1/0,r=-1/0;for(const i of e)Number.isFinite(i.x)&&Number.isFinite(i.y)&&(t=Math.min(t,i.x),n=Math.min(n,i.y),o=Math.max(o,i.x),r=Math.max(r,i.y));return Number.isFinite(t)&&Number.isFinite(n)?{x:t,y:n,width:o-t,height:r-n}:null}function q(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?e:null}function z(e){const t=e?.getSystem?.("Renderer"),n=t?.application?.screen,o=q(n?.width),r=q(n?.height);if(o&&r)return{width:o,height:r};const i=q(t?.params?.width),s=q(t?.params?.height);return i&&s?{width:i,height:s}:null}function K(e){const t=e?.getSystem?.("Renderer3DSystem");return t?.threeContext?.camera??null}function X(e,t){const n=e?.getSystem?.("Renderer3DSystem");return n?.threeContext?.nodes?.get?.(t)??null}function Z(e,t,n,o,r){return[e[0]*t+e[4]*n+e[8]*o+e[12]*r,e[1]*t+e[5]*n+e[9]*o+e[13]*r,e[2]*t+e[6]*n+e[10]*o+e[14]*r,e[3]*t+e[7]*n+e[11]*o+e[15]*r]}function H(e,t,n,o,r){const i=o.matrixWorldInverse?.elements,s=o.projectionMatrix?.elements;if(!i||i.length<16||!s||s.length<16)return null;if(r.width<=0||r.height<=0)return null;const a=Z(i,e,t,n,1),c=Z(s,a[0],a[1],a[2],a[3]);if(!Number.isFinite(c[3])||Math.abs(c[3])<1e-8)return null;if(c[3]<0)return null;const l=c[0]/c[3],d=c[1]/c[3],h=c[2]/c[3];return{x:.5*(l+1)*r.width,y:.5*(1-d)*r.height,depth:h}}function J(e,t,n,o){const r=e[3]*t+e[7]*n+e[11]*o+e[15],i=Math.abs(r)<1e-8?1:1/r;return[(e[0]*t+e[4]*n+e[8]*o+e[12])*i,(e[1]*t+e[5]*n+e[9]*o+e[13])*i,(e[2]*t+e[6]*n+e[10]*o+e[14])*i]}function Q(e,t){const n=Math.max(1,t);return{x:e.x-n/2,y:e.y-n/2,width:n,height:n}}function ee(e,t,n){const o=function(e){const t=[];let n=e;for(;n;)t.push(n),n=n.parent;t.reverse();let o={a:1,b:0,c:0,d:1,tx:0,ty:0};for(const e of t)o=U(o,Y(e));return o}(e),r=e.size.width,i=e.size.height,s=(r>0&&i>0?[{x:0,y:0},{x:r,y:0},{x:r,y:i},{x:0,y:i}]:[{x:0,y:0}]).map(e=>{return t=o,n=e.x,r=e.y,{x:t.a*n+t.c*r+t.tx,y:t.b*n+t.d*r+t.ty};var t,n,r}).map(e=>function(e,t,n){return!t||t.width<=0||t.height<=0?{x:e.x,y:e.y}:{x:e.x*(n.width/t.width),y:e.y*(n.height/t.height)}}(e,n,t)),a=$(s);if(a&&a.width>0&&a.height>0)return a;return Q(s[0]??{x:0,y:0},1)}function te(e,t,n,o){if(o){const e=function(e){const t=[],n=e=>{const n=e.geometry;if(!n)return;n.computeBoundingBox?.();const o=n.boundingBox,r=e.matrixWorld?.elements;if(!o||!r||r.length<16)return;const{min:i,max:s}=o;for(const e of[i.x,s.x])for(const n of[i.y,s.y])for(const o of[i.z,s.z])t.push(J(r,e,n,o))};return e.updateWorldMatrix?.(!0,!0),"function"==typeof e.traverse?e.traverse(n):n(e),t}(o),r=e.map(([e,o,r])=>H(e,o,r,t,n)).filter(e=>null!=e),i=$(r);if(i&&i.width>0&&i.height>0)return i}const r=H(e.worldPositionX??e.positionX??0,e.worldPositionY??e.positionY??0,e.worldPositionZ??e.positionZ??0,t,n);if(!r)return null;return Q(r,32*Math.max(Math.abs(e.scaleX??1),Math.abs(e.scaleY??1),Math.abs(e.scaleZ??1),1))}function ne(e,t){if(t.css.width<=0||t.css.height<=0)return null;const n=function(e){if(!e||"object"!=typeof e)return null;const t=e,n=[t.worldPositionX,t.worldPositionY,t.worldPositionZ].some(e=>"number"==typeof e&&Number.isFinite(e)),o=[t.positionX,t.positionY,t.positionZ].some(e=>"number"==typeof e&&Number.isFinite(e));return n||o?t:null}(e.getComponent("Transform3D"));return n&&t.camera?te(n,t.camera,t.css,t.object3D):ee(e.transform,t.css,t.design??null)}function oe(e,t,n){return t>=e.x&&n>=e.y&&t<=e.x+e.width&&n<=e.y+e.height}let re=class extends t.System{constructor(){super(...arguments),this.postMessageOrigin="*",this.allowedMessageOrigins=x(),this.enabled=!1,this.selected=null,this.overlay=null,this.overlayCss={width:0,height:0},this.pointerDownGoId=null,this.needsRescan=!1,this.mutedWithoutSoundSystem=!1,this.markerOverlayEnabled=!1,this.needsMarkerRescan=!1,this.markerOwners=new Set,this.onWindowSetPickMode=e=>{const t=e.detail;t&&"boolean"==typeof t.enabled&&this.setEnabled(t.enabled)},this.onWindowSetMarkerOverlay=e=>{const t=e.detail;t&&"boolean"==typeof t.enabled&&this.setMarkerOverlay(t.enabled)},this.onGameSetMarkerOverlay=e=>{e&&"boolean"==typeof e.enabled&&this.setMarkerOverlay(e.enabled)},this.onWindowMessage=e=>{if(!O(e.origin,this.allowedMessageOrigins))return;const t=e.data;t&&"object"==typeof t&&(t.type===o&&"boolean"==typeof t.enabled?this.setEnabled(t.enabled):t.type===d&&"boolean"==typeof t.enabled?this.setMarkerOverlay(t.enabled):t.type===i?this.requestSceneRescan():F(t)?this.clearSelectionAndNotify("parent-request"):t.type===l&&this.handleApplyProperty(t))},this.onGameSetPickMode=e=>{e&&"boolean"==typeof e.enabled&&this.setEnabled(e.enabled)},this.onGameRefresh=()=>{this.requestSceneRescan()},this.onWindowRefresh=()=>{this.requestSceneRescan()},this.onPointerDown=e=>{if(!this.enabled)return;e.preventDefault(),e.stopPropagation();try{this.overlay?.canvas.setPointerCapture(e.pointerId)}catch{}const t=this.hitTestPointer(e);this.pointerDownGoId=t?.id??null},this.onPointerUp=e=>{if(!this.enabled)return;e.preventDefault(),e.stopPropagation();const t=this.hitTestPointer(e);t&&t.id===this.pointerDownGoId&&this.onSelect(t,e),this.pointerDownGoId=null}}static{this.systemName="CombosDevelopmentToolSystem"}init(e){this.postMessageOrigin=e?.postMessageOrigin??"*",this.allowedMessageOrigins=x(e?.allowedMessageOrigins),this.overlay=M(),this.overlay&&(this.overlay.canvas.addEventListener("pointerdown",this.onPointerDown),this.overlay.canvas.addEventListener("pointerup",this.onPointerUp)),"undefined"!=typeof window&&(window.addEventListener(o,this.onWindowSetPickMode),window.addEventListener(d,this.onWindowSetMarkerOverlay),window.addEventListener(i,this.onWindowRefresh),window.addEventListener("message",this.onWindowMessage)),this.game.on(o,this.onGameSetPickMode),this.game.on(d,this.onGameSetMarkerOverlay),this.game.on(i,this.onGameRefresh),this.syncOverlayMode(),this.enabled&&(this.needsRescan=!0)}onDestroy(){this.overlay&&(this.overlay.canvas.removeEventListener("pointerdown",this.onPointerDown),this.overlay.canvas.removeEventListener("pointerup",this.onPointerUp),this.overlay.destroy(),this.overlay=null),"undefined"!=typeof window&&(window.removeEventListener(o,this.onWindowSetPickMode),window.removeEventListener(d,this.onWindowSetMarkerOverlay),window.removeEventListener(i,this.onWindowRefresh),window.removeEventListener("message",this.onWindowMessage)),this.game.off(o,this.onGameSetPickMode),this.game.off(d,this.onGameSetMarkerOverlay),this.game.off(i,this.onGameRefresh),this.markerOwners.clear(),this.clearSelectionAndNotify("pick-disabled")}setEnabled(e){this.enabled!==e&&(this.enabled=e,this.syncOverlayMode(),e?(this.needsRescan=!0,this.redrawOverlay()):(this.clearSelectionAndNotify("pick-disabled"),this.postSetSuccess(!1)))}get isEnabled(){return this.enabled}setMarkerOverlay(e){this.markerOverlayEnabled!==e&&(this.markerOverlayEnabled=e,this.syncOverlayMode(),e?this.needsMarkerRescan=!0:(this.markerOwners.clear(),this.postMarkerOverlaySuccess(!1,[]),this.redrawOverlay()))}get isMarkerOverlayEnabled(){return this.markerOverlayEnabled}get isMuted(){const e=this.getSoundSystem();return e?e.muted:this.mutedWithoutSoundSystem}setMuted(e){const t=this.getSoundSystem();t?t.muted=e:this.mutedWithoutSoundSystem=e}update(){this.enabled&&this.needsRescan&&(this.needsRescan=!1,this.postSetSuccess(!0)),this.markerOverlayEnabled&&this.needsMarkerRescan&&(this.needsMarkerRescan=!1,this.attachMarkers()),this.selected?.destroyed&&this.clearSelectionAndNotify("target-removed")}lateUpdate(e){this.redrawOverlay()}componentChanged(e){const{type:n,gameObject:o,componentName:r}=e;o&&"CombosDevelopmentToolTarget"===r&&(n===t.OBSERVER_TYPE.REMOVE&&this.selected===o&&this.clearSelectionAndNotify("target-removed"),this.markerOverlayEnabled&&(this.needsMarkerRescan=!0))}requestSceneRescan(){this.enabled&&(this.needsRescan=!0),this.markerOverlayEnabled&&(this.needsMarkerRescan=!0)}syncOverlayMode(){const e=this.enabled||this.markerOverlayEnabled;this.overlay?.setVisible(e),this.overlay?.setPickEnabled(this.enabled)}collectGameObjects(e,t){t.push(e);for(const n of e.transform.children)this.collectGameObjects(n.gameObject,t)}listSceneObjects(){const e=[],t=this.game.scene;if(!t?.transform?.children)return e;for(const n of t.transform.children)this.collectGameObjects(n.gameObject,e);return e}isIgnoredPickGo(e){return"__combosDevelopmentToolOutline"===e.name||this.isMarkerGo(e)}isMarkerGo(e){return"string"==typeof e.name&&e.name.startsWith("__combosDevelopmentToolMarker:")}projectGo(e){return ne(e,{css:this.overlayCss,design:z(this.game),camera:K(this.game),object3D:X(this.game,e.id)})}collectOverlayHits(){const e=[];for(const t of this.listSceneObjects()){if(t.destroyed||this.isIgnoredPickGo(t))continue;if(!t.getComponent(u))continue;const n=this.projectGo(t);if(n&&e.push({go:t,rect:n}),this.markerOverlayEnabled&&g(t)){const o=this.markerRectFor(t,n);o&&e.push({go:t,rect:o})}}return e}markerRectFor(e,t){const n=t??this.projectGo(e);return n?e.getComponent("Transform3D")?{x:n.x+n.width/2-14,y:n.y+n.height/2-14,width:y,height:y}:{x:n.x,y:n.y,width:y,height:y}:null}overlayPoint(e){const t=this.overlay?.canvas;if(!t)return{x:0,y:0};const n=t.getBoundingClientRect();return{x:e.clientX-n.left,y:e.clientY-n.top}}hitTestPointer(e){const t=this.overlayPoint(e),n=this.collectOverlayHits();return function(e,t,n){let o=null;for(let r=0;r<n.length;r++){const i=n[r];if(!oe(i.rect,e,t))continue;const s=Math.max(i.rect.width,0)*Math.max(i.rect.height,0);(!o||s<o.area||s===o.area&&r>o.index)&&(o={id:i.id,area:s,index:r})}return o?o.id:null}(t.x,t.y,n.map(e=>({id:e.go,rect:e.rect})))}redrawOverlay(){const e=this.overlay;if(!e)return;if(!(this.enabled||this.markerOverlayEnabled))return void e.setVisible(!1);const t=this.game.canvas??this.game.scene?.canvas;if(!t)return;const n=e.sync(t);n&&(this.overlayCss=n,e.ctx.clearRect(0,0,n.width,n.height),this.drawMarkers(e.ctx),this.drawSelectionOutline(e.ctx))}drawMarkers(e){if(!this.markerOverlayEnabled)return;const t=new m(e);for(const n of this.listSceneObjects()){if(n.destroyed||this.isIgnoredPickGo(n))continue;const o=g(n);if(!o)continue;const r=this.projectGo(n),i=this.markerRectFor(n,r);i&&(e.save(),e.translate(i.x,i.y),v(t,o,y),e.restore())}}drawSelectionOutline(e){if(!this.enabled||!this.selected||this.selected.destroyed)return;const t=this.projectGo(this.selected);if(!t)return;const n=z(this.game),o=n?this.overlayCss.width/n.width:1;e.save(),e.strokeStyle="#55ffaa",e.lineWidth=Math.max(2,4*(Number.isFinite(o)&&o>0?o:1)),e.strokeRect(t.x,t.y,t.width,t.height),e.restore()}postSetSuccess(e){const t={type:r,enabled:e};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(r,{enabled:e})}attachMarkers(){this.markerOwners.clear();const e=new Map;for(const t of this.listSceneObjects()){if(this.isIgnoredPickGo(t))continue;const n=g(t);n&&(this.markerOwners.add(t.id),e.set(n.componentName,(e.get(n.componentName)??0)+1))}const t=[...e.entries()].map(([e,t])=>({componentName:e,count:t}));this.postMarkerOverlaySuccess(!0,t),this.redrawOverlay()}postMarkerOverlaySuccess(e,t){const n={enabled:e,total:t.reduce((e,t)=>e+t.count,0),markers:t},o={type:h,...n};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(o,this.postMessageOrigin),this.game.emit(h,n)}getSoundSystem(){const e=this.game.getSystem("SoundSystem");return e&&"object"==typeof e&&"muted"in e&&"boolean"==typeof e.muted?e:null}onSelect(e,t){if(!this.enabled)return;this.selected=e,this.redrawOverlay();const n=this.overlayPoint(t),o=(r=n,i=z(this.game),a=this.overlayCss,!i||i.width<=0||i.height<=0||a.width<=0||a.height<=0?{x:r.x,y:r.y}:{x:r.x*(i.width/a.width),y:r.y*(i.height/a.height)});var r,i,a;const c=L(e),l={type:s,snapshot:c,pointer:o};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(l,this.postMessageOrigin)}findGameObjectById(e){return this.listSceneObjects().find(t=>t.id===e)??null}findGameObjectBySource(e){const t=e.file.trim(),n=(e.anchor??"").trim();if(!n)return null;for(const e of this.listSceneObjects()){const o=j(e);if(!o||o.file!==t)continue;if((o.anchor??e.name)===n)return e}return null}resolveApplyTarget(e){if("number"==typeof e.gameObjectId){const t=this.findGameObjectById(e.gameObjectId);if(t)return t}const t=e.source?.file?.trim(),n=e.source?.anchor?.trim();return t&&n?this.findGameObjectBySource({file:t,anchor:n}):null}handleApplyProperty(e){const t=e.componentName,n=e.path,o="number"==typeof e.gameObjectId,r=Boolean(e.source?.file?.trim())&&Boolean(e.source?.anchor?.trim());if(!o&&!r||"string"!=typeof t||!Array.isArray(n)||0===n.length)return;const i=this.resolveApplyTarget(e);if(!i)return;I(i,t,n,e.value)&&this.selected?.id===i.id&&(this.redrawOverlay(),this.postSnapshotUpdate(i))}postSnapshotUpdate(e){const t=L(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage({type:s,snapshot:t,pointer:null,source:"property-applied"},this.postMessageOrigin)}clearSelectionAndNotify(e){const t=null!=this.selected;this.selected=null,this.redrawOverlay(),t&&this.postGameObjectDeselected(e)}postGameObjectDeselected(e){const t=W(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(t.type,{reason:e})}};re=e.__decorate([t.decorators.componentObserver({CombosDevelopmentToolTarget:[]})],re);var ie=re;Object.assign(ie,{packageName:"@combos-fun/plugin-development-tool",packageVersion:"0.0.52"}),exports.COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY=l,exports.COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION=a,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED=c,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED=s,exports.COMBOS_DEVELOPMENT_TOOL_MARKER_OVERLAY_SUCCESS=h,exports.COMBOS_DEVELOPMENT_TOOL_PICK_MODE_SUCCESS=r,exports.COMBOS_DEVELOPMENT_TOOL_READY="combos-development-tool:ready",exports.COMBOS_DEVELOPMENT_TOOL_REFRESH=i,exports.COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY=d,exports.COMBOS_DEVELOPMENT_TOOL_SET_MUTED="combos-development-tool:set-muted",exports.COMBOS_DEVELOPMENT_TOOL_SET_PICK_MODE=o,exports.COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED="combos-development-tool:state-changed",exports.CombosDevelopmentToolSystem=ie,exports.CombosDevelopmentToolTarget=u,exports.DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES=w,exports.MARKER_COMPONENTS=f,exports.MARKER_ICON_SIZE=y,exports.applyPropertyValue=N,exports.applyPropertyWithHooks=I,exports.attachDevelopmentTarget=function(e,t){if(!e||e.destroyed||function(e){return"string"==typeof e.name&&e.name.startsWith("__")}(e)||function(e){return Array.isArray(e.gameObjects)}(e))return e;const n=t.file.trim(),o=t.anchor.trim();if(!n||!o)return e;const r=e.getComponent(u);return r?(i=r.payload?.source,E(i)&&Boolean(i.file.trim())&&Boolean((i.anchor??"").trim())||(r.payload={...r.payload??{},source:{file:n,anchor:o}}),e):(e.addComponent(new u({payload:{source:{file:n,anchor:o}}})),e);var i},exports.buildGameObjectDeselectedPayload=W,exports.buildGameObjectSnapshot=L,exports.drawMarkerIcon=v,exports.isAllowedMessageOrigin=O,exports.isClearSelectionMessage=F,exports.mergeAllowedMessageOrigins=x,exports.readPropertyValue=function(e,t,n){const o=e.getComponent(t);if(!o||!n.length)return;let r=o;for(const e of n){if(null==r||"object"!=typeof r)return;r=r[e]}return r},exports.readSourceAnchor=j,exports.resolveMarkerDef=g,exports.shouldNotifyGameObjectDeselected=V;
|
|
1
|
+
"use strict";var e=require("tslib"),t=require("@combos-fun/engine"),n=require("@combos-fun/inspector-decorator");const o="combos-development-tool:set-pick-mode",i="combos-development-tool:pick-mode-success",r="combos-development-tool:refresh",s="combos-development-tool:gameobject-selected",a="combos-development-tool:clear-selection",c="combos-development-tool:gameobject-deselected",l="combos-development-tool:apply-property",h="combos-development-tool:set-marker-overlay",d="combos-development-tool:marker-overlay-success";class u extends t.Component{constructor(){super(...arguments),this.payload={}}static{this.componentName="CombosDevelopmentToolTarget"}init(e){this.payload=e?.payload?{...e.payload}:{}}}function p(e,t=1){return`rgba(${e>>16&255}, ${e>>8&255}, ${255&e}, ${t})`}class m{constructor(e){this.ctx=e}clear(){this.ctx.beginPath()}roundRect(e,t,n,o,i=0){const r=this.ctx;if("function"==typeof r.roundRect)return void r.roundRect(e,t,n,o,i);const s=Math.max(0,Math.min(i,Math.min(n,o)/2));r.moveTo(e+s,t),r.lineTo(e+n-s,t),r.quadraticCurveTo(e+n,t,e+n,t+s),r.lineTo(e+n,t+o-s),r.quadraticCurveTo(e+n,t+o,e+n-s,t+o),r.lineTo(e+s,t+o),r.quadraticCurveTo(e,t+o,e,t+o-s),r.lineTo(e,t+s),r.quadraticCurveTo(e,t,e+s,t),r.closePath()}rect(e,t,n,o){this.ctx.rect(e,t,n,o)}circle(e,t,n){this.ctx.moveTo(e+n,t),this.ctx.arc(e,t,n,0,2*Math.PI)}poly(e,t=!0){if(!(e.length<4)){this.ctx.moveTo(e[0],e[1]);for(let t=2;t<e.length;t+=2)this.ctx.lineTo(e[t],e[t+1]);t&&this.ctx.closePath()}}fill(e){this.ctx.fillStyle=p(e.color,e.alpha??1),this.ctx.fill(),this.ctx.beginPath()}stroke(e){this.ctx.strokeStyle=p(e.color,e.alpha??1),this.ctx.lineWidth=e.width,this.ctx.stroke(),this.ctx.beginPath()}}const f=[{componentName:"Sound",badgeColor:9133302,glyph:"speaker"}],y=28;function g(e,t=f){for(const n of t)if(e.getComponent(n.componentName))return n;return null}const b=16777215;function w(e,t,n=28){if(function(e,t,n){e.clear(),e.roundRect(0,0,n,n,.22*n),e.fill({color:t.badgeColor,alpha:.92}),e.roundRect(0,0,n,n,.22*n),e.stroke({width:Math.max(1,.05*n),color:16777215,alpha:.6})}(e,t,n),"speaker"===t.glyph)!function(e,t){e.poly([.28*t,.4*t,.42*t,.4*t,.55*t,.26*t,.55*t,.74*t,.42*t,.6*t,.28*t,.6*t]),e.fill({color:b,alpha:.96}),e.rect(.62*t,.44*t,.045*t,.12*t),e.fill({color:b,alpha:.96}),e.rect(.71*t,.39*t,.045*t,.22*t),e.fill({color:b,alpha:.96})}(e,n);else!function(e,t){e.circle(.5*t,.5*t,.18*t),e.fill({color:b,alpha:.96})}(e,n)}const v=["knoffice.tech","converge.ai"];function O(e,t){if(t.includes("*"))return!0;if(0===t.length)return!1;let n;try{n=new URL(e)}catch{return!1}const o=e.toLowerCase(),i=n.hostname.toLowerCase();for(const e of t){const t=e.trim();if(!t)continue;if(t.includes("://")){if(o===t.toLowerCase())return!0;continue}const n=t.toLowerCase().replace(/^\./,"");if(i===n||i.endsWith(`.${n}`))return!0}return!1}function x(e){if(!e?.length)return[...v];if(e.includes("*"))return["*"];const t=new Set,n=[];for(const o of[...v,...e]){const e=o.trim();e&&!t.has(e)&&(t.add(e),n.push(e))}return n}function M(){if("undefined"==typeof document)return null;const e=document.createElement("canvas");e.setAttribute("data-combos-development-tool-overlay","true"),e.style.position="fixed",e.style.left="0",e.style.top="0",e.style.width="0",e.style.height="0",e.style.margin="0",e.style.padding="0",e.style.border="0",e.style.background="transparent",e.style.pointerEvents="none",e.style.touchAction="none",e.style.userSelect="none",e.style.zIndex="2147483000",e.style.display="none";const t=e.getContext("2d");if(!t)return null;let n=!1,o=!1;return{canvas:e,ctx:t,sync:n=>{!function(e,t){const n=document.body;n&&t.parentElement!==n&&n.appendChild(t)}(0,e);const i=n.getBoundingClientRect();if(i.width<=0||i.height<=0)return e.style.display="none",null;e.style.display=o?"block":"none",e.style.left=`${i.left}px`,e.style.top=`${i.top}px`,e.style.width=`${i.width}px`,e.style.height=`${i.height}px`;const r="undefined"!=typeof window&&window.devicePixelRatio||1,s=Math.max(1,Math.round(i.width*r)),a=Math.max(1,Math.round(i.height*r));return e.width===s&&e.height===a||(e.width=s,e.height=a),t.setTransform(r,0,0,r,0,0),{width:i.width,height:i.height}},setPickEnabled(t){n=t,e.style.pointerEvents=n?"auto":"none",e.style.cursor=n?"crosshair":"default"},setVisible(t){o=t,e.style.display=t?"block":"none"},destroy(){e.remove()}}}function E(e){return!!e&&"object"==typeof e&&"string"==typeof e.file}function S(e){return"string"==typeof e?"string":"number"==typeof e?"number":"boolean"==typeof e?"boolean":null!==e&&"object"==typeof e?"object":"unsupported"}function k(e,t=0){if(null==e)return e;if("number"==typeof e||"string"==typeof e||"boolean"==typeof e)return e;if(!(t>6)){if(Array.isArray(e))return e.map(e=>k(e,t+1));if("object"==typeof e){const n={};for(const[o,i]of Object.entries(e)){if("function"==typeof i)continue;const e=k(i,t+1);void 0!==e&&(n[o]=e)}return n}}}function T(e){const t=e.constructor,o=function(e){const t=Reflect.getMetadata(n.IDE_PROPERTY_METADATA,e)||{};return Object.keys(t).map(e=>({key:e,...t[e]}))}(t);return o.length>0?o:function(e){const t=e.IDEProps;return!t||Array.isArray(t)||"object"!=typeof t?[]:Object.keys(t).map(e=>{const n=t[e]||{};return{key:e,type:"string"==typeof n.type?n.type:void 0,step:"number"==typeof n.step?n.step:void 0,min:"number"==typeof n.min?n.min:void 0,max:"number"==typeof n.max?n.max:void 0,label:"string"==typeof n.label?n.label:void 0,description:"string"==typeof n.description?n.description:void 0,group:"string"==typeof n.group?n.group:void 0,editor:n.editor,enumOptions:Array.isArray(n.enumOptions)?n.enumOptions:void 0,unit:"string"==typeof n.unit?n.unit:void 0}})}(t)}function P(e,t){return e.editor?e.editor:"boolean"===t?"toggle":e.enumOptions?.length&&"string"===t?"enum":"number"===t?void 0!==e.min&&void 0!==e.max?"number-slider":"number-stepper":"string"===t?"text":void 0}function C(e){if(void 0!==e.min||void 0!==e.max||void 0!==e.step||void 0!==e.unit)return{min:e.min,max:e.max,step:e.step,unit:e.unit}}function _(e,t){if(e.label?.trim())return e.label.trim();const n=t[t.length-1];return n?function(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/_/g," ").replace(/^./,e=>e.toUpperCase())}(n):void 0}function D(e,t,n,o){const i=t.description?.trim();if(!i)return[];const r=S(o);if("unsupported"===r)return[];const s=t.type,a="size"===s||"object"===r&&null!==o&&"width"in o&&"height"in o;if("vector2"===s||"object"===r&&null!==o&&"x"in o&&"y"in o||a){const r=o,s=a?["width","height"]:["x","y"],c=_(t,n)??e,l=[];for(const o of s){const s=r[o],a=S(s);if("unsupported"===a||"object"===a)continue;const h=[...n,o];l.push({path:h,value:s,valueType:a,label:`${c} ${o.toUpperCase()}`,description:i,group:t.group??e,editorKind:P(t,a),numberMeta:C(t),persistTarget:"Transform"===e?"gameObjectConstructor":"component"})}return l}if("object"===r)return[];const c=_(t,n);return c?[{path:n,value:k(o),valueType:r,label:c,description:i,group:t.group??e,editorKind:P(t,r),enumOptions:t.enumOptions,numberMeta:C(t),persistTarget:"Transform"===e?"gameObjectConstructor":"component"}]:[]}function R(e){const t=e.name,n=T(e);if(0===n.length)return[];const o=[],i=e;for(const e of n){const n=i[e.key];"function"!=typeof n&&o.push(...D(t,e,[e.key],n))}return o}function L(e){const t=e.getComponent(u),n=t?.payload?.source;if(E(n))return{file:n.file,anchor:n.anchor??e.name}}function j(e){const t=e.components.filter(e=>"CombosDevelopmentToolTarget"!==e.name).map(e=>({componentName:e.name,fieldDescriptors:R(e)})).filter(e=>e.fieldDescriptors.length>0);return{id:e.id,name:e.name,components:t,source:L(e)}}function N(e,t,n,o){const i=e.getComponent(t);if(!i||!n.length)return!1;let r=i;for(let e=0;e<n.length-1;e++){const t=n[e];void 0!==r[t]&&null!==r[t]||(r[t]={}),r=r[t]}return r[n[n.length-1]]=o,!0}const A=new Set(["position","size","origin","anchor","scale","skew"]);function G(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const t=Number(e);return Number.isFinite(t)?t:void 0}}const I={Transform:function(e,t,n,o){const i=e.transform,r=i;if(1===n.length&&"rotation"===n[0]){const e=G(o);return void 0!==e&&(i.rotation=e,!0)}if(2===n.length&&A.has(n[0])){const t=n[0],i=n[1],s=G(o);if(void 0===s)return!1;const a=r[t];return!(!a||"object"!=typeof a)&&(a[i]=s,"position"===t&&(function(e){const t=e.getComponent("Physics");if(!t?.body)return;const{x:n,y:o}=e.transform.position;t.Body?.setPosition?t.Body.setPosition(t.body,{x:n,y:o}):(t.body.position.x=n,t.body.position.y=o)}(e),function(e){const t=e.getComponent("PlatformerMover");t&&(t.originX=e.transform.position.x,t.originY=e.transform.position.y)}(e)),!0)}return!1},Text:function(e,t,n,o){const i=t;if(1===n.length&&"text"===n[0])return i.text=String(o??""),!0;if(2===n.length&&"style"===n[0]){const e=n[1],t={...i.style??{},[e]:o};return i.style=t,!0}return!1},Sound:function(e,t,n,o){const i=t;if(1===n.length&&"volume"===n[0]||2===n.length&&"config"===n[0]&&"volume"===n[1]){const e=G(o);return void 0!==e&&(i.volume=e,!0)}return!1}};function B(e,t,n,o){const i=e.getComponent(t);if(!i||!n.length)return!1;const r=I[t];return!!r?.(e,i,n,o)||N(e,t,n,o)}function W(e){return{type:c,reason:e}}function V(e){return e}function F(e){return!(!e||"object"!=typeof e)&&e.type===a}function Y(e,t){return{a:e.a*t.a+e.c*t.b,b:e.b*t.a+e.d*t.b,c:e.a*t.c+e.c*t.d,d:e.b*t.c+e.d*t.d,tx:e.a*t.tx+e.c*t.ty+e.tx,ty:e.b*t.tx+e.d*t.ty+e.ty}}function U(e){const t=e.position.x+(e.parent?e.parent.size.width*e.anchor.x:0),n=e.position.y+(e.parent?e.parent.size.height*e.anchor.y:0),o=e.size.width*e.origin.x,i=e.size.height*e.origin.y,r=Math.cos(e.rotation),s=Math.sin(e.rotation),a=r*e.scale.x,c=s*e.scale.x,l=-s*e.scale.y,h=r*e.scale.y;return{a:a,b:c,c:l,d:h,tx:t-(o*a+i*l),ty:n-(o*c+i*h)}}function $(e){if(0===e.length)return null;let t=1/0,n=1/0,o=-1/0,i=-1/0;for(const r of e)Number.isFinite(r.x)&&Number.isFinite(r.y)&&(t=Math.min(t,r.x),n=Math.min(n,r.y),o=Math.max(o,r.x),i=Math.max(i,r.y));return Number.isFinite(t)&&Number.isFinite(n)?{x:t,y:n,width:o-t,height:i-n}:null}function q(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?e:null}function z(e){const t=e?.getSystem?.("Renderer"),n=t?.application?.screen,o=q(n?.width),i=q(n?.height);if(o&&i)return{width:o,height:i};const r=q(t?.params?.width),s=q(t?.params?.height);return r&&s?{width:r,height:s}:null}function X(e){const t=e?.getSystem?.("Renderer3DSystem");return t?.threeContext?.camera??null}function K(e,t){const n=e?.getSystem?.("Renderer3DSystem");return n?.threeContext?.nodes?.get?.(t)??null}function Z(e,t,n,o,i){return[e[0]*t+e[4]*n+e[8]*o+e[12]*i,e[1]*t+e[5]*n+e[9]*o+e[13]*i,e[2]*t+e[6]*n+e[10]*o+e[14]*i,e[3]*t+e[7]*n+e[11]*o+e[15]*i]}function H(e,t,n,o,i){const r=o.matrixWorldInverse?.elements,s=o.projectionMatrix?.elements;if(!r||r.length<16||!s||s.length<16)return null;if(i.width<=0||i.height<=0)return null;const a=Z(r,e,t,n,1),c=Z(s,a[0],a[1],a[2],a[3]);if(!Number.isFinite(c[3])||Math.abs(c[3])<1e-8)return null;if(c[3]<0)return null;const l=c[0]/c[3],h=c[1]/c[3],d=c[2]/c[3];return{x:.5*(l+1)*i.width,y:.5*(1-h)*i.height,depth:d}}function J(e,t,n,o){const i=e[3]*t+e[7]*n+e[11]*o+e[15],r=Math.abs(i)<1e-8?1:1/i;return[(e[0]*t+e[4]*n+e[8]*o+e[12])*r,(e[1]*t+e[5]*n+e[9]*o+e[13])*r,(e[2]*t+e[6]*n+e[10]*o+e[14])*r]}function Q(e,t){const n=Math.max(1,t);return{x:e.x-n/2,y:e.y-n/2,width:n,height:n}}function ee(e,t,n){const o=function(e){const t=[];let n=e;for(;n;)t.push(n),n=n.parent;t.reverse();let o={a:1,b:0,c:0,d:1,tx:0,ty:0};for(const e of t)o=Y(o,U(e));return o}(e),i=e.size.width,r=e.size.height,s=(i>0&&r>0?[{x:0,y:0},{x:i,y:0},{x:i,y:r},{x:0,y:r}]:[{x:0,y:0}]).map(e=>{return t=o,n=e.x,i=e.y,{x:t.a*n+t.c*i+t.tx,y:t.b*n+t.d*i+t.ty};var t,n,i}).map(e=>function(e,t,n){return!t||t.width<=0||t.height<=0?{x:e.x,y:e.y}:{x:e.x*(n.width/t.width),y:e.y*(n.height/t.height)}}(e,n,t)),a=$(s);if(a&&a.width>0&&a.height>0)return a;return Q(s[0]??{x:0,y:0},1)}function te(e,t,n,o){if(o){const e=function(e){const t=[],n=e=>{const n=e.geometry;if(!n)return;n.computeBoundingBox?.();const o=n.boundingBox,i=e.matrixWorld?.elements;if(!o||!i||i.length<16)return;const{min:r,max:s}=o;for(const e of[r.x,s.x])for(const n of[r.y,s.y])for(const o of[r.z,s.z])t.push(J(i,e,n,o))};return e.updateWorldMatrix?.(!0,!0),"function"==typeof e.traverse?e.traverse(n):n(e),t}(o),i=e.map(([e,o,i])=>H(e,o,i,t,n)).filter(e=>null!=e),r=$(i);if(r&&r.width>0&&r.height>0)return r}const i=H(e.worldPositionX??e.positionX??0,e.worldPositionY??e.positionY??0,e.worldPositionZ??e.positionZ??0,t,n);if(!i)return null;return Q(i,32*Math.max(Math.abs(e.scaleX??1),Math.abs(e.scaleY??1),Math.abs(e.scaleZ??1),1))}function ne(e,t){if(t.css.width<=0||t.css.height<=0)return null;const n=function(e){if(!e||"object"!=typeof e)return null;const t=e,n=[t.worldPositionX,t.worldPositionY,t.worldPositionZ].some(e=>"number"==typeof e&&Number.isFinite(e)),o=[t.positionX,t.positionY,t.positionZ].some(e=>"number"==typeof e&&Number.isFinite(e));return n||o?t:null}(e.getComponent("Transform3D"));return n&&t.camera?te(n,t.camera,t.css,t.object3D):ee(e.transform,t.css,t.design??null)}function oe(e,t,n){return t>=e.x&&n>=e.y&&t<=e.x+e.width&&n<=e.y+e.height}const ie=["Img","Sprite","TilingSprite","NinePatch","Text","Graphics","SpriteAnimation","Img3D","Sprite3D","TilingSprite3D","Text3D","Graphics3D","Model3D","SpriteAnimation3D"];function re(e,t,n=.75){if(!t||t.width<=0||t.height<=0)return!1;const o=t.width*t.height;return!(o<=0)&&function(e,t){const n=Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x),o=Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y);return n<=0||o<=0?0:n*o}(e,{x:0,y:0,width:t.width,height:t.height})/o>=n}function se(e){const t=e.getComponent("Render"),n=e.getComponent("Render3D"),o=!1!==t?.visible&&!1!==n?.visible,i=Math.min("number"==typeof t?.alpha&&Number.isFinite(t.alpha)?t.alpha:1,"number"==typeof n?.opacity&&Number.isFinite(n.opacity)?n.opacity:1);let r=0;return!o||i<=0?r+=2:i<=.35&&(r+=1),function(e){return ie.some(t=>Boolean(e.getComponent(t)))}(e)||(r+=1),r}function ae(e,t){return e.score!==t.score?e.score<t.score:e.covering!==t.covering?!e.covering:e.covering?e.index<t.index:e.area!==t.area?e.area<t.area:e.index>t.index}let ce=class extends t.System{constructor(){super(...arguments),this.postMessageOrigin="*",this.allowedMessageOrigins=x(),this.enabled=!1,this.selected=null,this.overlay=null,this.overlayCss={width:0,height:0},this.pointerDownGoId=null,this.pickListening=!1,this.needsRescan=!1,this.mutedWithoutSoundSystem=!1,this.markerOverlayEnabled=!1,this.needsMarkerRescan=!1,this.markerOwners=new Set,this.onWindowSetPickMode=e=>{const t=e.detail;t&&"boolean"==typeof t.enabled&&this.setEnabled(t.enabled)},this.onWindowSetMarkerOverlay=e=>{const t=e.detail;t&&"boolean"==typeof t.enabled&&this.setMarkerOverlay(t.enabled)},this.onGameSetMarkerOverlay=e=>{e&&"boolean"==typeof e.enabled&&this.setMarkerOverlay(e.enabled)},this.onWindowMessage=e=>{if(!O(e.origin,this.allowedMessageOrigins))return;const t=e.data;t&&"object"==typeof t&&(t.type===o&&"boolean"==typeof t.enabled?this.setEnabled(t.enabled):t.type===h&&"boolean"==typeof t.enabled?this.setMarkerOverlay(t.enabled):t.type===r?this.requestSceneRescan():F(t)?this.clearSelectionAndNotify("parent-request"):t.type===l&&this.handleApplyProperty(t))},this.onGameSetPickMode=e=>{e&&"boolean"==typeof e.enabled&&this.setEnabled(e.enabled)},this.onGameRefresh=()=>{this.requestSceneRescan()},this.onWindowRefresh=()=>{this.requestSceneRescan()},this.onPointerDown=e=>{if(!this.enabled||!this.isPickPointInGame(e))return;e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation();try{this.overlay?.canvas.setPointerCapture(e.pointerId)}catch{}const t=this.hitTestPointer(e);this.pointerDownGoId=t?.id??null},this.onPointerUp=e=>{if(!this.enabled)return;if(!this.isPickPointInGame(e))return void(this.pointerDownGoId=null);e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation();const t=this.hitTestPointer(e);t&&t.id===this.pointerDownGoId&&this.onSelect(t,e),this.pointerDownGoId=null}}static{this.systemName="CombosDevelopmentToolSystem"}init(e){this.postMessageOrigin=e?.postMessageOrigin??"*",this.allowedMessageOrigins=x(e?.allowedMessageOrigins),this.overlay=M(),"undefined"!=typeof window&&(window.addEventListener(o,this.onWindowSetPickMode),window.addEventListener(h,this.onWindowSetMarkerOverlay),window.addEventListener(r,this.onWindowRefresh),window.addEventListener("message",this.onWindowMessage)),this.game.on(o,this.onGameSetPickMode),this.game.on(h,this.onGameSetMarkerOverlay),this.game.on(r,this.onGameRefresh),this.syncOverlayMode(),this.enabled&&(this.needsRescan=!0)}onDestroy(){this.unbindPickListeners(),this.overlay&&(this.overlay.destroy(),this.overlay=null),"undefined"!=typeof window&&(window.removeEventListener(o,this.onWindowSetPickMode),window.removeEventListener(h,this.onWindowSetMarkerOverlay),window.removeEventListener(r,this.onWindowRefresh),window.removeEventListener("message",this.onWindowMessage)),this.game.off(o,this.onGameSetPickMode),this.game.off(h,this.onGameSetMarkerOverlay),this.game.off(r,this.onGameRefresh),this.markerOwners.clear(),this.clearSelectionAndNotify("pick-disabled")}setEnabled(e){this.enabled!==e&&(this.enabled=e,this.syncOverlayMode(),e?(this.needsRescan=!0,this.redrawOverlay()):(this.clearSelectionAndNotify("pick-disabled"),this.postSetSuccess(!1)))}get isEnabled(){return this.enabled}setMarkerOverlay(e){this.markerOverlayEnabled!==e&&(this.markerOverlayEnabled=e,this.syncOverlayMode(),e?this.needsMarkerRescan=!0:(this.markerOwners.clear(),this.postMarkerOverlaySuccess(!1,[]),this.redrawOverlay()))}get isMarkerOverlayEnabled(){return this.markerOverlayEnabled}get isMuted(){const e=this.getSoundSystem();return e?e.muted:this.mutedWithoutSoundSystem}setMuted(e){const t=this.getSoundSystem();t?t.muted=e:this.mutedWithoutSoundSystem=e}update(){this.enabled&&this.needsRescan&&(this.needsRescan=!1,this.postSetSuccess(!0)),this.markerOverlayEnabled&&this.needsMarkerRescan&&(this.needsMarkerRescan=!1,this.attachMarkers()),this.selected?.destroyed&&this.clearSelectionAndNotify("target-removed")}lateUpdate(e){this.redrawOverlay()}componentChanged(e){const{type:n,gameObject:o,componentName:i}=e;o&&"CombosDevelopmentToolTarget"===i&&(n===t.OBSERVER_TYPE.REMOVE&&this.selected===o&&this.clearSelectionAndNotify("target-removed"),this.markerOverlayEnabled&&(this.needsMarkerRescan=!0))}requestSceneRescan(){this.enabled&&(this.needsRescan=!0),this.markerOverlayEnabled&&(this.needsMarkerRescan=!0)}syncOverlayMode(){const e=this.enabled||this.markerOverlayEnabled;this.overlay?.setVisible(e),this.overlay?.setPickEnabled(this.enabled),this.enabled?this.bindPickListeners():this.unbindPickListeners()}bindPickListeners(){this.pickListening||"undefined"==typeof window||(window.addEventListener("pointerdown",this.onPointerDown,!0),window.addEventListener("pointerup",this.onPointerUp,!0),this.pickListening=!0)}unbindPickListeners(){this.pickListening&&"undefined"!=typeof window&&(window.removeEventListener("pointerdown",this.onPointerDown,!0),window.removeEventListener("pointerup",this.onPointerUp,!0),this.pickListening=!1)}isPickPointInGame(e){const t=this.game.canvas??this.game.scene?.canvas??this.overlay?.canvas;if(!t)return!1;const n=t.getBoundingClientRect();return n.width>0&&n.height>0&&e.clientX>=n.left&&e.clientX<=n.right&&e.clientY>=n.top&&e.clientY<=n.bottom}collectGameObjects(e,t){t.push(e);for(const n of e.transform.children)this.collectGameObjects(n.gameObject,t)}listSceneObjects(){const e=[],t=this.game.scene;if(!t?.transform?.children)return e;for(const n of t.transform.children)this.collectGameObjects(n.gameObject,e);return e}isIgnoredPickGo(e){return"__combosDevelopmentToolOutline"===e.name||this.isMarkerGo(e)}isMarkerGo(e){return"string"==typeof e.name&&e.name.startsWith("__combosDevelopmentToolMarker:")}projectGo(e){return ne(e,{css:this.overlayCss,design:z(this.game),camera:X(this.game),object3D:K(this.game,e.id)})}collectOverlayHits(){const e=[];for(const t of this.listSceneObjects()){if(t.destroyed||this.isIgnoredPickGo(t))continue;if(!t.getComponent(u))continue;const n=this.projectGo(t),o=se(t);if(n&&e.push({go:t,rect:n,passThrough:o}),this.markerOverlayEnabled&&g(t)){const i=this.markerRectFor(t,n);i&&e.push({go:t,rect:i,passThrough:o})}}return e}markerRectFor(e,t){const n=t??this.projectGo(e);return n?e.getComponent("Transform3D")?{x:n.x+n.width/2-14,y:n.y+n.height/2-14,width:y,height:y}:{x:n.x,y:n.y,width:y,height:y}:null}overlayPoint(e){const t=this.overlay?.canvas;if(!t)return{x:0,y:0};const n=t.getBoundingClientRect();return{x:e.clientX-n.left,y:e.clientY-n.top}}hitTestPointer(e){const t=this.overlayPoint(e),n=this.collectOverlayHits();return function(e,t,n,o){let i=null;const r=o?.coveringRatio??.75;for(let s=0;s<n.length;s++){const a=n[s];if(!oe(a.rect,e,t))continue;const c=Math.max(a.rect.width,0)*Math.max(a.rect.height,0),l=re(a.rect,o?.viewport,r),h=(a.passThrough??0)+(l?1:0),d={id:a.id,score:h,covering:l,area:c,index:s};i&&!ae(d,i)||(i=d)}return i?i.id:null}(t.x,t.y,n.map(e=>({id:e.go,rect:e.rect,passThrough:e.passThrough})),{viewport:this.overlayCss})}redrawOverlay(){const e=this.overlay;if(!e)return;if(!(this.enabled||this.markerOverlayEnabled))return void e.setVisible(!1);const t=this.game.canvas??this.game.scene?.canvas;if(!t)return;const n=e.sync(t);n&&(this.overlayCss=n,e.ctx.clearRect(0,0,n.width,n.height),this.drawMarkers(e.ctx),this.drawSelectionOutline(e.ctx))}drawMarkers(e){if(!this.markerOverlayEnabled)return;const t=new m(e);for(const n of this.listSceneObjects()){if(n.destroyed||this.isIgnoredPickGo(n))continue;const o=g(n);if(!o)continue;const i=this.projectGo(n),r=this.markerRectFor(n,i);r&&(e.save(),e.translate(r.x,r.y),w(t,o,y),e.restore())}}drawSelectionOutline(e){if(!this.enabled||!this.selected||this.selected.destroyed)return;const t=this.projectGo(this.selected);if(!t)return;const n=z(this.game),o=n?this.overlayCss.width/n.width:1;e.save(),e.strokeStyle="#55ffaa",e.lineWidth=Math.max(2,4*(Number.isFinite(o)&&o>0?o:1)),e.strokeRect(t.x,t.y,t.width,t.height),e.restore()}postSetSuccess(e){const t={type:i,enabled:e};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(i,{enabled:e})}attachMarkers(){this.markerOwners.clear();const e=new Map;for(const t of this.listSceneObjects()){if(this.isIgnoredPickGo(t))continue;const n=g(t);n&&(this.markerOwners.add(t.id),e.set(n.componentName,(e.get(n.componentName)??0)+1))}const t=[...e.entries()].map(([e,t])=>({componentName:e,count:t}));this.postMarkerOverlaySuccess(!0,t),this.redrawOverlay()}postMarkerOverlaySuccess(e,t){const n={enabled:e,total:t.reduce((e,t)=>e+t.count,0),markers:t},o={type:d,...n};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(o,this.postMessageOrigin),this.game.emit(d,n)}getSoundSystem(){const e=this.game.getSystem("SoundSystem");return e&&"object"==typeof e&&"muted"in e&&"boolean"==typeof e.muted?e:null}onSelect(e,t){if(!this.enabled)return;this.selected=e,this.redrawOverlay();const n=this.overlayPoint(t),o=(i=n,r=z(this.game),a=this.overlayCss,!r||r.width<=0||r.height<=0||a.width<=0||a.height<=0?{x:i.x,y:i.y}:{x:i.x*(r.width/a.width),y:i.y*(r.height/a.height)});var i,r,a;const c=j(e),l={type:s,snapshot:c,pointer:o};"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(l,this.postMessageOrigin)}findGameObjectById(e){return this.listSceneObjects().find(t=>t.id===e)??null}findGameObjectBySource(e){const t=e.file.trim(),n=(e.anchor??"").trim();if(!n)return null;for(const e of this.listSceneObjects()){const o=L(e);if(!o||o.file!==t)continue;if((o.anchor??e.name)===n)return e}return null}resolveApplyTarget(e){if("number"==typeof e.gameObjectId){const t=this.findGameObjectById(e.gameObjectId);if(t)return t}const t=e.source?.file?.trim(),n=e.source?.anchor?.trim();return t&&n?this.findGameObjectBySource({file:t,anchor:n}):null}handleApplyProperty(e){const t=e.componentName,n=e.path,o="number"==typeof e.gameObjectId,i=Boolean(e.source?.file?.trim())&&Boolean(e.source?.anchor?.trim());if(!o&&!i||"string"!=typeof t||!Array.isArray(n)||0===n.length)return;const r=this.resolveApplyTarget(e);if(!r)return;B(r,t,n,e.value)&&this.selected?.id===r.id&&(this.redrawOverlay(),this.postSnapshotUpdate(r))}postSnapshotUpdate(e){const t=j(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage({type:s,snapshot:t,pointer:null,source:"property-applied"},this.postMessageOrigin)}clearSelectionAndNotify(e){const t=null!=this.selected;this.selected=null,this.redrawOverlay(),t&&this.postGameObjectDeselected(e)}postGameObjectDeselected(e){const t=W(e);"undefined"!=typeof window&&window.parent&&window.parent!==window&&window.parent.postMessage(t,this.postMessageOrigin),this.game.emit(t.type,{reason:e})}};ce=e.__decorate([t.decorators.componentObserver({CombosDevelopmentToolTarget:[]})],ce);var le=ce;Object.assign(le,{packageName:"@combos-fun/plugin-development-tool",packageVersion:"0.0.54"}),exports.COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY=l,exports.COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION=a,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED=c,exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED=s,exports.COMBOS_DEVELOPMENT_TOOL_MARKER_OVERLAY_SUCCESS=d,exports.COMBOS_DEVELOPMENT_TOOL_PICK_MODE_SUCCESS=i,exports.COMBOS_DEVELOPMENT_TOOL_READY="combos-development-tool:ready",exports.COMBOS_DEVELOPMENT_TOOL_REFRESH=r,exports.COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY=h,exports.COMBOS_DEVELOPMENT_TOOL_SET_MUTED="combos-development-tool:set-muted",exports.COMBOS_DEVELOPMENT_TOOL_SET_PICK_MODE=o,exports.COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED="combos-development-tool:state-changed",exports.CombosDevelopmentToolSystem=le,exports.CombosDevelopmentToolTarget=u,exports.DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES=v,exports.MARKER_COMPONENTS=f,exports.MARKER_ICON_SIZE=y,exports.applyPropertyValue=N,exports.applyPropertyWithHooks=B,exports.attachDevelopmentTarget=function(e,t){if(!e||e.destroyed||function(e){return"string"==typeof e.name&&e.name.startsWith("__")}(e)||function(e){return Array.isArray(e.gameObjects)}(e))return e;const n=t.file.trim(),o=t.anchor.trim();if(!n||!o)return e;const i=e.getComponent(u);return i?(r=i.payload?.source,E(r)&&Boolean(r.file.trim())&&Boolean((r.anchor??"").trim())||(i.payload={...i.payload??{},source:{file:n,anchor:o}}),e):(e.addComponent(new u({payload:{source:{file:n,anchor:o}}})),e);var r},exports.buildGameObjectDeselectedPayload=W,exports.buildGameObjectSnapshot=j,exports.drawMarkerIcon=w,exports.isAllowedMessageOrigin=O,exports.isClearSelectionMessage=F,exports.mergeAllowedMessageOrigins=x,exports.readPropertyValue=function(e,t,n){const o=e.getComponent(t);if(!o||!n.length)return;let i=o;for(const e of n){if(null==i||"object"!=typeof i)return;i=i[e]}return i},exports.readSourceAnchor=L,exports.resolveMarkerDef=g,exports.shouldNotifyGameObjectDeselected=V;
|
|
@@ -130,8 +130,10 @@ interface CombosDevelopmentToolSystemParams {
|
|
|
130
130
|
/**
|
|
131
131
|
* **Off** at start. While enabled:
|
|
132
132
|
* - a transparent HTML canvas overlay captures pointer events (game Event / Event3D
|
|
133
|
-
* do not receive the tap);
|
|
133
|
+
* do not receive the tap); pick also listens on `window` capture so a mostly
|
|
134
|
+
* transparent DOM HUD above the canvas cannot swallow the tap;
|
|
134
135
|
* - only nodes with {@link CombosDevelopmentToolTarget} are pickable;
|
|
136
|
+
* - fullscreen / hollow / low-alpha layers lose to content underneath;
|
|
135
137
|
* - selection outline and markers are drawn with the Canvas 2D API (no renderer plugin).
|
|
136
138
|
*
|
|
137
139
|
* Turn on/off via:
|
|
@@ -158,6 +160,7 @@ declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSy
|
|
|
158
160
|
private overlay;
|
|
159
161
|
private overlayCss;
|
|
160
162
|
private pointerDownGoId;
|
|
163
|
+
private pickListening;
|
|
161
164
|
private needsRescan;
|
|
162
165
|
/** Remembered mute when `SoundSystem` is not registered yet. */
|
|
163
166
|
private mutedWithoutSoundSystem;
|
|
@@ -205,6 +208,9 @@ declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSy
|
|
|
205
208
|
/** Re-bind pick targets / markers after dynamic scene changes while active. */
|
|
206
209
|
requestSceneRescan(): void;
|
|
207
210
|
private syncOverlayMode;
|
|
211
|
+
private bindPickListeners;
|
|
212
|
+
private unbindPickListeners;
|
|
213
|
+
private isPickPointInGame;
|
|
208
214
|
private collectGameObjects;
|
|
209
215
|
private listSceneObjects;
|
|
210
216
|
private isIgnoredPickGo;
|
|
@@ -253,14 +253,17 @@ function mergeAllowedMessageOrigins(extra) {
|
|
|
253
253
|
|
|
254
254
|
const OVERLAY_Z_INDEX = '2147483000';
|
|
255
255
|
const OVERLAY_ATTR = 'data-combos-development-tool-overlay';
|
|
256
|
-
function ensureParent(
|
|
257
|
-
const parent =
|
|
256
|
+
function ensureParent(_gameCanvas, overlay) {
|
|
257
|
+
const parent = document.body;
|
|
258
|
+
if (!parent)
|
|
259
|
+
return;
|
|
258
260
|
if (overlay.parentElement !== parent) {
|
|
259
261
|
parent.appendChild(overlay);
|
|
260
262
|
}
|
|
261
263
|
}
|
|
262
264
|
/**
|
|
263
|
-
* Transparent HTML canvas stacked on the game canvas.
|
|
265
|
+
* Transparent HTML canvas stacked on the game canvas and mounted on `document.body`
|
|
266
|
+
* so a transformed canvas parent cannot trap `position: fixed` under a DOM HUD.
|
|
264
267
|
* Pick mode sets `pointer-events: auto` so game Event / Event3D do not receive the tap.
|
|
265
268
|
*/
|
|
266
269
|
function createOverlayCanvas() {
|
|
@@ -988,16 +991,100 @@ function projectGameObjectToScreen(go, opts) {
|
|
|
988
991
|
function rectContains(rect, x, y) {
|
|
989
992
|
return x >= rect.x && y >= rect.y && x <= rect.x + rect.width && y <= rect.y + rect.height;
|
|
990
993
|
}
|
|
991
|
-
/**
|
|
992
|
-
|
|
994
|
+
/** Fraction of the overlay a rect must cover to count as a fullscreen pass-through layer. */
|
|
995
|
+
const COVERING_OVERLAY_RATIO = 0.75;
|
|
996
|
+
/** `Render.alpha` / `Render3D.opacity` at or below this is treated as see-through. */
|
|
997
|
+
const LOW_ALPHA_PASSTHROUGH = 0.35;
|
|
998
|
+
/**
|
|
999
|
+
* Known drawable component names. Duck-typed so this package does not import
|
|
1000
|
+
* renderer plugins. Unknown custom visuals are treated as non-drawable only for
|
|
1001
|
+
* pass-through ranking; they remain pickable when they are the only hit.
|
|
1002
|
+
*/
|
|
1003
|
+
const KNOWN_VISUAL_COMPONENT_NAMES = [
|
|
1004
|
+
'Img',
|
|
1005
|
+
'Sprite',
|
|
1006
|
+
'TilingSprite',
|
|
1007
|
+
'NinePatch',
|
|
1008
|
+
'Text',
|
|
1009
|
+
'Graphics',
|
|
1010
|
+
'SpriteAnimation',
|
|
1011
|
+
'Img3D',
|
|
1012
|
+
'Sprite3D',
|
|
1013
|
+
'TilingSprite3D',
|
|
1014
|
+
'Text3D',
|
|
1015
|
+
'Graphics3D',
|
|
1016
|
+
'Model3D',
|
|
1017
|
+
'SpriteAnimation3D',
|
|
1018
|
+
];
|
|
1019
|
+
function rectOverlapArea(a, b) {
|
|
1020
|
+
const width = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);
|
|
1021
|
+
const height = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);
|
|
1022
|
+
if (width <= 0 || height <= 0)
|
|
1023
|
+
return 0;
|
|
1024
|
+
return width * height;
|
|
1025
|
+
}
|
|
1026
|
+
function isCoveringOverlay(rect, viewport, ratio = COVERING_OVERLAY_RATIO) {
|
|
1027
|
+
if (!viewport || viewport.width <= 0 || viewport.height <= 0) {
|
|
1028
|
+
return false;
|
|
1029
|
+
}
|
|
1030
|
+
const viewportArea = viewport.width * viewport.height;
|
|
1031
|
+
if (viewportArea <= 0)
|
|
1032
|
+
return false;
|
|
1033
|
+
return rectOverlapArea(rect, { x: 0, y: 0, width: viewport.width, height: viewport.height }) / viewportArea >= ratio;
|
|
1034
|
+
}
|
|
1035
|
+
function hasKnownVisual(go) {
|
|
1036
|
+
return KNOWN_VISUAL_COMPONENT_NAMES.some(name => Boolean(go.getComponent(name)));
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Higher = more likely to click through to a target underneath.
|
|
1040
|
+
* Invisible / zero-alpha layers rank above hollow containers and low-alpha dimmers.
|
|
1041
|
+
*/
|
|
1042
|
+
function pickPassThrough(go) {
|
|
1043
|
+
const render = go.getComponent('Render');
|
|
1044
|
+
const render3d = go.getComponent('Render3D');
|
|
1045
|
+
const visible = render?.visible !== false && render3d?.visible !== false;
|
|
1046
|
+
const alpha = Math.min(typeof render?.alpha === 'number' && Number.isFinite(render.alpha) ? render.alpha : 1, typeof render3d?.opacity === 'number' && Number.isFinite(render3d.opacity) ? render3d.opacity : 1);
|
|
1047
|
+
let score = 0;
|
|
1048
|
+
if (!visible || alpha <= 0)
|
|
1049
|
+
score += 2;
|
|
1050
|
+
else if (alpha <= LOW_ALPHA_PASSTHROUGH)
|
|
1051
|
+
score += 1;
|
|
1052
|
+
if (!hasKnownVisual(go))
|
|
1053
|
+
score += 1;
|
|
1054
|
+
return score;
|
|
1055
|
+
}
|
|
1056
|
+
function isBetterHit(next, best) {
|
|
1057
|
+
if (next.score !== best.score)
|
|
1058
|
+
return next.score < best.score;
|
|
1059
|
+
if (next.covering !== best.covering)
|
|
1060
|
+
return !next.covering;
|
|
1061
|
+
if (next.covering) {
|
|
1062
|
+
return next.index < best.index;
|
|
1063
|
+
}
|
|
1064
|
+
if (next.area !== best.area)
|
|
1065
|
+
return next.area < best.area;
|
|
1066
|
+
return next.index > best.index;
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Pick among overlapping targets:
|
|
1070
|
+
* - lower pass-through score wins (content over invisible / hollow / low-alpha);
|
|
1071
|
+
* - a covering fullscreen layer loses to any non-covering hit;
|
|
1072
|
+
* - among covering-only hits, the earlier scene-walk item wins (what's behind);
|
|
1073
|
+
* - among content hits, smallest rect wins, later items win ties (front-most).
|
|
1074
|
+
*/
|
|
1075
|
+
function hitTestRects(x, y, items, opts) {
|
|
993
1076
|
let best = null;
|
|
1077
|
+
const coveringRatio = opts?.coveringRatio ?? COVERING_OVERLAY_RATIO;
|
|
994
1078
|
for (let i = 0; i < items.length; i++) {
|
|
995
1079
|
const item = items[i];
|
|
996
1080
|
if (!rectContains(item.rect, x, y))
|
|
997
1081
|
continue;
|
|
998
1082
|
const area = Math.max(item.rect.width, 0) * Math.max(item.rect.height, 0);
|
|
999
|
-
|
|
1000
|
-
|
|
1083
|
+
const covering = isCoveringOverlay(item.rect, opts?.viewport, coveringRatio);
|
|
1084
|
+
const score = (item.passThrough ?? 0) + (covering ? 1 : 0);
|
|
1085
|
+
const next = { id: item.id, score, covering, area, index: i };
|
|
1086
|
+
if (!best || isBetterHit(next, best)) {
|
|
1087
|
+
best = next;
|
|
1001
1088
|
}
|
|
1002
1089
|
}
|
|
1003
1090
|
return best ? best.id : null;
|
|
@@ -1009,8 +1096,10 @@ const OUTLINE_COLOR = '#55ffaa';
|
|
|
1009
1096
|
/**
|
|
1010
1097
|
* **Off** at start. While enabled:
|
|
1011
1098
|
* - a transparent HTML canvas overlay captures pointer events (game Event / Event3D
|
|
1012
|
-
* do not receive the tap);
|
|
1099
|
+
* do not receive the tap); pick also listens on `window` capture so a mostly
|
|
1100
|
+
* transparent DOM HUD above the canvas cannot swallow the tap;
|
|
1013
1101
|
* - only nodes with {@link CombosDevelopmentToolTarget} are pickable;
|
|
1102
|
+
* - fullscreen / hollow / low-alpha layers lose to content underneath;
|
|
1014
1103
|
* - selection outline and markers are drawn with the Canvas 2D API (no renderer plugin).
|
|
1015
1104
|
*
|
|
1016
1105
|
* Turn on/off via:
|
|
@@ -1038,6 +1127,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1038
1127
|
this.overlay = null;
|
|
1039
1128
|
this.overlayCss = { width: 0, height: 0 };
|
|
1040
1129
|
this.pointerDownGoId = null;
|
|
1130
|
+
this.pickListening = false;
|
|
1041
1131
|
this.needsRescan = false;
|
|
1042
1132
|
/** Remembered mute when `SoundSystem` is not registered yet. */
|
|
1043
1133
|
this.mutedWithoutSoundSystem = false;
|
|
@@ -1103,10 +1193,11 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1103
1193
|
this.requestSceneRescan();
|
|
1104
1194
|
};
|
|
1105
1195
|
this.onPointerDown = (e) => {
|
|
1106
|
-
if (!this.enabled)
|
|
1196
|
+
if (!this.enabled || !this.isPickPointInGame(e))
|
|
1107
1197
|
return;
|
|
1108
1198
|
e.preventDefault();
|
|
1109
1199
|
e.stopPropagation();
|
|
1200
|
+
e.stopImmediatePropagation();
|
|
1110
1201
|
try {
|
|
1111
1202
|
this.overlay?.canvas.setPointerCapture(e.pointerId);
|
|
1112
1203
|
}
|
|
@@ -1119,8 +1210,13 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1119
1210
|
this.onPointerUp = (e) => {
|
|
1120
1211
|
if (!this.enabled)
|
|
1121
1212
|
return;
|
|
1213
|
+
if (!this.isPickPointInGame(e)) {
|
|
1214
|
+
this.pointerDownGoId = null;
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1122
1217
|
e.preventDefault();
|
|
1123
1218
|
e.stopPropagation();
|
|
1219
|
+
e.stopImmediatePropagation();
|
|
1124
1220
|
const hit = this.hitTestPointer(e);
|
|
1125
1221
|
if (hit && hit.id === this.pointerDownGoId) {
|
|
1126
1222
|
this.onSelect(hit, e);
|
|
@@ -1133,10 +1229,6 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1133
1229
|
this.postMessageOrigin = params?.postMessageOrigin ?? '*';
|
|
1134
1230
|
this.allowedMessageOrigins = mergeAllowedMessageOrigins(params?.allowedMessageOrigins);
|
|
1135
1231
|
this.overlay = createOverlayCanvas();
|
|
1136
|
-
if (this.overlay) {
|
|
1137
|
-
this.overlay.canvas.addEventListener('pointerdown', this.onPointerDown);
|
|
1138
|
-
this.overlay.canvas.addEventListener('pointerup', this.onPointerUp);
|
|
1139
|
-
}
|
|
1140
1232
|
if (typeof window !== 'undefined') {
|
|
1141
1233
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_PICK_MODE, this.onWindowSetPickMode);
|
|
1142
1234
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY, this.onWindowSetMarkerOverlay);
|
|
@@ -1152,9 +1244,8 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1152
1244
|
}
|
|
1153
1245
|
}
|
|
1154
1246
|
onDestroy() {
|
|
1247
|
+
this.unbindPickListeners();
|
|
1155
1248
|
if (this.overlay) {
|
|
1156
|
-
this.overlay.canvas.removeEventListener('pointerdown', this.onPointerDown);
|
|
1157
|
-
this.overlay.canvas.removeEventListener('pointerup', this.onPointerUp);
|
|
1158
1249
|
this.overlay.destroy();
|
|
1159
1250
|
this.overlay = null;
|
|
1160
1251
|
}
|
|
@@ -1271,6 +1362,38 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1271
1362
|
const active = this.enabled || this.markerOverlayEnabled;
|
|
1272
1363
|
this.overlay?.setVisible(active);
|
|
1273
1364
|
this.overlay?.setPickEnabled(this.enabled);
|
|
1365
|
+
if (this.enabled) {
|
|
1366
|
+
this.bindPickListeners();
|
|
1367
|
+
}
|
|
1368
|
+
else {
|
|
1369
|
+
this.unbindPickListeners();
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
bindPickListeners() {
|
|
1373
|
+
if (this.pickListening || typeof window === 'undefined')
|
|
1374
|
+
return;
|
|
1375
|
+
window.addEventListener('pointerdown', this.onPointerDown, true);
|
|
1376
|
+
window.addEventListener('pointerup', this.onPointerUp, true);
|
|
1377
|
+
this.pickListening = true;
|
|
1378
|
+
}
|
|
1379
|
+
unbindPickListeners() {
|
|
1380
|
+
if (!this.pickListening || typeof window === 'undefined')
|
|
1381
|
+
return;
|
|
1382
|
+
window.removeEventListener('pointerdown', this.onPointerDown, true);
|
|
1383
|
+
window.removeEventListener('pointerup', this.onPointerUp, true);
|
|
1384
|
+
this.pickListening = false;
|
|
1385
|
+
}
|
|
1386
|
+
isPickPointInGame(e) {
|
|
1387
|
+
const canvas = this.game.canvas ?? this.game.scene?.canvas ?? this.overlay?.canvas;
|
|
1388
|
+
if (!canvas)
|
|
1389
|
+
return false;
|
|
1390
|
+
const rect = canvas.getBoundingClientRect();
|
|
1391
|
+
return (rect.width > 0 &&
|
|
1392
|
+
rect.height > 0 &&
|
|
1393
|
+
e.clientX >= rect.left &&
|
|
1394
|
+
e.clientX <= rect.right &&
|
|
1395
|
+
e.clientY >= rect.top &&
|
|
1396
|
+
e.clientY <= rect.bottom);
|
|
1274
1397
|
}
|
|
1275
1398
|
collectGameObjects(go, out) {
|
|
1276
1399
|
out.push(go);
|
|
@@ -1310,13 +1433,14 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1310
1433
|
if (!go.getComponent(CombosDevelopmentToolTarget))
|
|
1311
1434
|
continue;
|
|
1312
1435
|
const rect = this.projectGo(go);
|
|
1436
|
+
const passThrough = pickPassThrough(go);
|
|
1313
1437
|
if (rect) {
|
|
1314
|
-
hits.push({ go, rect });
|
|
1438
|
+
hits.push({ go, rect, passThrough });
|
|
1315
1439
|
}
|
|
1316
1440
|
if (this.markerOverlayEnabled && resolveMarkerDef(go)) {
|
|
1317
1441
|
const markerRect = this.markerRectFor(go, rect);
|
|
1318
1442
|
if (markerRect) {
|
|
1319
|
-
hits.push({ go, rect: markerRect });
|
|
1443
|
+
hits.push({ go, rect: markerRect, passThrough });
|
|
1320
1444
|
}
|
|
1321
1445
|
}
|
|
1322
1446
|
}
|
|
@@ -1351,7 +1475,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1351
1475
|
hitTestPointer(e) {
|
|
1352
1476
|
const pt = this.overlayPoint(e);
|
|
1353
1477
|
const hits = this.collectOverlayHits();
|
|
1354
|
-
return hitTestRects(pt.x, pt.y, hits.map(h => ({ id: h.go, rect: h.rect })));
|
|
1478
|
+
return hitTestRects(pt.x, pt.y, hits.map(h => ({ id: h.go, rect: h.rect, passThrough: h.passThrough })), { viewport: this.overlayCss });
|
|
1355
1479
|
}
|
|
1356
1480
|
redrawOverlay() {
|
|
1357
1481
|
const overlay = this.overlay;
|
|
@@ -1570,7 +1694,7 @@ var CombosDevelopmentToolSystem$1 = CombosDevelopmentToolSystem;
|
|
|
1570
1694
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
1571
1695
|
Object.assign(CombosDevelopmentToolSystem$1, {
|
|
1572
1696
|
packageName: "@combos-fun/plugin-development-tool",
|
|
1573
|
-
packageVersion: "0.0.
|
|
1697
|
+
packageVersion: "0.0.54",
|
|
1574
1698
|
});
|
|
1575
1699
|
|
|
1576
1700
|
function isInternalEditorGo(go) {
|