@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
package/agent-skill.md
CHANGED
|
@@ -56,13 +56,13 @@ export default defineConfig({
|
|
|
56
56
|
});
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
Do not add `CombosDevelopmentToolTarget` from game code. Opt out of a construct with `// combos-no-target
|
|
59
|
+
Do not add `CombosDevelopmentToolTarget` from game code. Opt out of a construct with `// combos-no-target`.
|
|
60
60
|
|
|
61
61
|
## Runtime behaviour
|
|
62
62
|
|
|
63
|
-
The System starts disabled. In pick mode it shows a full-canvas overlay (`pointer-events: auto`) so game `Event` / `Event3D` do not receive the tap. Targets are hit-tested from engine transforms projected to overlay CSS pixels. Target additions/removals are observed automatically; `requestSceneRescan()` is for parent-driven structural refreshes.
|
|
63
|
+
The System starts disabled. In pick mode it shows a full-canvas overlay (`pointer-events: auto`) so game `Event` / `Event3D` do not receive the tap, and it also listens on `window` capture so a DOM HUD above the canvas cannot swallow the tap. Targets are hit-tested from engine transforms projected to overlay CSS pixels. Overlapping hits prefer content: hollow / invisible / low-alpha nodes and rects covering ≥75% of the overlay lose to a smaller target underneath; two covering layers pick the earlier scene-walk item. Target additions/removals are observed automatically; `requestSceneRescan()` is for parent-driven structural refreshes.
|
|
64
64
|
|
|
65
|
-
2D bounds come from `
|
|
65
|
+
2D bounds come from `Transform2D` size plus `GameObject` hierarchy (position, origin, anchor, scale, rotation). Set `Transform2D.size` when the visual does not match a zero size. 3D bounds project `Transform3D` world position through the active `Renderer3DSystem` camera; a mesh bounding box is used when the Three object is available, otherwise a screen-space pad around the projected point.
|
|
66
66
|
|
|
67
67
|
The marker overlay is independent of pick mode and mute. It currently draws a 28×28 canvas badge only for `Sound`; the owner still needs a Target for selection and persistence (the Vite plugin attaches that Target).
|
|
68
68
|
|
|
@@ -90,8 +90,10 @@ Snapshots expose described schema-backed `fieldDescriptors`, not raw fields. For
|
|
|
90
90
|
|
|
91
91
|
## Common pitfalls
|
|
92
92
|
|
|
93
|
-
- 2D picking needs a positive `
|
|
93
|
+
- 2D picking needs a positive `Transform2D.size` to get a usable hit rect.
|
|
94
94
|
- 3D picking needs `Renderer3DSystem` (for the camera) at runtime; there is no package dependency.
|
|
95
|
+
- Pick ranking is not pixel-perfect: a fullscreen `Img` with `alpha: 1` still counts as drawable even if the PNG is mostly transparent.
|
|
96
|
+
- A covering overlay is still selected when it is the only hit under the pointer.
|
|
95
97
|
- Parent messages require an iframe (`window.parent !== window`) and an allowed origin.
|
|
96
98
|
- Structural replacement needs `refresh`; ordinary Target add/remove does not.
|
|
97
99
|
- Persistence fails if the game build did not run `combosDevelopmentTargetPlugin`.
|
|
@@ -255,14 +255,17 @@ function mergeAllowedMessageOrigins(extra) {
|
|
|
255
255
|
|
|
256
256
|
const OVERLAY_Z_INDEX = '2147483000';
|
|
257
257
|
const OVERLAY_ATTR = 'data-combos-development-tool-overlay';
|
|
258
|
-
function ensureParent(
|
|
259
|
-
const parent =
|
|
258
|
+
function ensureParent(_gameCanvas, overlay) {
|
|
259
|
+
const parent = document.body;
|
|
260
|
+
if (!parent)
|
|
261
|
+
return;
|
|
260
262
|
if (overlay.parentElement !== parent) {
|
|
261
263
|
parent.appendChild(overlay);
|
|
262
264
|
}
|
|
263
265
|
}
|
|
264
266
|
/**
|
|
265
|
-
* Transparent HTML canvas stacked on the game canvas.
|
|
267
|
+
* Transparent HTML canvas stacked on the game canvas and mounted on `document.body`
|
|
268
|
+
* so a transformed canvas parent cannot trap `position: fixed` under a DOM HUD.
|
|
266
269
|
* Pick mode sets `pointer-events: auto` so game Event / Event3D do not receive the tap.
|
|
267
270
|
*/
|
|
268
271
|
function createOverlayCanvas() {
|
|
@@ -498,7 +501,7 @@ function leafDescriptorsFromValue(componentName, options, path, value) {
|
|
|
498
501
|
group: options.group ?? componentName,
|
|
499
502
|
editorKind: mapEditorKind(options, axisType),
|
|
500
503
|
numberMeta: buildNumberMeta(options),
|
|
501
|
-
persistTarget:
|
|
504
|
+
persistTarget: 'component',
|
|
502
505
|
});
|
|
503
506
|
}
|
|
504
507
|
return out;
|
|
@@ -521,7 +524,7 @@ function leafDescriptorsFromValue(componentName, options, path, value) {
|
|
|
521
524
|
editorKind: mapEditorKind(options, valueType),
|
|
522
525
|
enumOptions: options.enumOptions,
|
|
523
526
|
numberMeta: buildNumberMeta(options),
|
|
524
|
-
persistTarget:
|
|
527
|
+
persistTarget: 'component',
|
|
525
528
|
},
|
|
526
529
|
];
|
|
527
530
|
}
|
|
@@ -618,7 +621,10 @@ function syncPhysicsBodyFromTransform(go) {
|
|
|
618
621
|
if (!physics?.body) {
|
|
619
622
|
return;
|
|
620
623
|
}
|
|
621
|
-
const
|
|
624
|
+
const pose = go.getComponent('Transform2D');
|
|
625
|
+
if (!pose)
|
|
626
|
+
return;
|
|
627
|
+
const { x, y } = pose.position;
|
|
622
628
|
if (physics.Body?.setPosition) {
|
|
623
629
|
physics.Body.setPosition(physics.body, { x, y });
|
|
624
630
|
return;
|
|
@@ -631,11 +637,16 @@ function syncMoverOriginFromTransform(go) {
|
|
|
631
637
|
if (!mover) {
|
|
632
638
|
return;
|
|
633
639
|
}
|
|
634
|
-
|
|
635
|
-
|
|
640
|
+
const pose = go.getComponent('Transform2D');
|
|
641
|
+
if (!pose)
|
|
642
|
+
return;
|
|
643
|
+
mover.originX = pose.position.x;
|
|
644
|
+
mover.originY = pose.position.y;
|
|
636
645
|
}
|
|
637
646
|
function applyTransformProperty(go, _comp, path, value) {
|
|
638
|
-
const transform = go.
|
|
647
|
+
const transform = go.getComponent('Transform2D');
|
|
648
|
+
if (!transform)
|
|
649
|
+
return false;
|
|
639
650
|
const transformRecord = transform;
|
|
640
651
|
if (path.length === 1 && path[0] === 'rotation') {
|
|
641
652
|
const next = asNumber(value);
|
|
@@ -693,7 +704,7 @@ function applySoundProperty(_go, comp, path, value) {
|
|
|
693
704
|
return false;
|
|
694
705
|
}
|
|
695
706
|
const APPLY_HOOKS = {
|
|
696
|
-
|
|
707
|
+
Transform2D: applyTransformProperty,
|
|
697
708
|
Text: applyTextProperty,
|
|
698
709
|
Sound: applySoundProperty,
|
|
699
710
|
};
|
|
@@ -977,6 +988,32 @@ function projectTransform3D(transform, camera, css, object3D) {
|
|
|
977
988
|
const scale = Math.max(Math.abs(transform.scaleX ?? 1), Math.abs(transform.scaleY ?? 1), Math.abs(transform.scaleZ ?? 1), 1);
|
|
978
989
|
return padAround(projected, DEFAULT_POINT_EXTENT * scale);
|
|
979
990
|
}
|
|
991
|
+
function asTransform2DPose(value) {
|
|
992
|
+
if (!value || typeof value !== 'object')
|
|
993
|
+
return null;
|
|
994
|
+
const t = value;
|
|
995
|
+
if (!t.position || !t.size)
|
|
996
|
+
return null;
|
|
997
|
+
return {
|
|
998
|
+
position: t.position,
|
|
999
|
+
size: t.size,
|
|
1000
|
+
origin: t.origin ?? { x: 0, y: 0 },
|
|
1001
|
+
anchor: t.anchor ?? { x: 0, y: 0 },
|
|
1002
|
+
scale: t.scale ?? { x: 1, y: 1 },
|
|
1003
|
+
skew: t.skew ?? { x: 0, y: 0 },
|
|
1004
|
+
rotation: t.rotation ?? 0,
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
function pose2DFromGameObject(go) {
|
|
1008
|
+
const pose = asTransform2DPose(go.getComponent('Transform2D'));
|
|
1009
|
+
if (!pose)
|
|
1010
|
+
return null;
|
|
1011
|
+
const parentGo = go.parent && go.parent !== go.scene ? go.parent : null;
|
|
1012
|
+
return {
|
|
1013
|
+
...pose,
|
|
1014
|
+
parent: parentGo ? pose2DFromGameObject(parentGo) : null,
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
980
1017
|
function projectGameObjectToScreen(go, opts) {
|
|
981
1018
|
if (opts.css.width <= 0 || opts.css.height <= 0) {
|
|
982
1019
|
return null;
|
|
@@ -985,21 +1022,108 @@ function projectGameObjectToScreen(go, opts) {
|
|
|
985
1022
|
if (t3d && opts.camera) {
|
|
986
1023
|
return projectTransform3D(t3d, opts.camera, opts.css, opts.object3D);
|
|
987
1024
|
}
|
|
988
|
-
|
|
1025
|
+
const t2d = pose2DFromGameObject(go);
|
|
1026
|
+
if (!t2d)
|
|
1027
|
+
return null;
|
|
1028
|
+
return projectTransform2D(t2d, opts.css, opts.design ?? null);
|
|
989
1029
|
}
|
|
990
1030
|
function rectContains(rect, x, y) {
|
|
991
1031
|
return x >= rect.x && y >= rect.y && x <= rect.x + rect.width && y <= rect.y + rect.height;
|
|
992
1032
|
}
|
|
993
|
-
/**
|
|
994
|
-
|
|
1033
|
+
/** Fraction of the overlay a rect must cover to count as a fullscreen pass-through layer. */
|
|
1034
|
+
const COVERING_OVERLAY_RATIO = 0.75;
|
|
1035
|
+
/** `Render.alpha` / `Render3D.opacity` at or below this is treated as see-through. */
|
|
1036
|
+
const LOW_ALPHA_PASSTHROUGH = 0.35;
|
|
1037
|
+
/**
|
|
1038
|
+
* Known drawable component names. Duck-typed so this package does not import
|
|
1039
|
+
* renderer plugins. Unknown custom visuals are treated as non-drawable only for
|
|
1040
|
+
* pass-through ranking; they remain pickable when they are the only hit.
|
|
1041
|
+
*/
|
|
1042
|
+
const KNOWN_VISUAL_COMPONENT_NAMES = [
|
|
1043
|
+
'Img',
|
|
1044
|
+
'Sprite',
|
|
1045
|
+
'TilingSprite',
|
|
1046
|
+
'NinePatch',
|
|
1047
|
+
'Text',
|
|
1048
|
+
'Graphics',
|
|
1049
|
+
'SpriteAnimation',
|
|
1050
|
+
'Img3D',
|
|
1051
|
+
'Sprite3D',
|
|
1052
|
+
'TilingSprite3D',
|
|
1053
|
+
'Text3D',
|
|
1054
|
+
'Graphics3D',
|
|
1055
|
+
'Model3D',
|
|
1056
|
+
'SpriteAnimation3D',
|
|
1057
|
+
];
|
|
1058
|
+
function rectOverlapArea(a, b) {
|
|
1059
|
+
const width = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);
|
|
1060
|
+
const height = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);
|
|
1061
|
+
if (width <= 0 || height <= 0)
|
|
1062
|
+
return 0;
|
|
1063
|
+
return width * height;
|
|
1064
|
+
}
|
|
1065
|
+
function isCoveringOverlay(rect, viewport, ratio = COVERING_OVERLAY_RATIO) {
|
|
1066
|
+
if (!viewport || viewport.width <= 0 || viewport.height <= 0) {
|
|
1067
|
+
return false;
|
|
1068
|
+
}
|
|
1069
|
+
const viewportArea = viewport.width * viewport.height;
|
|
1070
|
+
if (viewportArea <= 0)
|
|
1071
|
+
return false;
|
|
1072
|
+
return rectOverlapArea(rect, { x: 0, y: 0, width: viewport.width, height: viewport.height }) / viewportArea >= ratio;
|
|
1073
|
+
}
|
|
1074
|
+
function hasKnownVisual(go) {
|
|
1075
|
+
return KNOWN_VISUAL_COMPONENT_NAMES.some(name => Boolean(go.getComponent(name)));
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Higher = more likely to click through to a target underneath.
|
|
1079
|
+
* Invisible / zero-alpha layers rank above hollow containers and low-alpha dimmers.
|
|
1080
|
+
*/
|
|
1081
|
+
function pickPassThrough(go) {
|
|
1082
|
+
const render = go.getComponent('Render');
|
|
1083
|
+
const render3d = go.getComponent('Render3D');
|
|
1084
|
+
const visible = render?.visible !== false && render3d?.visible !== false;
|
|
1085
|
+
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);
|
|
1086
|
+
let score = 0;
|
|
1087
|
+
if (!visible || alpha <= 0)
|
|
1088
|
+
score += 2;
|
|
1089
|
+
else if (alpha <= LOW_ALPHA_PASSTHROUGH)
|
|
1090
|
+
score += 1;
|
|
1091
|
+
if (!hasKnownVisual(go))
|
|
1092
|
+
score += 1;
|
|
1093
|
+
return score;
|
|
1094
|
+
}
|
|
1095
|
+
function isBetterHit(next, best) {
|
|
1096
|
+
if (next.score !== best.score)
|
|
1097
|
+
return next.score < best.score;
|
|
1098
|
+
if (next.covering !== best.covering)
|
|
1099
|
+
return !next.covering;
|
|
1100
|
+
if (next.covering) {
|
|
1101
|
+
return next.index < best.index;
|
|
1102
|
+
}
|
|
1103
|
+
if (next.area !== best.area)
|
|
1104
|
+
return next.area < best.area;
|
|
1105
|
+
return next.index > best.index;
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Pick among overlapping targets:
|
|
1109
|
+
* - lower pass-through score wins (content over invisible / hollow / low-alpha);
|
|
1110
|
+
* - a covering fullscreen layer loses to any non-covering hit;
|
|
1111
|
+
* - among covering-only hits, the earlier scene-walk item wins (what's behind);
|
|
1112
|
+
* - among content hits, smallest rect wins, later items win ties (front-most).
|
|
1113
|
+
*/
|
|
1114
|
+
function hitTestRects(x, y, items, opts) {
|
|
995
1115
|
let best = null;
|
|
1116
|
+
const coveringRatio = opts?.coveringRatio ?? COVERING_OVERLAY_RATIO;
|
|
996
1117
|
for (let i = 0; i < items.length; i++) {
|
|
997
1118
|
const item = items[i];
|
|
998
1119
|
if (!rectContains(item.rect, x, y))
|
|
999
1120
|
continue;
|
|
1000
1121
|
const area = Math.max(item.rect.width, 0) * Math.max(item.rect.height, 0);
|
|
1001
|
-
|
|
1002
|
-
|
|
1122
|
+
const covering = isCoveringOverlay(item.rect, opts?.viewport, coveringRatio);
|
|
1123
|
+
const score = (item.passThrough ?? 0) + (covering ? 1 : 0);
|
|
1124
|
+
const next = { id: item.id, score, covering, area, index: i };
|
|
1125
|
+
if (!best || isBetterHit(next, best)) {
|
|
1126
|
+
best = next;
|
|
1003
1127
|
}
|
|
1004
1128
|
}
|
|
1005
1129
|
return best ? best.id : null;
|
|
@@ -1011,8 +1135,10 @@ const OUTLINE_COLOR = '#55ffaa';
|
|
|
1011
1135
|
/**
|
|
1012
1136
|
* **Off** at start. While enabled:
|
|
1013
1137
|
* - a transparent HTML canvas overlay captures pointer events (game Event / Event3D
|
|
1014
|
-
* do not receive the tap);
|
|
1138
|
+
* do not receive the tap); pick also listens on `window` capture so a mostly
|
|
1139
|
+
* transparent DOM HUD above the canvas cannot swallow the tap;
|
|
1015
1140
|
* - only nodes with {@link CombosDevelopmentToolTarget} are pickable;
|
|
1141
|
+
* - fullscreen / hollow / low-alpha layers lose to content underneath;
|
|
1016
1142
|
* - selection outline and markers are drawn with the Canvas 2D API (no renderer plugin).
|
|
1017
1143
|
*
|
|
1018
1144
|
* Turn on/off via:
|
|
@@ -1040,6 +1166,7 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
1040
1166
|
this.overlay = null;
|
|
1041
1167
|
this.overlayCss = { width: 0, height: 0 };
|
|
1042
1168
|
this.pointerDownGoId = null;
|
|
1169
|
+
this.pickListening = false;
|
|
1043
1170
|
this.needsRescan = false;
|
|
1044
1171
|
/** Remembered mute when `SoundSystem` is not registered yet. */
|
|
1045
1172
|
this.mutedWithoutSoundSystem = false;
|
|
@@ -1105,10 +1232,11 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
1105
1232
|
this.requestSceneRescan();
|
|
1106
1233
|
};
|
|
1107
1234
|
this.onPointerDown = (e) => {
|
|
1108
|
-
if (!this.enabled)
|
|
1235
|
+
if (!this.enabled || !this.isPickPointInGame(e))
|
|
1109
1236
|
return;
|
|
1110
1237
|
e.preventDefault();
|
|
1111
1238
|
e.stopPropagation();
|
|
1239
|
+
e.stopImmediatePropagation();
|
|
1112
1240
|
try {
|
|
1113
1241
|
this.overlay?.canvas.setPointerCapture(e.pointerId);
|
|
1114
1242
|
}
|
|
@@ -1121,8 +1249,13 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
1121
1249
|
this.onPointerUp = (e) => {
|
|
1122
1250
|
if (!this.enabled)
|
|
1123
1251
|
return;
|
|
1252
|
+
if (!this.isPickPointInGame(e)) {
|
|
1253
|
+
this.pointerDownGoId = null;
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1124
1256
|
e.preventDefault();
|
|
1125
1257
|
e.stopPropagation();
|
|
1258
|
+
e.stopImmediatePropagation();
|
|
1126
1259
|
const hit = this.hitTestPointer(e);
|
|
1127
1260
|
if (hit && hit.id === this.pointerDownGoId) {
|
|
1128
1261
|
this.onSelect(hit, e);
|
|
@@ -1135,10 +1268,6 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
1135
1268
|
this.postMessageOrigin = params?.postMessageOrigin ?? '*';
|
|
1136
1269
|
this.allowedMessageOrigins = mergeAllowedMessageOrigins(params?.allowedMessageOrigins);
|
|
1137
1270
|
this.overlay = createOverlayCanvas();
|
|
1138
|
-
if (this.overlay) {
|
|
1139
|
-
this.overlay.canvas.addEventListener('pointerdown', this.onPointerDown);
|
|
1140
|
-
this.overlay.canvas.addEventListener('pointerup', this.onPointerUp);
|
|
1141
|
-
}
|
|
1142
1271
|
if (typeof window !== 'undefined') {
|
|
1143
1272
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_PICK_MODE, this.onWindowSetPickMode);
|
|
1144
1273
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY, this.onWindowSetMarkerOverlay);
|
|
@@ -1154,9 +1283,8 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
1154
1283
|
}
|
|
1155
1284
|
}
|
|
1156
1285
|
onDestroy() {
|
|
1286
|
+
this.unbindPickListeners();
|
|
1157
1287
|
if (this.overlay) {
|
|
1158
|
-
this.overlay.canvas.removeEventListener('pointerdown', this.onPointerDown);
|
|
1159
|
-
this.overlay.canvas.removeEventListener('pointerup', this.onPointerUp);
|
|
1160
1288
|
this.overlay.destroy();
|
|
1161
1289
|
this.overlay = null;
|
|
1162
1290
|
}
|
|
@@ -1273,20 +1401,52 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
1273
1401
|
const active = this.enabled || this.markerOverlayEnabled;
|
|
1274
1402
|
this.overlay?.setVisible(active);
|
|
1275
1403
|
this.overlay?.setPickEnabled(this.enabled);
|
|
1404
|
+
if (this.enabled) {
|
|
1405
|
+
this.bindPickListeners();
|
|
1406
|
+
}
|
|
1407
|
+
else {
|
|
1408
|
+
this.unbindPickListeners();
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
bindPickListeners() {
|
|
1412
|
+
if (this.pickListening || typeof window === 'undefined')
|
|
1413
|
+
return;
|
|
1414
|
+
window.addEventListener('pointerdown', this.onPointerDown, true);
|
|
1415
|
+
window.addEventListener('pointerup', this.onPointerUp, true);
|
|
1416
|
+
this.pickListening = true;
|
|
1417
|
+
}
|
|
1418
|
+
unbindPickListeners() {
|
|
1419
|
+
if (!this.pickListening || typeof window === 'undefined')
|
|
1420
|
+
return;
|
|
1421
|
+
window.removeEventListener('pointerdown', this.onPointerDown, true);
|
|
1422
|
+
window.removeEventListener('pointerup', this.onPointerUp, true);
|
|
1423
|
+
this.pickListening = false;
|
|
1424
|
+
}
|
|
1425
|
+
isPickPointInGame(e) {
|
|
1426
|
+
const canvas = this.game.canvas ?? this.game.scene?.canvas ?? this.overlay?.canvas;
|
|
1427
|
+
if (!canvas)
|
|
1428
|
+
return false;
|
|
1429
|
+
const rect = canvas.getBoundingClientRect();
|
|
1430
|
+
return (rect.width > 0 &&
|
|
1431
|
+
rect.height > 0 &&
|
|
1432
|
+
e.clientX >= rect.left &&
|
|
1433
|
+
e.clientX <= rect.right &&
|
|
1434
|
+
e.clientY >= rect.top &&
|
|
1435
|
+
e.clientY <= rect.bottom);
|
|
1276
1436
|
}
|
|
1277
1437
|
collectGameObjects(go, out) {
|
|
1278
1438
|
out.push(go);
|
|
1279
|
-
for (const
|
|
1280
|
-
this.collectGameObjects(
|
|
1439
|
+
for (const child of go.children) {
|
|
1440
|
+
this.collectGameObjects(child, out);
|
|
1281
1441
|
}
|
|
1282
1442
|
}
|
|
1283
1443
|
listSceneObjects() {
|
|
1284
1444
|
const list = [];
|
|
1285
1445
|
const scene = this.game.scene;
|
|
1286
|
-
if (!scene?.
|
|
1446
|
+
if (!scene?.children)
|
|
1287
1447
|
return list;
|
|
1288
|
-
for (const
|
|
1289
|
-
this.collectGameObjects(
|
|
1448
|
+
for (const child of scene.children) {
|
|
1449
|
+
this.collectGameObjects(child, list);
|
|
1290
1450
|
}
|
|
1291
1451
|
return list;
|
|
1292
1452
|
}
|
|
@@ -1312,13 +1472,14 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
1312
1472
|
if (!go.getComponent(CombosDevelopmentToolTarget))
|
|
1313
1473
|
continue;
|
|
1314
1474
|
const rect = this.projectGo(go);
|
|
1475
|
+
const passThrough = pickPassThrough(go);
|
|
1315
1476
|
if (rect) {
|
|
1316
|
-
hits.push({ go, rect });
|
|
1477
|
+
hits.push({ go, rect, passThrough });
|
|
1317
1478
|
}
|
|
1318
1479
|
if (this.markerOverlayEnabled && resolveMarkerDef(go)) {
|
|
1319
1480
|
const markerRect = this.markerRectFor(go, rect);
|
|
1320
1481
|
if (markerRect) {
|
|
1321
|
-
hits.push({ go, rect: markerRect });
|
|
1482
|
+
hits.push({ go, rect: markerRect, passThrough });
|
|
1322
1483
|
}
|
|
1323
1484
|
}
|
|
1324
1485
|
}
|
|
@@ -1353,7 +1514,7 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
1353
1514
|
hitTestPointer(e) {
|
|
1354
1515
|
const pt = this.overlayPoint(e);
|
|
1355
1516
|
const hits = this.collectOverlayHits();
|
|
1356
|
-
return hitTestRects(pt.x, pt.y, hits.map(h => ({ id: h.go, rect: h.rect })));
|
|
1517
|
+
return hitTestRects(pt.x, pt.y, hits.map(h => ({ id: h.go, rect: h.rect, passThrough: h.passThrough })), { viewport: this.overlayCss });
|
|
1357
1518
|
}
|
|
1358
1519
|
redrawOverlay() {
|
|
1359
1520
|
const overlay = this.overlay;
|
|
@@ -1572,7 +1733,7 @@ var CombosDevelopmentToolSystem = CombosDevelopmentToolSystem$1;
|
|
|
1572
1733
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
1573
1734
|
Object.assign(CombosDevelopmentToolSystem, {
|
|
1574
1735
|
packageName: "@combos-fun/plugin-development-tool",
|
|
1575
|
-
packageVersion: "0.0
|
|
1736
|
+
packageVersion: "0.1.0",
|
|
1576
1737
|
});
|
|
1577
1738
|
|
|
1578
1739
|
function isInternalEditorGo(go) {
|