@minecraft/server-ui 1.0.0-beta.00001b37

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/.eslintrc.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "env": {
3
+ "browser": true,
4
+ "es2021": true
5
+ },
6
+ "extends": [
7
+ "eslint:recommended",
8
+ "plugin:@typescript-eslint/recommended"
9
+ ],
10
+ "overrides": [
11
+ ],
12
+ "parser": "@typescript-eslint/parser",
13
+ "parserOptions": {
14
+ "ecmaVersion": "latest",
15
+ "sourceType": "module"
16
+ },
17
+ "plugins": [
18
+ "@typescript-eslint"
19
+ ],
20
+ "rules": {
21
+ "@typescript-eslint/no-explicit-any": "off"
22
+ }
23
+ }
package/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # `@minecraft/server-ui`
2
+
3
+ The `@minecraft/server-ui` module contains types for expressing simple dialog-based user experiences.
4
+
5
+
6
+
7
+ * [*@minecraft/server-ui.ActionFormData*](../@minecraft-server-ui/ActionFormData.md) contain a list of buttons with captions and images that can be used for presenting a set of options to a player.
8
+
9
+ * [*@minecraft/server-ui.MessageFormData*](../@minecraft-server-ui/MessageFormData.md) are simple two-button message experiences that are functional for Yes/No or OK/Cancel questions.
10
+
11
+ * [*@minecraft/server-ui.ModalFormData*](../@minecraft-server-ui/ModalFormData.md) allow for a more flexible "questionnaire-style" list of controls that can be used to take input.
12
+
13
+ ## **NOTE: This version of this module is still in pre-release. It may change or it may be removed in future releases.**
14
+
15
+ See full documentation for this module here:
16
+
17
+ https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/@minecraft/server-ui/@minecraft/server-ui
package/index.d.ts ADDED
@@ -0,0 +1,268 @@
1
+ // Type definitions for Minecraft Bedrock Edition script APIs
2
+ // Project: https://docs.microsoft.com/minecraft/creator/
3
+ // Definitions by: Jake Shirley <https://github.com/JakeShirley>
4
+ // Mike Ammerlaan <https://github.com/mammerla>
5
+
6
+ /* *****************************************************************************
7
+ Copyright (c) Microsoft Corporation.
8
+ ***************************************************************************** */
9
+ /**
10
+ * @packageDocumentation
11
+ * The `@minecraft/server-ui` module contains types for
12
+ * expressing simple dialog-based user experiences.
13
+ *
14
+ * * {@link ActionFormData} contain a list of buttons with
15
+ * captions and images that can be used for presenting a set of
16
+ * options to a player.
17
+ * * {@link MessageFormData} are simple two-button message
18
+ * experiences that are functional for Yes/No or OK/Cancel
19
+ * questions.
20
+ * * {@link ModalFormData} allow for a more flexible
21
+ * "questionnaire-style" list of controls that can be used to
22
+ * take input.
23
+ * @example createActionForm.js
24
+ * ```typescript
25
+ * const form = new ActionFormData()
26
+ * .title("Months")
27
+ * .body("Choose your favorite month!")
28
+ * .button("January")
29
+ * .button("February")
30
+ * .button("March")
31
+ * .button("April")
32
+ * .button("May");
33
+ *
34
+ * form.show(players[0]).then((response) => {
35
+ * if (response.selection === 3) {
36
+ * dimension.runCommand("say I like April too!");
37
+ * }
38
+ * });
39
+ *
40
+ * ```
41
+ *
42
+ * Manifest Details
43
+ * ```json
44
+ * {
45
+ * "module_name": "@minecraft/server-ui",
46
+ * "version": "0.1.0"
47
+ * }
48
+ * ```
49
+ *
50
+ */
51
+ import * as minecraftserver from '@minecraft/server';
52
+ export enum FormCancelationReason {
53
+ userBusy = 'userBusy',
54
+ userClosed = 'userClosed',
55
+ }
56
+ /**
57
+ * Builds a simple player form with buttons that let the player
58
+ * take action.
59
+ */
60
+ export class ActionFormData {
61
+ /**
62
+ * @remarks
63
+ * Method that sets the body text for the modal form.
64
+ * @param bodyText
65
+ */
66
+ body(bodyText: string): ActionFormData;
67
+ /**
68
+ * @remarks
69
+ * Adds a button to this form with an icon from a resource
70
+ * pack.
71
+ * @param text
72
+ * @param iconPath
73
+ */
74
+ button(text: string, iconPath?: string): ActionFormData;
75
+ /**
76
+ * @remarks
77
+ * Creates and shows this modal popup form. Returns
78
+ * asynchronously when the player confirms or cancels the
79
+ * dialog.
80
+ * @param player
81
+ * Player to show this dialog to.
82
+ * @throws This function can throw errors.
83
+ */
84
+ show(player: minecraftserver.Player): Promise<ActionFormResponse>;
85
+ /**
86
+ * @remarks
87
+ * This builder method sets the title for the modal dialog.
88
+ * @param titleText
89
+ */
90
+ title(titleText: string): ActionFormData;
91
+ }
92
+ /**
93
+ * Returns data about the player results from a modal action
94
+ * form.
95
+ */
96
+ export class ActionFormResponse extends FormResponse {
97
+ /**
98
+ * Contains additional details as to why a form was canceled.
99
+ */
100
+ readonly cancelationReason?: FormCancelationReason;
101
+ /**
102
+ * If true, the form was canceled by the player (e.g., they
103
+ * selected the pop-up X close button).
104
+ */
105
+ readonly canceled: boolean;
106
+ /**
107
+ * Returns the index of the button that was pushed.
108
+ */
109
+ readonly selection?: number;
110
+ protected constructor();
111
+ }
112
+ /**
113
+ * Base type for a form response.
114
+ */
115
+ export class FormResponse {
116
+ /**
117
+ * Contains additional details as to why a form was canceled.
118
+ */
119
+ readonly cancelationReason?: FormCancelationReason;
120
+ /**
121
+ * If true, the form was canceled by the player (e.g., they
122
+ * selected the pop-up X close button).
123
+ */
124
+ readonly canceled: boolean;
125
+ protected constructor();
126
+ }
127
+ /**
128
+ * Builds a simple two-button modal dialog.
129
+ */
130
+ export class MessageFormData {
131
+ /**
132
+ * @remarks
133
+ * Method that sets the body text for the modal form.
134
+ * @param bodyText
135
+ */
136
+ body(bodyText: string): MessageFormData;
137
+ /**
138
+ * @remarks
139
+ * Method that sets the text for the first button of the
140
+ * dialog.
141
+ * @param text
142
+ */
143
+ button1(text: string): MessageFormData;
144
+ /**
145
+ * @remarks
146
+ * This method sets the text for the second button on the
147
+ * dialog.
148
+ * @param text
149
+ */
150
+ button2(text: string): MessageFormData;
151
+ /**
152
+ * @remarks
153
+ * Creates and shows this modal popup form. Returns
154
+ * asynchronously when the player confirms or cancels the
155
+ * dialog.
156
+ * @param player
157
+ * Player to show this dialog to.
158
+ * @throws This function can throw errors.
159
+ */
160
+ show(player: minecraftserver.Player): Promise<MessageFormResponse>;
161
+ /**
162
+ * @remarks
163
+ * This builder method sets the title for the modal dialog.
164
+ * @param titleText
165
+ */
166
+ title(titleText: string): MessageFormData;
167
+ }
168
+ /**
169
+ * Returns data about the player results from a modal message
170
+ * form.
171
+ */
172
+ export class MessageFormResponse extends FormResponse {
173
+ /**
174
+ * Contains additional details as to why a form was canceled.
175
+ */
176
+ readonly cancelationReason?: FormCancelationReason;
177
+ /**
178
+ * If true, the form was canceled by the player (e.g., they
179
+ * selected the pop-up X close button).
180
+ */
181
+ readonly canceled: boolean;
182
+ /**
183
+ * Returns the index of the button that was pushed.
184
+ */
185
+ readonly selection?: number;
186
+ protected constructor();
187
+ }
188
+ /**
189
+ * Used to create a fully customizable pop-up form for a
190
+ * player.
191
+ */
192
+ export class ModalFormData {
193
+ /**
194
+ * @remarks
195
+ * Adds a dropdown with choices to the form.
196
+ * @param label
197
+ * @param options
198
+ * @param defaultValueIndex
199
+ */
200
+ dropdown(label: string, options: string[], defaultValueIndex?: number): ModalFormData;
201
+ /**
202
+ * @remarks
203
+ * Creates and shows this modal popup form. Returns
204
+ * asynchronously when the player confirms or cancels the
205
+ * dialog.
206
+ * @param player
207
+ * Player to show this dialog to.
208
+ * @throws This function can throw errors.
209
+ */
210
+ show(player: minecraftserver.Player): Promise<ModalFormResponse>;
211
+ /**
212
+ * @remarks
213
+ * Adds a numeric slider to the form.
214
+ * @param label
215
+ * @param minimumValue
216
+ * @param maximumValue
217
+ * @param valueStep
218
+ * @param defaultValue
219
+ */
220
+ slider(
221
+ label: string,
222
+ minimumValue: number,
223
+ maximumValue: number,
224
+ valueStep: number,
225
+ defaultValue?: number,
226
+ ): ModalFormData;
227
+ /**
228
+ * @remarks
229
+ * Adds a textbox to the form.
230
+ * @param label
231
+ * @param placeholderText
232
+ * @param defaultValue
233
+ */
234
+ textField(label: string, placeholderText: string, defaultValue?: string): ModalFormData;
235
+ /**
236
+ * @remarks
237
+ * This builder method sets the title for the modal dialog.
238
+ * @param titleText
239
+ */
240
+ title(titleText: string): ModalFormData;
241
+ /**
242
+ * @remarks
243
+ * Adds a toggle checkbox button to the form.
244
+ * @param label
245
+ * @param defaultValue
246
+ */
247
+ toggle(label: string, defaultValue?: boolean): ModalFormData;
248
+ }
249
+ /**
250
+ * Returns data about player responses to a modal form.
251
+ */
252
+ export class ModalFormResponse extends FormResponse {
253
+ /**
254
+ * Contains additional details as to why a form was canceled.
255
+ */
256
+ readonly cancelationReason?: FormCancelationReason;
257
+ /**
258
+ * If true, the form was canceled by the player (e.g., they
259
+ * selected the pop-up X close button).
260
+ */
261
+ readonly canceled: boolean;
262
+ /**
263
+ * An ordered set of values based on the order of controls
264
+ * specified by ModalFormData.
265
+ */
266
+ readonly formValues?: any[];
267
+ protected constructor();
268
+ }
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@minecraft/server-ui",
3
+ "version": "1.0.0-beta.00001b37",
4
+ "description": "",
5
+ "contributors": [
6
+ {
7
+ "name": "Jake Shirley",
8
+ "email": "jake@xbox.com"
9
+ },
10
+ {
11
+ "name": "Mike Ammerlaan",
12
+ "email": "mikeam@microsoft.com"
13
+ }
14
+ ],
15
+ "dependencies": {
16
+ "@minecraft/server": "1.0.0-beta.00001b37"
17
+ },
18
+ "license": "MIT"
19
+ }
package/tests.ts ADDED
@@ -0,0 +1,171 @@
1
+ import * as mc from '@minecraft/server';
2
+
3
+ export async function showActionForm(log: (message: string, status?: number) => void) {
4
+ const players = mc.world.getPlayers();
5
+
6
+ const playerList = Array.from(players);
7
+
8
+ if (playerList.length >= 1) {
9
+ const form = new mcui.ActionFormData()
10
+ .title('Test Title')
11
+ .body('Body text here!')
12
+ .button('btn 1')
13
+ .button('btn 2')
14
+ .button('btn 3')
15
+ .button('btn 4')
16
+ .button('btn 5');
17
+
18
+ const result = await form.show(playerList[0]);
19
+
20
+ if (result.canceled) {
21
+ log('Player exited out of the dialog.');
22
+ } else {
23
+ log('Your result was: ' + result.selection);
24
+ }
25
+ }
26
+ }
27
+
28
+ export function showFavoriteMonth(log: (message: string, status?: number) => void) {
29
+ const players = mc.world.getPlayers();
30
+
31
+ const playerList = Array.from(players);
32
+
33
+ if (playerList.length >= 1) {
34
+ const form = new mcui.ActionFormData()
35
+ .title('Months')
36
+ .body('Choose your favorite month!')
37
+ .button('January')
38
+ .button('February')
39
+ .button('March')
40
+ .button('April')
41
+ .button('May');
42
+
43
+ form.show(playerList[0]).then((response: mcui.ActionFormResponse) => {
44
+ if (response.selection === 3) {
45
+ log('I like April too!');
46
+ }
47
+ });
48
+ }
49
+ }
50
+
51
+ export default class SampleManager {
52
+ tickCount = 0;
53
+
54
+ _availableFuncs: {
55
+ [name: string]: Array<(log: (message: string, status?: number) => void, location: mc.Location) => void>;
56
+ };
57
+
58
+ pendingFuncs: Array<{
59
+ name: string;
60
+ func: (log: (message: string, status?: number) => void, location: mc.Location) => void;
61
+ location: mc.Location;
62
+ }> = [];
63
+
64
+ gameplayLogger(message: string, status?: number) {
65
+ if (status !== undefined && status > 0) {
66
+ message = 'SUCCESS: ' + message;
67
+ } else if (status !== undefined && status < 0) {
68
+ message = 'FAIL: ' + message;
69
+ }
70
+
71
+ this.say(message);
72
+ }
73
+ say(message: string) {
74
+ mc.world.getDimension('overworld').runCommand('say ' + message);
75
+ }
76
+
77
+ newChatMessage(chatEvent: mc.ChatEvent) {
78
+ const message = chatEvent.message.toLowerCase();
79
+
80
+ if (message.startsWith('howto') && chatEvent.sender) {
81
+ const nearbyBlock = chatEvent.sender.getBlockFromViewVector();
82
+ if (!nearbyBlock) {
83
+ this.gameplayLogger('Please look at the block where you want me to run this.');
84
+ return;
85
+ }
86
+
87
+ const nearbyBlockLoc = nearbyBlock.location;
88
+ const nearbyLoc = new mc.Location(nearbyBlockLoc.x, nearbyBlockLoc.y + 1, nearbyBlockLoc.z);
89
+
90
+ const sampleId = message.substring(5).trim();
91
+
92
+ if (sampleId.length < 2) {
93
+ let availableFuncStr = 'Here is my list of available samples:';
94
+
95
+ for (const sampleFuncKey in this._availableFuncs) {
96
+ availableFuncStr += ' ' + sampleFuncKey;
97
+ }
98
+
99
+ this.say(availableFuncStr);
100
+ } else {
101
+ for (const sampleFuncKey in this._availableFuncs) {
102
+ if (sampleFuncKey.toLowerCase() === sampleId) {
103
+ const sampleFunc = this._availableFuncs[sampleFuncKey];
104
+
105
+ this.runSample(sampleFuncKey + this.tickCount, sampleFunc, nearbyLoc);
106
+
107
+ return;
108
+ }
109
+ }
110
+
111
+ this.say(`I couldn't find the sample '${sampleId}"'`);
112
+ }
113
+ }
114
+ }
115
+
116
+ runSample(
117
+ sampleId: string,
118
+ snippetFunctions: Array<(log: (message: string, status?: number) => void, location: mc.Location) => void>,
119
+ targetLocation: mc.Location,
120
+ ) {
121
+ for (let i = snippetFunctions.length - 1; i >= 0; i--) {
122
+ this.pendingFuncs.push({ name: sampleId, func: snippetFunctions[i], location: targetLocation });
123
+ }
124
+ }
125
+
126
+ worldTick() {
127
+ if (this.tickCount % 10 === 0) {
128
+ if (this.pendingFuncs.length > 0) {
129
+ const funcSet = this.pendingFuncs.pop();
130
+
131
+ if (funcSet) {
132
+ funcSet.func(this.gameplayLogger, funcSet.location);
133
+ }
134
+ }
135
+ }
136
+
137
+ this.tickCount++;
138
+ }
139
+
140
+ constructor() {
141
+ this._availableFuncs = {};
142
+
143
+ this.gameplayLogger = this.gameplayLogger.bind(this);
144
+
145
+ mc.world.events.tick.subscribe(this.worldTick.bind(this));
146
+ mc.world.events.chat.subscribe(this.newChatMessage.bind(this));
147
+ }
148
+
149
+ registerSamples(sampleSet: {
150
+ [name: string]: Array<(log: (message: string, status?: number) => void, location: mc.Location) => void>;
151
+ }) {
152
+ for (const sampleKey in sampleSet) {
153
+ if (sampleKey.length > 1 && sampleSet[sampleKey]) {
154
+ this._availableFuncs[sampleKey] = sampleSet[sampleKey];
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ import * as mcui from '@minecraft/server-ui';
161
+
162
+ const mojangMinecraftUIFuncs: {
163
+ [name: string]: Array<(log: (message: string, status?: number) => void, location: mc.Location) => void>;
164
+ } = {
165
+ showActionForm: [showActionForm],
166
+ showFavoriteMonth: [showFavoriteMonth],
167
+ };
168
+
169
+ export function register(sampleManager: SampleManager) {
170
+ sampleManager.registerSamples(mojangMinecraftUIFuncs);
171
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "lib": ["es6"],
5
+ "target": "es6",
6
+ "forceConsistentCasingInFileNames": true,
7
+ "noEmit": true,
8
+ "noImplicitAny": true,
9
+ "noImplicitThis": true,
10
+ "strictFunctionTypes": true,
11
+ "strictNullChecks": true,
12
+ "baseUrl": "../",
13
+ "typeRoots": ["../"],
14
+ "types": []
15
+ },
16
+ "files": [
17
+ "index.d.ts",
18
+ "tests.ts"
19
+ ]
20
+ }