Skip to content

Commit 04710f9

Browse files
SnaveSutitgitbutler-client
authored andcommitted
🚧 Interaction Nodes
1 parent 33b9fe0 commit 04710f9

11 files changed

Lines changed: 617 additions & 16 deletions

File tree

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"description": "Effortlessly craft complex animations for Minecraft: Java Edition",
77
"version": "1.10.0-beta.5",
88
"min_blockbench_version": "5.1.4",
9-
"max_blockbench_version": "5.1.4",
109
"variant": "desktop",
1110
"tags": [
1211
"Minecraft: Java Edition",
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<script lang="ts" module>
2+
import { type Observable } from 'svelte-observable-store'
3+
import CheckBox from '../../svelteComponents/dialogItems/checkbox.svelte'
4+
import CodeInput from '../../svelteComponents/dialogItems/codeInput.svelte'
5+
import { localize } from '../../util/lang'
6+
</script>
7+
8+
<script lang="ts">
9+
const PLUGIN_MODE = !!Project?.animated_java?.enable_plugin_mode
10+
11+
export let response: Observable<boolean>
12+
export let onSummonFunction: Observable<string>
13+
export let onInteractionFunction: Observable<string>
14+
export let onAttackFunction: Observable<string>
15+
export let onRemoveFunction: Observable<string>
16+
export let onTickFunction: Observable<string>
17+
</script>
18+
19+
<div class="locator-config">
20+
{#if PLUGIN_MODE}
21+
{#each localize('dialog.interaction_config.plugin_mode_warning').split('\n') as line}
22+
<p>{line}</p>
23+
{/each}
24+
{:else}
25+
<CheckBox
26+
label={localize('dialog.interaction_config.response.title')}
27+
tooltip={localize('dialog.interaction_config.response.description')}
28+
bind:checked={response}
29+
defaultValue={false}
30+
/>
31+
32+
<CodeInput
33+
label={localize('dialog.interaction_config.on_summon_function.title')}
34+
tooltip={localize('dialog.interaction_config.on_summon_function.description')}
35+
bind:value={onSummonFunction}
36+
defaultValue=""
37+
syntax="mcfunction"
38+
/>
39+
40+
<CodeInput
41+
label={localize('dialog.interaction_config.on_interaction_function.title')}
42+
tooltip={localize('dialog.interaction_config.on_interaction_function.description')}
43+
bind:value={onInteractionFunction}
44+
defaultValue=""
45+
syntax="mcfunction"
46+
/>
47+
48+
<CodeInput
49+
label={localize('dialog.interaction_config.on_attack_function.title')}
50+
tooltip={localize('dialog.interaction_config.on_attack_function.description')}
51+
bind:value={onAttackFunction}
52+
defaultValue=""
53+
syntax="mcfunction"
54+
/>
55+
56+
<CodeInput
57+
label={localize('dialog.interaction_config.on_remove_function.title')}
58+
tooltip={localize('dialog.interaction_config.on_remove_function.description')}
59+
bind:value={onRemoveFunction}
60+
defaultValue=""
61+
syntax="mcfunction"
62+
/>
63+
64+
<CodeInput
65+
label={localize('dialog.interaction_config.on_tick_function.title')}
66+
tooltip={localize('dialog.interaction_config.on_tick_function.description')}
67+
bind:value={onTickFunction}
68+
defaultValue=""
69+
syntax="mcfunction"
70+
/>
71+
{/if}
72+
</div>
73+
74+
<style>
75+
.locator-config {
76+
max-height: 75vh;
77+
overflow-y: auto;
78+
}
79+
</style>
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import {
2+
registerDeletableHandlerPatch,
3+
registerPropertyOverridePatch,
4+
} from 'blockbench-patch-manager'
5+
import { observable } from 'svelte-observable-store'
6+
import { SvelteDialog } from 'svelte-patching-tools/blockbench'
7+
import { PACKAGE } from '../../constants'
8+
import { activeProjectIsBlueprintFormat } from '../../formats/blueprint'
9+
import { InteractionConfig } from '../../nodeConfigs'
10+
import { localize } from '../../util/lang'
11+
import LocatorConfigDialog from './interactionConfig.svelte'
12+
13+
// TODO - Make on-tick function work without requiring use-entity.
14+
15+
export function openInteractionConfigDialog(interaction: BoundingBox) {
16+
// Blockbench's JSON stringifier doesn't handle custom toJSON functions, so I'm storing the config JSON in the bounding box instead of the actual BoundingBoxConfig object
17+
const boundingBoxConfig = InteractionConfig.fromJSON(
18+
// @ts-expect-error - Broken BB types
19+
(interaction.config ??= new InteractionConfig().toJSON())
20+
)
21+
22+
const response = observable(boundingBoxConfig.response)
23+
const onSummonFunction = observable(boundingBoxConfig.onSummonFunction)
24+
const onInteractionFunction = observable(boundingBoxConfig.onInteractionFunction)
25+
const onAttackFunction = observable(boundingBoxConfig.onAttackFunction)
26+
const onRemoveFunction = observable(boundingBoxConfig.onRemoveFunction)
27+
const onTickFunction = observable(boundingBoxConfig.onTickFunction)
28+
29+
new SvelteDialog({
30+
id: `${PACKAGE.name}:interactionConfig`,
31+
title: localize('dialog.interaction_config.title'),
32+
width: 800,
33+
component: LocatorConfigDialog,
34+
props: {
35+
response,
36+
onSummonFunction,
37+
onInteractionFunction,
38+
onAttackFunction,
39+
onRemoveFunction,
40+
onTickFunction,
41+
},
42+
disableKeybinds: true,
43+
onConfirm() {
44+
boundingBoxConfig.response = response.get()
45+
boundingBoxConfig.onSummonFunction = onSummonFunction.get()
46+
boundingBoxConfig.onInteractionFunction = onInteractionFunction.get()
47+
boundingBoxConfig.onAttackFunction = onAttackFunction.get()
48+
boundingBoxConfig.onRemoveFunction = onRemoveFunction.get()
49+
boundingBoxConfig.onTickFunction = onTickFunction.get()
50+
51+
// @ts-expect-error - Broken BB types
52+
interaction.config = boundingBoxConfig.toJSON()
53+
},
54+
}).show()
55+
}
56+
57+
const OPEN_INTERACTION_CONFIG = registerDeletableHandlerPatch({
58+
id: `animated_java:action/interaction-config`,
59+
create() {
60+
// @ts-expect-error - Broken BB types
61+
const action = new Blockbench.Action(`animated_java:action/interaction-config`, {
62+
icon: 'settings',
63+
name: localize('action.open_interaction_config.name'),
64+
condition: () => activeProjectIsBlueprintFormat(),
65+
click: () => {
66+
const interaction = BoundingBox.selected.at(0)
67+
if (!interaction) return
68+
// @ts-expect-error - Broken BB types
69+
openInteractionConfigDialog(interaction)
70+
},
71+
})
72+
return action
73+
},
74+
})
75+
76+
registerPropertyOverridePatch({
77+
id: `animated_java:bounding-box/extend`,
78+
target: BoundingBox.prototype,
79+
key: 'extend',
80+
81+
get: function (this, value) {
82+
if (activeProjectIsBlueprintFormat()) {
83+
return function (this: BoundingBox, ...args) {
84+
const result = value.apply(this, args)
85+
this.menu = BoundingBox.prototype.menu
86+
return result
87+
}
88+
}
89+
return value
90+
},
91+
})
92+
93+
registerPropertyOverridePatch({
94+
id: `animated_java:bounding-box/menu`,
95+
dependencies: [`animated_java:action/interaction-config`],
96+
target: BoundingBox.prototype,
97+
key: 'menu',
98+
99+
get: function (this, value) {
100+
if (activeProjectIsBlueprintFormat()) {
101+
return new Menu([
102+
...Outliner.control_menu_group,
103+
new MenuSeparator('export'),
104+
'generate_bedrock_block_box',
105+
'generate_bedrock_entity_box',
106+
new MenuSeparator('interaction'),
107+
OPEN_INTERACTION_CONFIG.get(),
108+
new MenuSeparator('settings'),
109+
{
110+
name: 'menu.cube.color',
111+
icon: 'color_lens',
112+
children() {
113+
return markerColors.map((color, i) => {
114+
return {
115+
icon: 'bubble_chart',
116+
color: color.standard,
117+
// @ts-expect-error - Broken BB types
118+
name: color.name ?? 'cube.color.' + color.id,
119+
click(element: BoundingBox) {
120+
// @ts-expect-error - Broken BB types
121+
element.forSelected((obj: BoundingBox) => {
122+
obj.setColor(i)
123+
}, 'Change color')
124+
},
125+
}
126+
})
127+
},
128+
},
129+
'randomize_marker_colors',
130+
new MenuSeparator('manage'),
131+
'rename',
132+
'toggle_visibility',
133+
'delete',
134+
])
135+
}
136+
return value
137+
},
138+
})

src/dialogs/locatorConfig/locatorConfig.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export function openLocatorConfigDialog(locator: Locator) {
5050
registerDeletableHandlerPatch({
5151
id: `animated_java:action/locator-config`,
5252
create() {
53+
// @ts-expect-error - Broken BB types
5354
const action = new Blockbench.Action(`animated_java:action/locator-config`, {
5455
icon: 'settings',
5556
name: translate('action.open_locator_config.name'),

src/formats/blueprint/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { mount, unmount } from 'svelte'
55
import { observable, type Observable } from 'svelte-observable-store'
66
import { injectComponent } from 'svelte-patching-tools'
77
import AnimatedJavaIcon from '../../assets/icons/animated_java_fancy_icon_centered.svg'
8-
import { DisplayEntityConfig, LocatorConfig } from '../../nodeConfigs'
8+
import { DisplayEntityConfig, InteractionConfig, LocatorConfig } from '../../nodeConfigs'
99
import { type TextDisplay } from '../../outliner/textDisplay'
1010
import { type VanillaBlockDisplay } from '../../outliner/vanillaBlockDisplay'
1111
import { type VanillaItemDisplay } from '../../outliner/vanillaItemDisplay'
@@ -65,6 +65,18 @@ export interface IBlueprintLocatorConfigJSON {
6565
on_tick_function?: LocatorConfig['__onTickFunction']
6666
}
6767

68+
/**
69+
* The serialized Variant Interaction Config
70+
*/
71+
export interface IBlueprintInteractionConfigJSON {
72+
response?: InteractionConfig['__response']
73+
on_summon_function?: InteractionConfig['__onSummonFunction']
74+
on_interaction_function?: InteractionConfig['__onInteractionFunction']
75+
on_attack_function?: InteractionConfig['__onAttackFunction']
76+
on_remove_function?: InteractionConfig['__onRemoveFunction']
77+
on_tick_function?: InteractionConfig['__onTickFunction']
78+
}
79+
6880
/**
6981
* The serialized Variant
7082
*/
@@ -361,6 +373,7 @@ export const BLUEPRINT_FORMAT = registerDeletableHandlerPatch({
361373
single_texture: false,
362374
texture_folder: false,
363375
texture_meshes: false,
376+
bounding_boxes: true,
364377
uv_rotation: true,
365378
vertex_color_ambient_occlusion: true,
366379
java_cube_shading_properties: true,

src/lang/en.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ animated_java:
2626
name: Display Entity Config
2727
open_locator_config:
2828
name: Locator Config
29+
open_interaction_config:
30+
name: Interaction Config
2931
export:
3032
name: Export
3133
export_debug:
@@ -506,7 +508,61 @@ animated_java:
506508
[Markdown]
507509
Commands to run `as` and `at` the Locator's entity every tick.
508510
511+
interaction_config:
512+
title: Interaction Config
513+
plugin_mode_warning: |-
514+
Plugin Mode is enabled! Interaction have no configuration in Plugin Mode.
515+
Instead, use the Plugin API to add custom functionality to your Interaction.
516+
For more information, see the Official Plugin API documentation for more information.
517+
518+
response:
519+
title: Response
520+
description: Whether interacting with this Interaction should trigger a response (hand animation / attack sound).
521+
522+
on_summon_function:
523+
title: On-Summon Function
524+
description: |-
525+
[Markdown]
526+
Commands to run `as` and `at` this Interaction when summoned.
527+
528+
Supports [MC-Build](https://mcbuild.dev) syntax.
529+
530+
on_interaction_function:
531+
title: On-Interaction Function
532+
description: |-
533+
[Markdown]
534+
Commands to run `as` and `at` this Interaction when a player interacts with it.
535+
536+
You can use `execute on target` to select the player who initiated the interaction.
537+
538+
Supports [MC-Build](https://mcbuild.dev) syntax.
539+
540+
on_attack_function:
541+
title: On-Attack Function
542+
description: |-
543+
[Markdown]
544+
Commands to run `as` and `at` this Interaction when a player attacks it.
545+
546+
You can use `execute on attacker` to select the player who initiated the attack.
547+
548+
Supports [MC-Build](https://mcbuild.dev) syntax.
549+
550+
on_remove_function:
551+
title: On-Remove Function
552+
description: |-
553+
[Markdown]
554+
Commands to run `as` and `at` this Interaction when removed.
555+
509556
Supports [MC-Build](https://mcbuild.dev) syntax.
557+
558+
on_tick_function:
559+
title: On-Tick Function
560+
description: |-
561+
[Markdown]
562+
Commands to run `as` and `at` this Interaction every tick.
563+
564+
Supports [MC-Build](https://mcbuild.dev) syntax.
565+
510566
text_display_config:
511567
title: Text Display Config
512568
use_nbt:

0 commit comments

Comments
 (0)