@combos-fun/plugin-development-tool 0.0.26 → 0.0.28
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 +24 -0
- package/dist/plugin-development-tool.cjs.js +258 -49
- 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 +115 -18
- package/dist/plugin-development-tool.esm.js +253 -49
- package/dist/plugin-development-tool.esm.js.map +1 -1
- package/package.json +9 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, ComponentParams, System, UpdateParams, ComponentChanged
|
|
1
|
+
import { GameObject, Component, ComponentParams, System, UpdateParams, ComponentChanged } from '@combos-fun/engine';
|
|
2
2
|
|
|
3
3
|
/** Toggle development-tool selection / parent postMessage. Payload: `{ enabled: boolean }`. */
|
|
4
4
|
declare const COMBOS_DEVELOPMENT_TOOL_SET: "combos-development-tool:set";
|
|
@@ -16,12 +16,81 @@ declare const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED: "combos-development
|
|
|
16
16
|
declare const COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY: "combos-development-tool:apply-property";
|
|
17
17
|
/** iframe → parent: game scene bootstrap finished; parent may enable pick mode. */
|
|
18
18
|
declare const COMBOS_DEVELOPMENT_TOOL_READY: "combos-development-tool:ready";
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Parent → iframe: mute or unmute audio when `SoundSystem` is registered. Payload: `{ muted: boolean }`.
|
|
21
|
+
*
|
|
22
|
+
* Note: play / pause / resume are owned by the engine core lifecycle protocol
|
|
23
|
+
* (`combos-game:set-playing` / `combos-game:state-changed`), not this tool.
|
|
24
|
+
*/
|
|
22
25
|
declare const COMBOS_DEVELOPMENT_TOOL_SET_MUTED: "combos-development-tool:set-muted";
|
|
23
|
-
/** iframe → parent (and `game.emit`): current
|
|
26
|
+
/** iframe → parent (and `game.emit`): current mute snapshot after a successful change. */
|
|
24
27
|
declare const COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED: "combos-development-tool:state-changed";
|
|
28
|
+
/**
|
|
29
|
+
* Parent → iframe (also `window` CustomEvent / `game.emit`): toggle the marker
|
|
30
|
+
* overlay — a persistent, clickable icon on every object owning an otherwise
|
|
31
|
+
* invisible registered component (Sound first). Independent of pick mode and
|
|
32
|
+
* mute. Payload: `{ enabled: boolean }`.
|
|
33
|
+
*/
|
|
34
|
+
declare const COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY: "combos-development-tool:set-marker-overlay";
|
|
35
|
+
/**
|
|
36
|
+
* iframe → parent (and `game.emit`): marker overlay finished (re)building.
|
|
37
|
+
* Payload: `{ enabled: boolean, total: number, markers: { componentName, count }[] }`.
|
|
38
|
+
*/
|
|
39
|
+
declare const COMBOS_DEVELOPMENT_TOOL_MARKER_OVERLAY_SUCCESS: "combos-development-tool:marker-overlay-success";
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Marker overlay = a reusable "pin a persistent, clickable icon on every object
|
|
43
|
+
* that owns an otherwise-invisible component" capability. Audio (`Sound`) is the
|
|
44
|
+
* first consumer; register more component kinds below (Physics, Camera, Trigger,
|
|
45
|
+
* timers, spawn points, …) to reuse the exact same layer.
|
|
46
|
+
*/
|
|
47
|
+
/** Glyph drawn inside a marker badge. Extend as new component kinds are added. */
|
|
48
|
+
type MarkerGlyph = 'speaker' | 'dot';
|
|
49
|
+
/** One kind of invisible component the overlay surfaces with a pinned icon. */
|
|
50
|
+
interface MarkerComponentDef {
|
|
51
|
+
/** Engine component name to look for on each GameObject, e.g. `'Sound'`. */
|
|
52
|
+
componentName: string;
|
|
53
|
+
/** Badge fill color, `0xRRGGBB`. */
|
|
54
|
+
badgeColor: number;
|
|
55
|
+
/** Which glyph to draw inside the badge. */
|
|
56
|
+
glyph: MarkerGlyph;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Registered marker kinds, in priority order: a GameObject is marked by the
|
|
60
|
+
* first registered component it owns. For now this is **`Sound` only**; the
|
|
61
|
+
* mechanism is generic (append Physics / Camera / triggers / spawn points later
|
|
62
|
+
* to reuse the same layer) but only audio is wanted right now.
|
|
63
|
+
*/
|
|
64
|
+
declare const MARKER_COMPONENTS: readonly MarkerComponentDef[];
|
|
65
|
+
/** Fixed badge size in the owner's local space. */
|
|
66
|
+
declare const MARKER_ICON_SIZE = 28;
|
|
67
|
+
/**
|
|
68
|
+
* First registered marker def whose component is present on `go`, else `null`.
|
|
69
|
+
* Priority follows {@link MARKER_COMPONENTS} order.
|
|
70
|
+
*/
|
|
71
|
+
declare function resolveMarkerDef(go: Pick<GameObject, 'getComponent'>, registry?: readonly MarkerComponentDef[]): MarkerComponentDef | null;
|
|
72
|
+
/**
|
|
73
|
+
* Minimal subset of the PixiGraphics v8 surface the marker drawing uses. Keeps
|
|
74
|
+
* this module decoupled from the renderer and unit-testable with a mock.
|
|
75
|
+
*/
|
|
76
|
+
interface MarkerGraphicsLike {
|
|
77
|
+
clear(): unknown;
|
|
78
|
+
roundRect(x: number, y: number, width: number, height: number, radius?: number): unknown;
|
|
79
|
+
rect(x: number, y: number, width: number, height: number): unknown;
|
|
80
|
+
circle(x: number, y: number, radius: number): unknown;
|
|
81
|
+
poly(points: number[], close?: boolean): unknown;
|
|
82
|
+
fill(style: {
|
|
83
|
+
color: number;
|
|
84
|
+
alpha?: number;
|
|
85
|
+
}): unknown;
|
|
86
|
+
stroke(style: {
|
|
87
|
+
width: number;
|
|
88
|
+
color: number;
|
|
89
|
+
alpha?: number;
|
|
90
|
+
}): unknown;
|
|
91
|
+
}
|
|
92
|
+
/** Render a full marker (badge + glyph) into `g`, sized to `size` (local units). */
|
|
93
|
+
declare function drawMarkerIcon(g: MarkerGraphicsLike, def: MarkerComponentDef, size?: number): void;
|
|
25
94
|
|
|
26
95
|
/** Default inbound postMessage host suffixes (host + all subdomains). */
|
|
27
96
|
declare const DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES: readonly ["knoffice.tech", "converge.ai"];
|
|
@@ -71,12 +140,14 @@ interface CombosDevelopmentToolSystemParams {
|
|
|
71
140
|
* - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)
|
|
72
141
|
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`
|
|
73
142
|
*
|
|
74
|
-
*
|
|
75
|
-
* - `postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, paused: true })`
|
|
143
|
+
* Mute (independent of pick mode; parent toolbar or in-game debug UI):
|
|
76
144
|
* - `postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET_MUTED, muted: true })`
|
|
77
|
-
* - `game.emit(
|
|
145
|
+
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET_MUTED, { muted: true })` or `.setMuted(true)`
|
|
78
146
|
* Mute applies when `SoundSystem` is registered; otherwise the desired value is remembered until it appears.
|
|
79
|
-
*
|
|
147
|
+
* Emits / posts `COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED` with `{ muted }`.
|
|
148
|
+
*
|
|
149
|
+
* Play / pause / resume are handled by the engine core lifecycle protocol
|
|
150
|
+
* (`combos-game:set-playing` / `combos-game:state-changed`), not this tool.
|
|
80
151
|
*
|
|
81
152
|
* While enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`,
|
|
82
153
|
* or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.
|
|
@@ -98,13 +169,25 @@ declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSy
|
|
|
98
169
|
private lastOutlineBounds;
|
|
99
170
|
/** Remembered mute when `SoundSystem` is not registered yet. */
|
|
100
171
|
private mutedWithoutSoundSystem;
|
|
172
|
+
/**
|
|
173
|
+
* Marker overlay (see {@link markerLayer}): a visual-only icon layer, toggled
|
|
174
|
+
* independently of pick mode + mute. Selection/persistence are NOT handled here
|
|
175
|
+
* — a marked object (e.g. Sound) carries its own `CombosDevelopmentToolTarget`
|
|
176
|
+
* (added by the game code), so it is picked and serialized through the normal
|
|
177
|
+
* Target path. The icon just makes the invisible object visible and, by adding
|
|
178
|
+
* to the owner's rendered bounds, gives its Target pick a clickable hit area.
|
|
179
|
+
*/
|
|
180
|
+
private markerOverlayEnabled;
|
|
181
|
+
private needsMarkerRescan;
|
|
182
|
+
/** ownerGoId → its marker GO (icon child, Graphics only). */
|
|
183
|
+
private readonly markerGoByOwner;
|
|
101
184
|
private readonly onWindowSet;
|
|
102
|
-
private readonly onWindowSetPaused;
|
|
103
185
|
private readonly onWindowSetMuted;
|
|
186
|
+
private readonly onWindowSetMarkerOverlay;
|
|
187
|
+
private readonly onGameSetMarkerOverlay;
|
|
104
188
|
private readonly onWindowMessage;
|
|
105
189
|
private readonly onGameSet;
|
|
106
190
|
private readonly onGameRefresh;
|
|
107
|
-
private readonly onGameSetPaused;
|
|
108
191
|
private readonly onGameSetMuted;
|
|
109
192
|
private readonly onWindowRefresh;
|
|
110
193
|
init(params?: CombosDevelopmentToolSystemParams): void;
|
|
@@ -112,12 +195,19 @@ declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSy
|
|
|
112
195
|
/** Programmatic toggle (same effect as events). */
|
|
113
196
|
setEnabled(on: boolean): void;
|
|
114
197
|
get isEnabled(): boolean;
|
|
115
|
-
/**
|
|
116
|
-
|
|
198
|
+
/**
|
|
199
|
+
* Toggle the marker overlay: pin a persistent icon on every object that owns a
|
|
200
|
+
* registered invisible component ({@link markerLayer}, Sound first). Independent
|
|
201
|
+
* of pick mode / mute. This layer is purely visual — the icon makes the object
|
|
202
|
+
* visible and adds to its rendered bounds so the owner's own
|
|
203
|
+
* `CombosDevelopmentToolTarget` pick gets a clickable hit area. Selecting and
|
|
204
|
+
* persisting edits (e.g. volume) still go through that Target, exactly like any
|
|
205
|
+
* other scene edit, so the object must carry a Target (added by the game code).
|
|
206
|
+
*/
|
|
207
|
+
setMarkerOverlay(on: boolean): void;
|
|
208
|
+
get isMarkerOverlayEnabled(): boolean;
|
|
117
209
|
/** Master mute when `SoundSystem` exists; otherwise the last requested value. */
|
|
118
210
|
get isMuted(): boolean;
|
|
119
|
-
/** Pause or resume the game loop (same as `game.pause()` / `game.resume()`). */
|
|
120
|
-
setPaused(paused: boolean): void;
|
|
121
211
|
/**
|
|
122
212
|
* Mute or unmute audio via `SoundSystem` when registered.
|
|
123
213
|
* No-op on the audio graph if `SoundSystem` is missing; value is remembered for `isMuted`.
|
|
@@ -125,11 +215,12 @@ declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSy
|
|
|
125
215
|
setMuted(muted: boolean): void;
|
|
126
216
|
update(e: UpdateParams): void;
|
|
127
217
|
componentChanged(changed: ComponentChanged): void;
|
|
128
|
-
/** Re-bind pick targets after dynamic scene changes while
|
|
218
|
+
/** Re-bind pick targets / markers after dynamic scene changes while active. */
|
|
129
219
|
requestSceneRescan(): void;
|
|
130
220
|
private attachEditMode;
|
|
131
221
|
private collectGameObjects;
|
|
132
222
|
private isIgnoredPickGo;
|
|
223
|
+
private isMarkerGo;
|
|
133
224
|
private stripGameEvent;
|
|
134
225
|
private restoreDisabledGameEvents;
|
|
135
226
|
private detachAllPicks;
|
|
@@ -146,6 +237,12 @@ declare class CombosDevelopmentToolSystem extends System<CombosDevelopmentToolSy
|
|
|
146
237
|
private releasePick;
|
|
147
238
|
private postSetSuccess;
|
|
148
239
|
private postStateChanged;
|
|
240
|
+
/** (Re)build markers for every object owning a registered marker component. */
|
|
241
|
+
private attachMarkers;
|
|
242
|
+
private createMarker;
|
|
243
|
+
private removeMarker;
|
|
244
|
+
private detachAllMarkers;
|
|
245
|
+
private postMarkerOverlaySuccess;
|
|
149
246
|
private getSoundSystem;
|
|
150
247
|
private ensureOutline;
|
|
151
248
|
private onSelect;
|
|
@@ -202,5 +299,5 @@ declare function buildGameObjectDeselectedPayload(reason: DevelopmentToolDeselec
|
|
|
202
299
|
declare function shouldNotifyGameObjectDeselected(hadSelection: boolean): boolean;
|
|
203
300
|
declare function isClearSelectionMessage(data: unknown): boolean;
|
|
204
301
|
|
|
205
|
-
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET,
|
|
206
|
-
export type { CombosDevelopmentToolSystemParams, CombosDevelopmentToolTargetParams, DevelopmentToolDeselectReason, SceneEditComponentSnapshot, SceneEditGameObjectSnapshot, SceneEditPropertyRef, SceneSourceAnchor };
|
|
302
|
+
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_MARKER_OVERLAY_SUCCESS, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY, COMBOS_DEVELOPMENT_TOOL_SET_MUTED, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED, CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, MARKER_COMPONENTS, MARKER_ICON_SIZE, applyPropertyValue, applyPropertyWithHooks, buildGameObjectDeselectedPayload, buildGameObjectSnapshot, drawMarkerIcon, isAllowedMessageOrigin, isClearSelectionMessage, mergeAllowedMessageOrigins, readPropertyValue, readSourceAnchor, resolveMarkerDef, shouldNotifyGameObjectDeselected };
|
|
303
|
+
export type { CombosDevelopmentToolSystemParams, CombosDevelopmentToolTargetParams, DevelopmentToolDeselectReason, MarkerComponentDef, MarkerGlyph, MarkerGraphicsLike, SceneEditComponentSnapshot, SceneEditGameObjectSnapshot, SceneEditPropertyRef, SceneSourceAnchor };
|
|
@@ -20,12 +20,27 @@ const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED = 'combos-development-tool:g
|
|
|
20
20
|
const COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY = 'combos-development-tool:apply-property';
|
|
21
21
|
/** iframe → parent: game scene bootstrap finished; parent may enable pick mode. */
|
|
22
22
|
const COMBOS_DEVELOPMENT_TOOL_READY = 'combos-development-tool:ready';
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Parent → iframe: mute or unmute audio when `SoundSystem` is registered. Payload: `{ muted: boolean }`.
|
|
25
|
+
*
|
|
26
|
+
* Note: play / pause / resume are owned by the engine core lifecycle protocol
|
|
27
|
+
* (`combos-game:set-playing` / `combos-game:state-changed`), not this tool.
|
|
28
|
+
*/
|
|
26
29
|
const COMBOS_DEVELOPMENT_TOOL_SET_MUTED = 'combos-development-tool:set-muted';
|
|
27
|
-
/** iframe → parent (and `game.emit`): current
|
|
30
|
+
/** iframe → parent (and `game.emit`): current mute snapshot after a successful change. */
|
|
28
31
|
const COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED = 'combos-development-tool:state-changed';
|
|
32
|
+
/**
|
|
33
|
+
* Parent → iframe (also `window` CustomEvent / `game.emit`): toggle the marker
|
|
34
|
+
* overlay — a persistent, clickable icon on every object owning an otherwise
|
|
35
|
+
* invisible registered component (Sound first). Independent of pick mode and
|
|
36
|
+
* mute. Payload: `{ enabled: boolean }`.
|
|
37
|
+
*/
|
|
38
|
+
const COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY = 'combos-development-tool:set-marker-overlay';
|
|
39
|
+
/**
|
|
40
|
+
* iframe → parent (and `game.emit`): marker overlay finished (re)building.
|
|
41
|
+
* Payload: `{ enabled: boolean, total: number, markers: { componentName, count }[] }`.
|
|
42
|
+
*/
|
|
43
|
+
const COMBOS_DEVELOPMENT_TOOL_MARKER_OVERLAY_SUCCESS = 'combos-development-tool:marker-overlay-success';
|
|
29
44
|
|
|
30
45
|
/**
|
|
31
46
|
* Marks a `GameObject` as selectable in editor pick mode. While the development tool is enabled,
|
|
@@ -43,6 +58,73 @@ class CombosDevelopmentToolTarget extends Component {
|
|
|
43
58
|
}
|
|
44
59
|
}
|
|
45
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Registered marker kinds, in priority order: a GameObject is marked by the
|
|
63
|
+
* first registered component it owns. For now this is **`Sound` only**; the
|
|
64
|
+
* mechanism is generic (append Physics / Camera / triggers / spawn points later
|
|
65
|
+
* to reuse the same layer) but only audio is wanted right now.
|
|
66
|
+
*/
|
|
67
|
+
const MARKER_COMPONENTS = [
|
|
68
|
+
{ componentName: 'Sound', badgeColor: 0x8b5cf6, glyph: 'speaker' },
|
|
69
|
+
];
|
|
70
|
+
/** Fixed badge size in the owner's local space. */
|
|
71
|
+
const MARKER_ICON_SIZE = 28;
|
|
72
|
+
/**
|
|
73
|
+
* First registered marker def whose component is present on `go`, else `null`.
|
|
74
|
+
* Priority follows {@link MARKER_COMPONENTS} order.
|
|
75
|
+
*/
|
|
76
|
+
function resolveMarkerDef(go, registry = MARKER_COMPONENTS) {
|
|
77
|
+
for (const def of registry) {
|
|
78
|
+
if (go.getComponent(def.componentName)) {
|
|
79
|
+
return def;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const GLYPH_COLOR = 0xffffff;
|
|
85
|
+
/** Draw the rounded badge background shared by every glyph. */
|
|
86
|
+
function drawBadge(g, def, size) {
|
|
87
|
+
g.clear();
|
|
88
|
+
g.roundRect(0, 0, size, size, size * 0.22);
|
|
89
|
+
g.fill({ color: def.badgeColor, alpha: 0.92 });
|
|
90
|
+
g.roundRect(0, 0, size, size, size * 0.22);
|
|
91
|
+
g.stroke({ width: Math.max(1, size * 0.05), color: 0xffffff, alpha: 0.6 });
|
|
92
|
+
}
|
|
93
|
+
/** A speaker cone + two volume bars, normalized to the `size` box. */
|
|
94
|
+
function drawSpeakerGlyph(g, s) {
|
|
95
|
+
g.poly([
|
|
96
|
+
s * 0.28, s * 0.4,
|
|
97
|
+
s * 0.42, s * 0.4,
|
|
98
|
+
s * 0.55, s * 0.26,
|
|
99
|
+
s * 0.55, s * 0.74,
|
|
100
|
+
s * 0.42, s * 0.6,
|
|
101
|
+
s * 0.28, s * 0.6,
|
|
102
|
+
]);
|
|
103
|
+
g.fill({ color: GLYPH_COLOR, alpha: 0.96 });
|
|
104
|
+
g.rect(s * 0.62, s * 0.44, s * 0.045, s * 0.12);
|
|
105
|
+
g.fill({ color: GLYPH_COLOR, alpha: 0.96 });
|
|
106
|
+
g.rect(s * 0.71, s * 0.39, s * 0.045, s * 0.22);
|
|
107
|
+
g.fill({ color: GLYPH_COLOR, alpha: 0.96 });
|
|
108
|
+
}
|
|
109
|
+
/** Generic fallback glyph for component kinds without a dedicated icon. */
|
|
110
|
+
function drawDotGlyph(g, s) {
|
|
111
|
+
g.circle(s * 0.5, s * 0.5, s * 0.18);
|
|
112
|
+
g.fill({ color: GLYPH_COLOR, alpha: 0.96 });
|
|
113
|
+
}
|
|
114
|
+
/** Render a full marker (badge + glyph) into `g`, sized to `size` (local units). */
|
|
115
|
+
function drawMarkerIcon(g, def, size = MARKER_ICON_SIZE) {
|
|
116
|
+
drawBadge(g, def, size);
|
|
117
|
+
switch (def.glyph) {
|
|
118
|
+
case 'speaker':
|
|
119
|
+
drawSpeakerGlyph(g, size);
|
|
120
|
+
break;
|
|
121
|
+
case 'dot':
|
|
122
|
+
default:
|
|
123
|
+
drawDotGlyph(g, size);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
46
128
|
/** Default inbound postMessage host suffixes (host + all subdomains). */
|
|
47
129
|
const DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES = [
|
|
48
130
|
'knoffice.tech',
|
|
@@ -366,6 +448,7 @@ function isClearSelectionMessage(data) {
|
|
|
366
448
|
}
|
|
367
449
|
|
|
368
450
|
const OUTLINE_GO_NAME = '__combosDevelopmentToolOutline';
|
|
451
|
+
const MARKER_GO_NAME_PREFIX = '__combosDevelopmentToolMarker:';
|
|
369
452
|
/**
|
|
370
453
|
* **Off** at start. While enabled:
|
|
371
454
|
* - soft-disables game `Event` hit targets (`container.interactive = false`, restored on disable);
|
|
@@ -376,12 +459,14 @@ const OUTLINE_GO_NAME = '__combosDevelopmentToolOutline';
|
|
|
376
459
|
* - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)
|
|
377
460
|
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`
|
|
378
461
|
*
|
|
379
|
-
*
|
|
380
|
-
* - `postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, paused: true })`
|
|
462
|
+
* Mute (independent of pick mode; parent toolbar or in-game debug UI):
|
|
381
463
|
* - `postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET_MUTED, muted: true })`
|
|
382
|
-
* - `game.emit(
|
|
464
|
+
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET_MUTED, { muted: true })` or `.setMuted(true)`
|
|
383
465
|
* Mute applies when `SoundSystem` is registered; otherwise the desired value is remembered until it appears.
|
|
384
|
-
*
|
|
466
|
+
* Emits / posts `COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED` with `{ muted }`.
|
|
467
|
+
*
|
|
468
|
+
* Play / pause / resume are handled by the engine core lifecycle protocol
|
|
469
|
+
* (`combos-game:set-playing` / `combos-game:state-changed`), not this tool.
|
|
385
470
|
*
|
|
386
471
|
* While enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`,
|
|
387
472
|
* or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.
|
|
@@ -404,24 +489,41 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
404
489
|
this.lastOutlineBounds = null;
|
|
405
490
|
/** Remembered mute when `SoundSystem` is not registered yet. */
|
|
406
491
|
this.mutedWithoutSoundSystem = false;
|
|
492
|
+
/**
|
|
493
|
+
* Marker overlay (see {@link markerLayer}): a visual-only icon layer, toggled
|
|
494
|
+
* independently of pick mode + mute. Selection/persistence are NOT handled here
|
|
495
|
+
* — a marked object (e.g. Sound) carries its own `CombosDevelopmentToolTarget`
|
|
496
|
+
* (added by the game code), so it is picked and serialized through the normal
|
|
497
|
+
* Target path. The icon just makes the invisible object visible and, by adding
|
|
498
|
+
* to the owner's rendered bounds, gives its Target pick a clickable hit area.
|
|
499
|
+
*/
|
|
500
|
+
this.markerOverlayEnabled = false;
|
|
501
|
+
this.needsMarkerRescan = false;
|
|
502
|
+
/** ownerGoId → its marker GO (icon child, Graphics only). */
|
|
503
|
+
this.markerGoByOwner = new Map();
|
|
407
504
|
this.onWindowSet = (e) => {
|
|
408
505
|
const d = e.detail;
|
|
409
506
|
if (d && typeof d.enabled === 'boolean') {
|
|
410
507
|
this.setEnabled(d.enabled);
|
|
411
508
|
}
|
|
412
509
|
};
|
|
413
|
-
this.onWindowSetPaused = (e) => {
|
|
414
|
-
const d = e.detail;
|
|
415
|
-
if (d && typeof d.paused === 'boolean') {
|
|
416
|
-
this.setPaused(d.paused);
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
510
|
this.onWindowSetMuted = (e) => {
|
|
420
511
|
const d = e.detail;
|
|
421
512
|
if (d && typeof d.muted === 'boolean') {
|
|
422
513
|
this.setMuted(d.muted);
|
|
423
514
|
}
|
|
424
515
|
};
|
|
516
|
+
this.onWindowSetMarkerOverlay = (e) => {
|
|
517
|
+
const d = e.detail;
|
|
518
|
+
if (d && typeof d.enabled === 'boolean') {
|
|
519
|
+
this.setMarkerOverlay(d.enabled);
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
this.onGameSetMarkerOverlay = (payload) => {
|
|
523
|
+
if (payload && typeof payload.enabled === 'boolean') {
|
|
524
|
+
this.setMarkerOverlay(payload.enabled);
|
|
525
|
+
}
|
|
526
|
+
};
|
|
425
527
|
this.onWindowMessage = (e) => {
|
|
426
528
|
if (!isAllowedMessageOrigin(e.origin, this.allowedMessageOrigins)) {
|
|
427
529
|
return;
|
|
@@ -432,12 +534,13 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
432
534
|
if (d.type === COMBOS_DEVELOPMENT_TOOL_SET && typeof d.enabled === 'boolean') {
|
|
433
535
|
this.setEnabled(d.enabled);
|
|
434
536
|
}
|
|
435
|
-
else if (d.type === COMBOS_DEVELOPMENT_TOOL_SET_PAUSED && typeof d.paused === 'boolean') {
|
|
436
|
-
this.setPaused(d.paused);
|
|
437
|
-
}
|
|
438
537
|
else if (d.type === COMBOS_DEVELOPMENT_TOOL_SET_MUTED && typeof d.muted === 'boolean') {
|
|
439
538
|
this.setMuted(d.muted);
|
|
440
539
|
}
|
|
540
|
+
else if (d.type === COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY &&
|
|
541
|
+
typeof d.enabled === 'boolean') {
|
|
542
|
+
this.setMarkerOverlay(d.enabled);
|
|
543
|
+
}
|
|
441
544
|
else if (d.type === COMBOS_DEVELOPMENT_TOOL_REFRESH) {
|
|
442
545
|
this.requestSceneRescan();
|
|
443
546
|
}
|
|
@@ -456,11 +559,6 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
456
559
|
this.onGameRefresh = () => {
|
|
457
560
|
this.requestSceneRescan();
|
|
458
561
|
};
|
|
459
|
-
this.onGameSetPaused = (payload) => {
|
|
460
|
-
if (payload && typeof payload.paused === 'boolean') {
|
|
461
|
-
this.setPaused(payload.paused);
|
|
462
|
-
}
|
|
463
|
-
};
|
|
464
562
|
this.onGameSetMuted = (payload) => {
|
|
465
563
|
if (payload && typeof payload.muted === 'boolean') {
|
|
466
564
|
this.setMuted(payload.muted);
|
|
@@ -476,14 +574,14 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
476
574
|
this.allowedMessageOrigins = mergeAllowedMessageOrigins(params?.allowedMessageOrigins);
|
|
477
575
|
if (typeof window !== 'undefined') {
|
|
478
576
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
|
|
479
|
-
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, this.onWindowSetPaused);
|
|
480
577
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_MUTED, this.onWindowSetMuted);
|
|
578
|
+
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY, this.onWindowSetMarkerOverlay);
|
|
481
579
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);
|
|
482
580
|
window.addEventListener('message', this.onWindowMessage);
|
|
483
581
|
}
|
|
484
582
|
this.game.on(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
|
|
485
|
-
this.game.on(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, this.onGameSetPaused);
|
|
486
583
|
this.game.on(COMBOS_DEVELOPMENT_TOOL_SET_MUTED, this.onGameSetMuted);
|
|
584
|
+
this.game.on(COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY, this.onGameSetMarkerOverlay);
|
|
487
585
|
this.game.on(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
488
586
|
if (this.enabled) {
|
|
489
587
|
this.needsRescan = true;
|
|
@@ -492,16 +590,17 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
492
590
|
onDestroy() {
|
|
493
591
|
if (typeof window !== 'undefined') {
|
|
494
592
|
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
|
|
495
|
-
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, this.onWindowSetPaused);
|
|
496
593
|
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET_MUTED, this.onWindowSetMuted);
|
|
594
|
+
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY, this.onWindowSetMarkerOverlay);
|
|
497
595
|
window.removeEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);
|
|
498
596
|
window.removeEventListener('message', this.onWindowMessage);
|
|
499
597
|
}
|
|
500
598
|
this.game.off(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
|
|
501
|
-
this.game.off(COMBOS_DEVELOPMENT_TOOL_SET_PAUSED, this.onGameSetPaused);
|
|
502
599
|
this.game.off(COMBOS_DEVELOPMENT_TOOL_SET_MUTED, this.onGameSetMuted);
|
|
600
|
+
this.game.off(COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY, this.onGameSetMarkerOverlay);
|
|
503
601
|
this.game.off(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
504
602
|
this.detachAllPicks();
|
|
603
|
+
this.detachAllMarkers();
|
|
505
604
|
this.restoreDisabledGameEvents();
|
|
506
605
|
this.clearSelectionAndNotify('pick-disabled');
|
|
507
606
|
}
|
|
@@ -523,9 +622,34 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
523
622
|
get isEnabled() {
|
|
524
623
|
return this.enabled;
|
|
525
624
|
}
|
|
526
|
-
/**
|
|
527
|
-
|
|
528
|
-
|
|
625
|
+
/**
|
|
626
|
+
* Toggle the marker overlay: pin a persistent icon on every object that owns a
|
|
627
|
+
* registered invisible component ({@link markerLayer}, Sound first). Independent
|
|
628
|
+
* of pick mode / mute. This layer is purely visual — the icon makes the object
|
|
629
|
+
* visible and adds to its rendered bounds so the owner's own
|
|
630
|
+
* `CombosDevelopmentToolTarget` pick gets a clickable hit area. Selecting and
|
|
631
|
+
* persisting edits (e.g. volume) still go through that Target, exactly like any
|
|
632
|
+
* other scene edit, so the object must carry a Target (added by the game code).
|
|
633
|
+
*/
|
|
634
|
+
setMarkerOverlay(on) {
|
|
635
|
+
if (this.markerOverlayEnabled === on)
|
|
636
|
+
return;
|
|
637
|
+
this.markerOverlayEnabled = on;
|
|
638
|
+
if (on) {
|
|
639
|
+
// `attachMarkers` requests the pick rescan itself, once the icons exist.
|
|
640
|
+
this.needsMarkerRescan = true;
|
|
641
|
+
}
|
|
642
|
+
else {
|
|
643
|
+
this.detachAllMarkers();
|
|
644
|
+
this.postMarkerOverlaySuccess(false, []);
|
|
645
|
+
// Shrink owners' pick hit areas back now that the icons are gone.
|
|
646
|
+
if (this.enabled) {
|
|
647
|
+
this.needsRescan = true;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
get isMarkerOverlayEnabled() {
|
|
652
|
+
return this.markerOverlayEnabled;
|
|
529
653
|
}
|
|
530
654
|
/** Master mute when `SoundSystem` exists; otherwise the last requested value. */
|
|
531
655
|
get isMuted() {
|
|
@@ -535,18 +659,6 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
535
659
|
}
|
|
536
660
|
return this.mutedWithoutSoundSystem;
|
|
537
661
|
}
|
|
538
|
-
/** Pause or resume the game loop (same as `game.pause()` / `game.resume()`). */
|
|
539
|
-
setPaused(paused) {
|
|
540
|
-
if (paused) {
|
|
541
|
-
if (this.game.playing) {
|
|
542
|
-
this.game.pause();
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
else if (!this.game.playing) {
|
|
546
|
-
this.game.resume();
|
|
547
|
-
}
|
|
548
|
-
this.postStateChanged();
|
|
549
|
-
}
|
|
550
662
|
/**
|
|
551
663
|
* Mute or unmute audio via `SoundSystem` when registered.
|
|
552
664
|
* No-op on the audio graph if `SoundSystem` is missing; value is remembered for `isMuted`.
|
|
@@ -567,11 +679,26 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
567
679
|
this.attachEditMode();
|
|
568
680
|
this.postSetSuccess(true);
|
|
569
681
|
}
|
|
682
|
+
// Attaching markers is deferred to run *after* the pick rescan above so that a
|
|
683
|
+
// newly drawn icon's rebuild lands on a later frame (see `attachMarkers`): the
|
|
684
|
+
// icon child needs a rendered container before it contributes to the owner's
|
|
685
|
+
// bounds, and only then does the owner's Target pick get a hit area over it.
|
|
686
|
+
if (this.markerOverlayEnabled && this.needsMarkerRescan) {
|
|
687
|
+
this.needsMarkerRescan = false;
|
|
688
|
+
this.attachMarkers();
|
|
689
|
+
}
|
|
570
690
|
for (const go of [...this.tapOwners.values()]) {
|
|
571
691
|
if (go.destroyed) {
|
|
572
692
|
this.releasePick(go);
|
|
573
693
|
}
|
|
574
694
|
}
|
|
695
|
+
// Drop markers whose owner disappeared while the overlay is on.
|
|
696
|
+
for (const [ownerId, marker] of [...this.markerGoByOwner.entries()]) {
|
|
697
|
+
const owner = this.findGameObjectById(ownerId);
|
|
698
|
+
if (!owner || owner.destroyed || marker.destroyed) {
|
|
699
|
+
this.removeMarker(ownerId);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
575
702
|
if (!this.enabled || !this.selected || !this.outlineGo)
|
|
576
703
|
return;
|
|
577
704
|
this.updateSelectionOutline();
|
|
@@ -593,11 +720,14 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
593
720
|
}
|
|
594
721
|
}
|
|
595
722
|
}
|
|
596
|
-
/** Re-bind pick targets after dynamic scene changes while
|
|
723
|
+
/** Re-bind pick targets / markers after dynamic scene changes while active. */
|
|
597
724
|
requestSceneRescan() {
|
|
598
|
-
if (
|
|
599
|
-
|
|
600
|
-
|
|
725
|
+
if (this.enabled) {
|
|
726
|
+
this.needsRescan = true;
|
|
727
|
+
}
|
|
728
|
+
if (this.markerOverlayEnabled) {
|
|
729
|
+
this.needsMarkerRescan = true;
|
|
730
|
+
}
|
|
601
731
|
}
|
|
602
732
|
attachEditMode() {
|
|
603
733
|
this.detachAllPicks();
|
|
@@ -625,7 +755,10 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
625
755
|
}
|
|
626
756
|
}
|
|
627
757
|
isIgnoredPickGo(go) {
|
|
628
|
-
return go.name === OUTLINE_GO_NAME || go === this.outlineGo;
|
|
758
|
+
return go.name === OUTLINE_GO_NAME || go === this.outlineGo || this.isMarkerGo(go);
|
|
759
|
+
}
|
|
760
|
+
isMarkerGo(go) {
|
|
761
|
+
return typeof go.name === 'string' && go.name.startsWith(MARKER_GO_NAME_PREFIX);
|
|
629
762
|
}
|
|
630
763
|
stripGameEvent(go) {
|
|
631
764
|
if (this.disabledGameEventGoIds.has(go.id))
|
|
@@ -831,7 +964,6 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
831
964
|
}
|
|
832
965
|
postStateChanged() {
|
|
833
966
|
const state = {
|
|
834
|
-
paused: this.isPaused,
|
|
835
967
|
muted: this.isMuted,
|
|
836
968
|
};
|
|
837
969
|
const payload = {
|
|
@@ -843,6 +975,78 @@ let CombosDevelopmentToolSystem = class CombosDevelopmentToolSystem extends Syst
|
|
|
843
975
|
}
|
|
844
976
|
this.game.emit(COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED, state);
|
|
845
977
|
}
|
|
978
|
+
/** (Re)build markers for every object owning a registered marker component. */
|
|
979
|
+
attachMarkers() {
|
|
980
|
+
this.detachAllMarkers();
|
|
981
|
+
const list = [];
|
|
982
|
+
for (const tr of this.game.scene.transform.children) {
|
|
983
|
+
this.collectGameObjects(tr.gameObject, list);
|
|
984
|
+
}
|
|
985
|
+
const counts = new Map();
|
|
986
|
+
for (const go of list) {
|
|
987
|
+
if (this.isIgnoredPickGo(go))
|
|
988
|
+
continue;
|
|
989
|
+
const def = resolveMarkerDef(go);
|
|
990
|
+
if (!def)
|
|
991
|
+
continue;
|
|
992
|
+
this.createMarker(go, def);
|
|
993
|
+
counts.set(def.componentName, (counts.get(def.componentName) ?? 0) + 1);
|
|
994
|
+
}
|
|
995
|
+
const markers = [...counts.entries()].map(([componentName, count]) => ({
|
|
996
|
+
componentName,
|
|
997
|
+
count,
|
|
998
|
+
}));
|
|
999
|
+
this.postMarkerOverlaySuccess(true, markers);
|
|
1000
|
+
// Rebuild picks next frame: the icons just added need a rendered container
|
|
1001
|
+
// before they enlarge their owners' bounds into a clickable hit area. Runs on
|
|
1002
|
+
// a later frame because the pick rescan block already executed above.
|
|
1003
|
+
if (this.enabled) {
|
|
1004
|
+
this.needsRescan = true;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
createMarker(owner, def) {
|
|
1008
|
+
if (this.markerGoByOwner.has(owner.id))
|
|
1009
|
+
return;
|
|
1010
|
+
const bounds = this.resolvePickBounds(owner);
|
|
1011
|
+
const marker = new GameObject(MARKER_GO_NAME_PREFIX + owner.id, {
|
|
1012
|
+
size: { width: MARKER_ICON_SIZE, height: MARKER_ICON_SIZE },
|
|
1013
|
+
position: { x: bounds.x, y: bounds.y },
|
|
1014
|
+
origin: { x: 0, y: 0 },
|
|
1015
|
+
});
|
|
1016
|
+
const gfx = marker.addComponent(new Graphics());
|
|
1017
|
+
if (gfx?.graphics) {
|
|
1018
|
+
drawMarkerIcon(gfx.graphics, def, MARKER_ICON_SIZE);
|
|
1019
|
+
}
|
|
1020
|
+
owner.addChild(marker);
|
|
1021
|
+
this.markerGoByOwner.set(owner.id, marker);
|
|
1022
|
+
}
|
|
1023
|
+
removeMarker(ownerId) {
|
|
1024
|
+
const marker = this.markerGoByOwner.get(ownerId);
|
|
1025
|
+
if (!marker)
|
|
1026
|
+
return;
|
|
1027
|
+
this.markerGoByOwner.delete(ownerId);
|
|
1028
|
+
if (!marker.destroyed) {
|
|
1029
|
+
marker.destroy();
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
detachAllMarkers() {
|
|
1033
|
+
for (const ownerId of [...this.markerGoByOwner.keys()]) {
|
|
1034
|
+
this.removeMarker(ownerId);
|
|
1035
|
+
}
|
|
1036
|
+
this.markerGoByOwner.clear();
|
|
1037
|
+
}
|
|
1038
|
+
postMarkerOverlaySuccess(enabled, markers) {
|
|
1039
|
+
const total = markers.reduce((sum, m) => sum + m.count, 0);
|
|
1040
|
+
const state = { enabled, total, markers };
|
|
1041
|
+
const payload = {
|
|
1042
|
+
type: COMBOS_DEVELOPMENT_TOOL_MARKER_OVERLAY_SUCCESS,
|
|
1043
|
+
...state,
|
|
1044
|
+
};
|
|
1045
|
+
if (typeof window !== 'undefined' && window.parent && window.parent !== window) {
|
|
1046
|
+
window.parent.postMessage(payload, this.postMessageOrigin);
|
|
1047
|
+
}
|
|
1048
|
+
this.game.emit(COMBOS_DEVELOPMENT_TOOL_MARKER_OVERLAY_SUCCESS, state);
|
|
1049
|
+
}
|
|
846
1050
|
getSoundSystem() {
|
|
847
1051
|
const system = this.game.getSystem('SoundSystem');
|
|
848
1052
|
if (!system ||
|
|
@@ -1029,8 +1233,8 @@ var CombosDevelopmentToolSystem$1 = CombosDevelopmentToolSystem;
|
|
|
1029
1233
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
1030
1234
|
Object.assign(CombosDevelopmentToolSystem$1, {
|
|
1031
1235
|
packageName: "@combos-fun/plugin-development-tool",
|
|
1032
|
-
packageVersion: "0.0.
|
|
1236
|
+
packageVersion: "0.0.27",
|
|
1033
1237
|
});
|
|
1034
1238
|
|
|
1035
|
-
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET,
|
|
1239
|
+
export { COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY, COMBOS_DEVELOPMENT_TOOL_CLEAR_SELECTION, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_DESELECTED, COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED, COMBOS_DEVELOPMENT_TOOL_MARKER_OVERLAY_SUCCESS, COMBOS_DEVELOPMENT_TOOL_READY, COMBOS_DEVELOPMENT_TOOL_REFRESH, COMBOS_DEVELOPMENT_TOOL_SET, COMBOS_DEVELOPMENT_TOOL_SET_MARKER_OVERLAY, COMBOS_DEVELOPMENT_TOOL_SET_MUTED, COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, COMBOS_DEVELOPMENT_TOOL_STATE_CHANGED, CombosDevelopmentToolSystem$1 as CombosDevelopmentToolSystem, CombosDevelopmentToolTarget, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, MARKER_COMPONENTS, MARKER_ICON_SIZE, applyPropertyValue, applyPropertyWithHooks, buildGameObjectDeselectedPayload, buildGameObjectSnapshot, drawMarkerIcon, isAllowedMessageOrigin, isClearSelectionMessage, mergeAllowedMessageOrigins, readPropertyValue, readSourceAnchor, resolveMarkerDef, shouldNotifyGameObjectDeselected };
|
|
1036
1240
|
//# sourceMappingURL=plugin-development-tool.esm.js.map
|