@combos-fun/plugin-development-tool 0.0.53 → 0.1.0
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 +6 -4
- package/dist/plugin-development-tool.cjs.js +193 -32
- 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 +193 -32
- 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.53"}),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 D(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 _(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=D(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:"component"})}return l}if("object"===r)return[];const c=D(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:"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(..._(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={Transform2D:function(e,t,n,o){const i=e.getComponent("Transform2D");if(!i)return!1;const 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 n=e.getComponent("Transform2D");if(!n)return;const{x:o,y:i}=n.position;t.Body?.setPosition?t.Body.setPosition(t.body,{x:o,y:i}):(t.body.position.x=o,t.body.position.y=i)}(e),function(e){const t=e.getComponent("PlatformerMover");if(!t)return;const n=e.getComponent("Transform2D");n&&(t.originX=n.position.x,t.originY=n.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 z(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 U(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 $(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?e:null}function q(e){const t=e?.getSystem?.("Renderer"),n=t?.application?.screen,o=$(n?.width),i=$(n?.height);if(o&&i)return{width:o,height:i};const r=$(t?.params?.width),s=$(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,z(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=U(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=U(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){const t=function(e){if(!e||"object"!=typeof e)return null;const t=e;return t.position&&t.size?{position:t.position,size:t.size,origin:t.origin??{x:0,y:0},anchor:t.anchor??{x:0,y:0},scale:t.scale??{x:1,y:1},skew:t.skew??{x:0,y:0},rotation:t.rotation??0}:null}(e.getComponent("Transform2D"));if(!t)return null;const n=e.parent&&e.parent!==e.scene?e.parent:null;return{...t,parent:n?ne(n):null}}function oe(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"));if(n&&t.camera)return te(n,t.camera,t.css,t.object3D);const o=ne(e);return o?ee(o,t.css,t.design??null):null}function ie(e,t,n){return t>=e.x&&n>=e.y&&t<=e.x+e.width&&n<=e.y+e.height}const re=["Img","Sprite","TilingSprite","NinePatch","Text","Graphics","SpriteAnimation","Img3D","Sprite3D","TilingSprite3D","Text3D","Graphics3D","Model3D","SpriteAnimation3D"];function se(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 ae(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 re.some(t=>Boolean(e.getComponent(t)))}(e)||(r+=1),r}function ce(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 le=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.children)this.collectGameObjects(n,t)}listSceneObjects(){const e=[],t=this.game.scene;if(!t?.children)return e;for(const n of t.children)this.collectGameObjects(n,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 oe(e,{css:this.overlayCss,design:q(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=ae(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(!ie(a.rect,e,t))continue;const c=Math.max(a.rect.width,0)*Math.max(a.rect.height,0),l=se(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&&!ce(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=q(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=q(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})}};le=e.__decorate([t.decorators.componentObserver({CombosDevelopmentToolTarget:[]})],le);var he=le;Object.assign(he,{packageName:"@combos-fun/plugin-development-tool",packageVersion:"0.1.0"}),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=he,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() {
|
|
@@ -496,7 +499,7 @@ function leafDescriptorsFromValue(componentName, options, path, value) {
|
|
|
496
499
|
group: options.group ?? componentName,
|
|
497
500
|
editorKind: mapEditorKind(options, axisType),
|
|
498
501
|
numberMeta: buildNumberMeta(options),
|
|
499
|
-
persistTarget:
|
|
502
|
+
persistTarget: 'component',
|
|
500
503
|
});
|
|
501
504
|
}
|
|
502
505
|
return out;
|
|
@@ -519,7 +522,7 @@ function leafDescriptorsFromValue(componentName, options, path, value) {
|
|
|
519
522
|
editorKind: mapEditorKind(options, valueType),
|
|
520
523
|
enumOptions: options.enumOptions,
|
|
521
524
|
numberMeta: buildNumberMeta(options),
|
|
522
|
-
persistTarget:
|
|
525
|
+
persistTarget: 'component',
|
|
523
526
|
},
|
|
524
527
|
];
|
|
525
528
|
}
|
|
@@ -616,7 +619,10 @@ function syncPhysicsBodyFromTransform(go) {
|
|
|
616
619
|
if (!physics?.body) {
|
|
617
620
|
return;
|
|
618
621
|
}
|
|
619
|
-
const
|
|
622
|
+
const pose = go.getComponent('Transform2D');
|
|
623
|
+
if (!pose)
|
|
624
|
+
return;
|
|
625
|
+
const { x, y } = pose.position;
|
|
620
626
|
if (physics.Body?.setPosition) {
|
|
621
627
|
physics.Body.setPosition(physics.body, { x, y });
|
|
622
628
|
return;
|
|
@@ -629,11 +635,16 @@ function syncMoverOriginFromTransform(go) {
|
|
|
629
635
|
if (!mover) {
|
|
630
636
|
return;
|
|
631
637
|
}
|
|
632
|
-
|
|
633
|
-
|
|
638
|
+
const pose = go.getComponent('Transform2D');
|
|
639
|
+
if (!pose)
|
|
640
|
+
return;
|
|
641
|
+
mover.originX = pose.position.x;
|
|
642
|
+
mover.originY = pose.position.y;
|
|
634
643
|
}
|
|
635
644
|
function applyTransformProperty(go, _comp, path, value) {
|
|
636
|
-
const transform = go.
|
|
645
|
+
const transform = go.getComponent('Transform2D');
|
|
646
|
+
if (!transform)
|
|
647
|
+
return false;
|
|
637
648
|
const transformRecord = transform;
|
|
638
649
|
if (path.length === 1 && path[0] === 'rotation') {
|
|
639
650
|
const next = asNumber(value);
|
|
@@ -691,7 +702,7 @@ function applySoundProperty(_go, comp, path, value) {
|
|
|
691
702
|
return false;
|
|
692
703
|
}
|
|
693
704
|
const APPLY_HOOKS = {
|
|
694
|
-
|
|
705
|
+
Transform2D: applyTransformProperty,
|
|
695
706
|
Text: applyTextProperty,
|
|
696
707
|
Sound: applySoundProperty,
|
|
697
708
|
};
|
|
@@ -975,6 +986,32 @@ function projectTransform3D(transform, camera, css, object3D) {
|
|
|
975
986
|
const scale = Math.max(Math.abs(transform.scaleX ?? 1), Math.abs(transform.scaleY ?? 1), Math.abs(transform.scaleZ ?? 1), 1);
|
|
976
987
|
return padAround(projected, DEFAULT_POINT_EXTENT * scale);
|
|
977
988
|
}
|
|
989
|
+
function asTransform2DPose(value) {
|
|
990
|
+
if (!value || typeof value !== 'object')
|
|
991
|
+
return null;
|
|
992
|
+
const t = value;
|
|
993
|
+
if (!t.position || !t.size)
|
|
994
|
+
return null;
|
|
995
|
+
return {
|
|
996
|
+
position: t.position,
|
|
997
|
+
size: t.size,
|
|
998
|
+
origin: t.origin ?? { x: 0, y: 0 },
|
|
999
|
+
anchor: t.anchor ?? { x: 0, y: 0 },
|
|
1000
|
+
scale: t.scale ?? { x: 1, y: 1 },
|
|
1001
|
+
skew: t.skew ?? { x: 0, y: 0 },
|
|
1002
|
+
rotation: t.rotation ?? 0,
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
function pose2DFromGameObject(go) {
|
|
1006
|
+
const pose = asTransform2DPose(go.getComponent('Transform2D'));
|
|
1007
|
+
if (!pose)
|
|
1008
|
+
return null;
|
|
1009
|
+
const parentGo = go.parent && go.parent !== go.scene ? go.parent : null;
|
|
1010
|
+
return {
|
|
1011
|
+
...pose,
|
|
1012
|
+
parent: parentGo ? pose2DFromGameObject(parentGo) : null,
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
978
1015
|
function projectGameObjectToScreen(go, opts) {
|
|
979
1016
|
if (opts.css.width <= 0 || opts.css.height <= 0) {
|
|
980
1017
|
return null;
|
|
@@ -983,21 +1020,108 @@ function projectGameObjectToScreen(go, opts) {
|
|
|
983
1020
|
if (t3d && opts.camera) {
|
|
984
1021
|
return projectTransform3D(t3d, opts.camera, opts.css, opts.object3D);
|
|
985
1022
|
}
|
|
986
|
-
|
|
1023
|
+
const t2d = pose2DFromGameObject(go);
|
|
1024
|
+
if (!t2d)
|
|
1025
|
+
return null;
|
|
1026
|
+
return projectTransform2D(t2d, opts.css, opts.design ?? null);
|
|
987
1027
|
}
|
|
988
1028
|
function rectContains(rect, x, y) {
|
|
989
1029
|
return x >= rect.x && y >= rect.y && x <= rect.x + rect.width && y <= rect.y + rect.height;
|
|
990
1030
|
}
|
|
991
|
-
/**
|
|
992
|
-
|
|
1031
|
+
/** Fraction of the overlay a rect must cover to count as a fullscreen pass-through layer. */
|
|
1032
|
+
const COVERING_OVERLAY_RATIO = 0.75;
|
|
1033
|
+
/** `Render.alpha` / `Render3D.opacity` at or below this is treated as see-through. */
|
|
1034
|
+
const LOW_ALPHA_PASSTHROUGH = 0.35;
|
|
1035
|
+
/**
|
|
1036
|
+
* Known drawable component names. Duck-typed so this package does not import
|
|
1037
|
+
* renderer plugins. Unknown custom visuals are treated as non-drawable only for
|
|
1038
|
+
* pass-through ranking; they remain pickable when they are the only hit.
|
|
1039
|
+
*/
|
|
1040
|
+
const KNOWN_VISUAL_COMPONENT_NAMES = [
|
|
1041
|
+
'Img',
|
|
1042
|
+
'Sprite',
|
|
1043
|
+
'TilingSprite',
|
|
1044
|
+
'NinePatch',
|
|
1045
|
+
'Text',
|
|
1046
|
+
'Graphics',
|
|
1047
|
+
'SpriteAnimation',
|
|
1048
|
+
'Img3D',
|
|
1049
|
+
'Sprite3D',
|
|
1050
|
+
'TilingSprite3D',
|
|
1051
|
+
'Text3D',
|
|
1052
|
+
'Graphics3D',
|
|
1053
|
+
'Model3D',
|
|
1054
|
+
'SpriteAnimation3D',
|
|
1055
|
+
];
|
|
1056
|
+
function rectOverlapArea(a, b) {
|
|
1057
|
+
const width = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);
|
|
1058
|
+
const height = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);
|
|
1059
|
+
if (width <= 0 || height <= 0)
|
|
1060
|
+
return 0;
|
|
1061
|
+
return width * height;
|
|
1062
|
+
}
|
|
1063
|
+
function isCoveringOverlay(rect, viewport, ratio = COVERING_OVERLAY_RATIO) {
|
|
1064
|
+
if (!viewport || viewport.width <= 0 || viewport.height <= 0) {
|
|
1065
|
+
return false;
|
|
1066
|
+
}
|
|
1067
|
+
const viewportArea = viewport.width * viewport.height;
|
|
1068
|
+
if (viewportArea <= 0)
|
|
1069
|
+
return false;
|
|
1070
|
+
return rectOverlapArea(rect, { x: 0, y: 0, width: viewport.width, height: viewport.height }) / viewportArea >= ratio;
|
|
1071
|
+
}
|
|
1072
|
+
function hasKnownVisual(go) {
|
|
1073
|
+
return KNOWN_VISUAL_COMPONENT_NAMES.some(name => Boolean(go.getComponent(name)));
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Higher = more likely to click through to a target underneath.
|
|
1077
|
+
* Invisible / zero-alpha layers rank above hollow containers and low-alpha dimmers.
|
|
1078
|
+
*/
|
|
1079
|
+
function pickPassThrough(go) {
|
|
1080
|
+
const render = go.getComponent('Render');
|
|
1081
|
+
const render3d = go.getComponent('Render3D');
|
|
1082
|
+
const visible = render?.visible !== false && render3d?.visible !== false;
|
|
1083
|
+
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);
|
|
1084
|
+
let score = 0;
|
|
1085
|
+
if (!visible || alpha <= 0)
|
|
1086
|
+
score += 2;
|
|
1087
|
+
else if (alpha <= LOW_ALPHA_PASSTHROUGH)
|
|
1088
|
+
score += 1;
|
|
1089
|
+
if (!hasKnownVisual(go))
|
|
1090
|
+
score += 1;
|
|
1091
|
+
return score;
|
|
1092
|
+
}
|
|
1093
|
+
function isBetterHit(next, best) {
|
|
1094
|
+
if (next.score !== best.score)
|
|
1095
|
+
return next.score < best.score;
|
|
1096
|
+
if (next.covering !== best.covering)
|
|
1097
|
+
return !next.covering;
|
|
1098
|
+
if (next.covering) {
|
|
1099
|
+
return next.index < best.index;
|
|
1100
|
+
}
|
|
1101
|
+
if (next.area !== best.area)
|
|
1102
|
+
return next.area < best.area;
|
|
1103
|
+
return next.index > best.index;
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* Pick among overlapping targets:
|
|
1107
|
+
* - lower pass-through score wins (content over invisible / hollow / low-alpha);
|
|
1108
|
+
* - a covering fullscreen layer loses to any non-covering hit;
|
|
1109
|
+
* - among covering-only hits, the earlier scene-walk item wins (what's behind);
|
|
1110
|
+
* - among content hits, smallest rect wins, later items win ties (front-most).
|
|
1111
|
+
*/
|
|
1112
|
+
function hitTestRects(x, y, items, opts) {
|
|
993
1113
|
let best = null;
|
|
1114
|
+
const coveringRatio = opts?.coveringRatio ?? COVERING_OVERLAY_RATIO;
|
|
994
1115
|
for (let i = 0; i < items.length; i++) {
|
|
995
1116
|
const item = items[i];
|
|
996
1117
|
if (!rectContains(item.rect, x, y))
|
|
997
1118
|
continue;
|
|
998
1119
|
const area = Math.max(item.rect.width, 0) * Math.max(item.rect.height, 0);
|
|
999
|
-
|
|
1000
|
-
|
|
1120
|
+
const covering = isCoveringOverlay(item.rect, opts?.viewport, coveringRatio);
|
|
1121
|
+
const score = (item.passThrough ?? 0) + (covering ? 1 : 0);
|
|
1122
|
+
const next = { id: item.id, score, covering, area, index: i };
|
|
1123
|
+
if (!best || isBetterHit(next, best)) {
|
|
1124
|
+
best = next;
|
|
1001
1125
|
}
|
|
1002
1126
|
}
|
|
1003
1127
|
return best ? best.id : null;
|
|
@@ -1009,8 +1133,10 @@ const OUTLINE_COLOR = '#55ffaa';
|
|
|
1009
1133
|
/**
|
|
1010
1134
|
* **Off** at start. While enabled:
|
|
1011
1135
|
* - a transparent HTML canvas overlay captures pointer events (game Event / Event3D
|
|
1012
|
-
* do not receive the tap);
|
|
1136
|
+
* do not receive the tap); pick also listens on `window` capture so a mostly
|
|
1137
|
+
* transparent DOM HUD above the canvas cannot swallow the tap;
|
|
1013
1138
|
* - only nodes with {@link CombosDevelopmentToolTarget} are pickable;
|
|
1139
|
+
* - fullscreen / hollow / low-alpha layers lose to content underneath;
|
|
1014
1140
|
* - selection outline and markers are drawn with the Canvas 2D API (no renderer plugin).
|
|
1015
1141
|
*
|
|
1016
1142
|
* Turn on/off via:
|
|
@@ -1038,6 +1164,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1038
1164
|
this.overlay = null;
|
|
1039
1165
|
this.overlayCss = { width: 0, height: 0 };
|
|
1040
1166
|
this.pointerDownGoId = null;
|
|
1167
|
+
this.pickListening = false;
|
|
1041
1168
|
this.needsRescan = false;
|
|
1042
1169
|
/** Remembered mute when `SoundSystem` is not registered yet. */
|
|
1043
1170
|
this.mutedWithoutSoundSystem = false;
|
|
@@ -1103,10 +1230,11 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1103
1230
|
this.requestSceneRescan();
|
|
1104
1231
|
};
|
|
1105
1232
|
this.onPointerDown = (e) => {
|
|
1106
|
-
if (!this.enabled)
|
|
1233
|
+
if (!this.enabled || !this.isPickPointInGame(e))
|
|
1107
1234
|
return;
|
|
1108
1235
|
e.preventDefault();
|
|
1109
1236
|
e.stopPropagation();
|
|
1237
|
+
e.stopImmediatePropagation();
|
|
1110
1238
|
try {
|
|
1111
1239
|
this.overlay?.canvas.setPointerCapture(e.pointerId);
|
|
1112
1240
|
}
|
|
@@ -1119,8 +1247,13 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1119
1247
|
this.onPointerUp = (e) => {
|
|
1120
1248
|
if (!this.enabled)
|
|
1121
1249
|
return;
|
|
1250
|
+
if (!this.isPickPointInGame(e)) {
|
|
1251
|
+
this.pointerDownGoId = null;
|
|
1252
|
+
return;
|
|
1253
|
+
}
|
|
1122
1254
|
e.preventDefault();
|
|
1123
1255
|
e.stopPropagation();
|
|
1256
|
+
e.stopImmediatePropagation();
|
|
1124
1257
|
const hit = this.hitTestPointer(e);
|
|
1125
1258
|
if (hit && hit.id === this.pointerDownGoId) {
|
|
1126
1259
|
this.onSelect(hit, e);
|
|
@@ -1133,10 +1266,6 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1133
1266
|
this.postMessageOrigin = params?.postMessageOrigin ?? '*';
|
|
1134
1267
|
this.allowedMessageOrigins = mergeAllowedMessageOrigins(params?.allowedMessageOrigins);
|
|
1135
1268
|
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
1269
|
if (typeof window !== 'undefined') {
|
|
1141
1270
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_PICK_MODE, this.onWindowSetPickMode);
|
|
1142
1271
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY, this.onWindowSetMarkerOverlay);
|
|
@@ -1152,9 +1281,8 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1152
1281
|
}
|
|
1153
1282
|
}
|
|
1154
1283
|
onDestroy() {
|
|
1284
|
+
this.unbindPickListeners();
|
|
1155
1285
|
if (this.overlay) {
|
|
1156
|
-
this.overlay.canvas.removeEventListener('pointerdown', this.onPointerDown);
|
|
1157
|
-
this.overlay.canvas.removeEventListener('pointerup', this.onPointerUp);
|
|
1158
1286
|
this.overlay.destroy();
|
|
1159
1287
|
this.overlay = null;
|
|
1160
1288
|
}
|
|
@@ -1271,20 +1399,52 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1271
1399
|
const active = this.enabled || this.markerOverlayEnabled;
|
|
1272
1400
|
this.overlay?.setVisible(active);
|
|
1273
1401
|
this.overlay?.setPickEnabled(this.enabled);
|
|
1402
|
+
if (this.enabled) {
|
|
1403
|
+
this.bindPickListeners();
|
|
1404
|
+
}
|
|
1405
|
+
else {
|
|
1406
|
+
this.unbindPickListeners();
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
bindPickListeners() {
|
|
1410
|
+
if (this.pickListening || typeof window === 'undefined')
|
|
1411
|
+
return;
|
|
1412
|
+
window.addEventListener('pointerdown', this.onPointerDown, true);
|
|
1413
|
+
window.addEventListener('pointerup', this.onPointerUp, true);
|
|
1414
|
+
this.pickListening = true;
|
|
1415
|
+
}
|
|
1416
|
+
unbindPickListeners() {
|
|
1417
|
+
if (!this.pickListening || typeof window === 'undefined')
|
|
1418
|
+
return;
|
|
1419
|
+
window.removeEventListener('pointerdown', this.onPointerDown, true);
|
|
1420
|
+
window.removeEventListener('pointerup', this.onPointerUp, true);
|
|
1421
|
+
this.pickListening = false;
|
|
1422
|
+
}
|
|
1423
|
+
isPickPointInGame(e) {
|
|
1424
|
+
const canvas = this.game.canvas ?? this.game.scene?.canvas ?? this.overlay?.canvas;
|
|
1425
|
+
if (!canvas)
|
|
1426
|
+
return false;
|
|
1427
|
+
const rect = canvas.getBoundingClientRect();
|
|
1428
|
+
return (rect.width > 0 &&
|
|
1429
|
+
rect.height > 0 &&
|
|
1430
|
+
e.clientX >= rect.left &&
|
|
1431
|
+
e.clientX <= rect.right &&
|
|
1432
|
+
e.clientY >= rect.top &&
|
|
1433
|
+
e.clientY <= rect.bottom);
|
|
1274
1434
|
}
|
|
1275
1435
|
collectGameObjects(go, out) {
|
|
1276
1436
|
out.push(go);
|
|
1277
|
-
for (const
|
|
1278
|
-
this.collectGameObjects(
|
|
1437
|
+
for (const child of go.children) {
|
|
1438
|
+
this.collectGameObjects(child, out);
|
|
1279
1439
|
}
|
|
1280
1440
|
}
|
|
1281
1441
|
listSceneObjects() {
|
|
1282
1442
|
const list = [];
|
|
1283
1443
|
const scene = this.game.scene;
|
|
1284
|
-
if (!scene?.
|
|
1444
|
+
if (!scene?.children)
|
|
1285
1445
|
return list;
|
|
1286
|
-
for (const
|
|
1287
|
-
this.collectGameObjects(
|
|
1446
|
+
for (const child of scene.children) {
|
|
1447
|
+
this.collectGameObjects(child, list);
|
|
1288
1448
|
}
|
|
1289
1449
|
return list;
|
|
1290
1450
|
}
|
|
@@ -1310,13 +1470,14 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1310
1470
|
if (!go.getComponent(CombosDevelopmentToolTarget))
|
|
1311
1471
|
continue;
|
|
1312
1472
|
const rect = this.projectGo(go);
|
|
1473
|
+
const passThrough = pickPassThrough(go);
|
|
1313
1474
|
if (rect) {
|
|
1314
|
-
hits.push({ go, rect });
|
|
1475
|
+
hits.push({ go, rect, passThrough });
|
|
1315
1476
|
}
|
|
1316
1477
|
if (this.markerOverlayEnabled && resolveMarkerDef(go)) {
|
|
1317
1478
|
const markerRect = this.markerRectFor(go, rect);
|
|
1318
1479
|
if (markerRect) {
|
|
1319
|
-
hits.push({ go, rect: markerRect });
|
|
1480
|
+
hits.push({ go, rect: markerRect, passThrough });
|
|
1320
1481
|
}
|
|
1321
1482
|
}
|
|
1322
1483
|
}
|
|
@@ -1351,7 +1512,7 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
1351
1512
|
hitTestPointer(e) {
|
|
1352
1513
|
const pt = this.overlayPoint(e);
|
|
1353
1514
|
const hits = this.collectOverlayHits();
|
|
1354
|
-
return hitTestRects(pt.x, pt.y, hits.map(h => ({ id: h.go, rect: h.rect })));
|
|
1515
|
+
return hitTestRects(pt.x, pt.y, hits.map(h => ({ id: h.go, rect: h.rect, passThrough: h.passThrough })), { viewport: this.overlayCss });
|
|
1355
1516
|
}
|
|
1356
1517
|
redrawOverlay() {
|
|
1357
1518
|
const overlay = this.overlay;
|
|
@@ -1570,7 +1731,7 @@ var CombosDevelopmentToolSystem$1 = CombosDevelopmentToolSystem;
|
|
|
1570
1731
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
1571
1732
|
Object.assign(CombosDevelopmentToolSystem$1, {
|
|
1572
1733
|
packageName: "@combos-fun/plugin-development-tool",
|
|
1573
|
-
packageVersion: "0.0
|
|
1734
|
+
packageVersion: "0.1.0",
|
|
1574
1735
|
});
|
|
1575
1736
|
|
|
1576
1737
|
function isInternalEditorGo(go) {
|