diff --git a/src/lib/Toolbox/Toolbox.xml b/src/lib/Toolbox/Toolbox.xml
index 13b5b91..2e348c8 100644
--- a/src/lib/Toolbox/Toolbox.xml
+++ b/src/lib/Toolbox/Toolbox.xml
@@ -3,6 +3,8 @@
+
+
@@ -16,6 +18,8 @@
+
+
@@ -43,6 +47,7 @@
+
@@ -181,10 +186,18 @@
-
+
-
+
+
+
+ hello world!
+
+
+
+
+
diff --git a/src/resources/blocks/control.js b/src/resources/blocks/control.js
index 37c9eb4..cd05208 100644
--- a/src/resources/blocks/control.js
+++ b/src/resources/blocks/control.js
@@ -75,6 +75,60 @@ function register() {
return `${code}\n`;
})
+ registerBlock(`${categoryPrefix}while`, {
+ message0: 'while %1 do %2 %3',
+ args0: [
+ {
+ "type": "input_value",
+ "name": "CONDITION",
+ "check": "Boolean"
+ },
+ {
+ "type": "input_dummy"
+ },
+ {
+ "type": "input_statement",
+ "name": "BLOCKS"
+ }
+ ],
+ previousStatement: null,
+ nextStatement: null,
+ inputsInline: true,
+ colour: categoryColor
+ }, (block) => {
+ const CONDITION = javascriptGenerator.valueToCode(block, 'CONDITION', javascriptGenerator.ORDER_ATOMIC);
+ const BLOCKS = javascriptGenerator.statementToCode(block, 'BLOCKS');
+ const code = `do { ${BLOCKS} } while (${CONDITION})`;
+ return `${code}\n`;
+ })
+
+ registerBlock(`${categoryPrefix}until`, {
+ message0: 'until %1 do %2 %3',
+ args0: [
+ {
+ "type": "input_value",
+ "name": "CONDITION",
+ "check": "Boolean"
+ },
+ {
+ "type": "input_dummy"
+ },
+ {
+ "type": "input_statement",
+ "name": "BLOCKS"
+ }
+ ],
+ previousStatement: null,
+ nextStatement: null,
+ inputsInline: true,
+ colour: categoryColor
+ }, (block) => {
+ const CONDITION = javascriptGenerator.valueToCode(block, 'CONDITION', javascriptGenerator.ORDER_ATOMIC);
+ const BLOCKS = javascriptGenerator.statementToCode(block, 'BLOCKS');
+ const code = `do { ${BLOCKS} } while (!(${CONDITION}))`;
+ return `${code}\n`;
+ })
+
// if <> then {}
registerBlock(`${categoryPrefix}ifthen`, {
message0: 'if %1 then %2 %3',
diff --git a/src/resources/blocks/events.js b/src/resources/blocks/events.js
index bb8c529..3222db9 100644
--- a/src/resources/blocks/events.js
+++ b/src/resources/blocks/events.js
@@ -171,6 +171,90 @@ function register() {
const code = `setTimeout(async () => { ${BLOCKS} }, (${TIME} * 1000));`;
return `${code}\n`;
})
+
+ registerBlock(`${categoryPrefix}whenkeypressed`, {
+ message0: 'when %1 key is down %2 %3',
+ args0: [
+ {
+ "type": "field_dropdown",
+ "name": "KEY",
+ "options": keyBoard
+ },
+ {
+ "type": "input_dummy"
+ },
+ {
+ "type": "input_statement",
+ "name": "BLOCKS"
+ }
+ ],
+ nextStatement: null,
+ inputsInline: true,
+ colour: categoryColor,
+ }, (block) => {
+ const KEY = block.getFieldValue('KEY')
+ const BLOCKS = javascriptGenerator.statementToCode(block, 'BLOCKS');
+ const code = `window.addEventListener("keydown", event => {
+ ${KEY===""?`${BLOCKS}`:`if (event.keyCode == '${KEY}') { ${BLOCKS}}`}});`;
+ return `${code}\n`;
+ })
}
+const keyBoard = [
+ ["ANY", ""],
+ ["SPACE", "32"],
+ ["UP ARROW", "38"],
+ ["DOWN ARROW", "40"],
+ ["LEFT ARROW", "37"],
+ ["RIGHT ARROW", "39"],
+ ["A", "65"],
+ ["B", "66"],
+ ["C", "67"],
+ ["D", "68"],
+ ["E", "69"],
+ ["F", "70"],
+ ["G", "71"],
+ ["H", "72"],
+ ["I", "73"],
+ ["J", "74"],
+ ["K", "75"],
+ ["L", "76"],
+ ["M", "77"],
+ ["N", "78"],
+ ["O", "79"],
+ ["P", "80"],
+ ["Q", "81"],
+ ["R", "82"],
+ ["S", "83"],
+ ["T", "84"],
+ ["U", "85"],
+ ["V", "86"],
+ ["W", "87"],
+ ["X", "88"],
+ ["Y", "89"],
+ ["Z", "90"],
+ ["0", "48"],
+ ["1", "49"],
+ ["2", "50"],
+ ["3", "51"],
+ ["4", "52"],
+ ["5", "53"],
+ ["6", "54"],
+ ["7", "55"],
+ ["8", "56"],
+ ["9", "57"],
+ ["F1", "112"],
+ ["F2", "113"],
+ ["F3", "114"],
+ ["F4", "115"],
+ ["F5", "116"],
+ ["F6", "117"],
+ ["F7", "118"],
+ ["F8", "119"],
+ ["F9", "120"],
+ ["F10", "121"],
+ ["F11", "122"],
+ ["F12", "123"],
+];
+
export default register;
diff --git a/src/resources/blocks/player.js b/src/resources/blocks/player.js
index 8c08f4b..cb7274d 100644
--- a/src/resources/blocks/player.js
+++ b/src/resources/blocks/player.js
@@ -76,7 +76,7 @@ function register() {
const MENU2 = block.getFieldValue('MENU2');
return [`ModAPI.player?ModAPI.player.dimension===${MENU2}:""`, javascriptGenerator.ORDER_ATOMIC];
})
-
+
registerBlock(`${categoryPrefix}username`, {
message0: 'username',
args0: [],
@@ -325,7 +325,245 @@ function register() {
})
- registerBlock(`${categoryPrefix}keypressed`, {
+ registerBlock(`${categoryPrefix}setpropertyboolean`, {
+ message0: 'set player property %1 to %2',
+ args0: [
+ {
+ "type": "field_dropdown",
+ "name": "PROPERTIES",
+ "options": [
+ [ "is dead", "isdead" ],
+ [ "is invisible", "isinvisible" ],
+ [ "is in web", "isinweb" ],
+ [ "is sprinting", "issprinting" ],
+ [ "is sneaking", "issneaking" ],
+ [ "is silent", "issilent" ],
+ [ "can edit", "canedit" ],
+ ]
+ },
+ {
+ "type": "input_value",
+ "name": "BOOLEAN",
+ "check": "Boolean"
+ },
+ ],
+ previousStatement: null,
+ nextStatement: null,
+ inputsInline: true,
+ colour: categoryColor
+ }, (block) => {
+ const PROPERTY = block.getFieldValue('PROPERTIES');
+ let BOOLEAN = javascriptGenerator.valueToCode(block, 'BOOLEAN', javascriptGenerator.ORDER_ATOMIC);
+ BOOLEAN = BOOLEAN ? `${Boolean(BOOLEAN)}` : 'false'
+ let code;
+ if (PROPERTY === "isdead") {
+ code = (BOOLEAN==="true"?`ModAPI.player.setDead()`:'');
+ } else if (PROPERTY === "isinvisible") {
+ code = `ModAPI.player.setInvisible({invisible: ${BOOLEAN}})`
+ } else if (PROPERTY === "isinweb") {
+ code = `ModAPI.player.setInWeb(${BOOLEAN})`
+ } else if (PROPERTY === "issprinting") {
+ code = `ModAPI.player.setSprinting({flag: ${BOOLEAN}})`
+ } else if (PROPERTY === "issneaking") {
+ code = `ModAPI.player.setSneaking({sneaking: ${BOOLEAN}})`
+ } else if (PROPERTY === "issilent") {
+ code = `ModAPI.player.setSilent({isSilent: ${BOOLEAN}})`
+ } else if (PROPERTY === "canedit") {
+ code = `ModAPI.player.allowEdit(${BOOLEAN})`
+ }
+ return code;
+ })
+
+ registerBlock(`${categoryPrefix}getpropertyboolean`, {
+ message0: "get player property %1",
+ args0: [
+ {
+ "type": "field_dropdown",
+ "name": "PROPERTIES",
+ "options": [
+ [ "is dead", "isdead" ],
+ [ "is invisible", "isinvisible" ],
+ [ "is in web", "isinweb" ],
+ [ "is sprinting", "issprinting" ],
+ [ "is sneaking", "issneaking" ],
+ [ "is silent", "issilent" ],
+ [ "can edit", "canedit" ],
+ [ "on ground", "onground" ],
+ [ "is moving", "ismoving" ],
+ ]
+ },
+ ],
+ output: "Boolean",
+ inputsInline: true,
+ colour: categoryColor
+ }, (block) => {
+ const PROPERTY = block.getFieldValue('PROPERTIES');
+ let code;
+ if (PROPERTY === "isdead") {
+ code = 'ModAPI.player.isDead';
+ } else if (PROPERTY === "isinvisible") {
+ code = `ModAPI.player.isInvisible()`
+ } else if (PROPERTY === "isinweb") {
+ code = `ModAPI.player.isInWeb`
+ } else if (PROPERTY === "issprinting") {
+ code = `ModAPI.player.isSprinting()`
+ } else if (PROPERTY === "issneaking") {
+ code = `ModAPI.player.isSneaking()`
+ } else if (PROPERTY === "issilent") {
+ code = `ModAPI.player.isSilent()`
+ } else if (PROPERTY === "canedit") {
+ code = `ModAPI.player.isAllowEdit()`
+ } else if (PROPERTY === "onground") {
+ code = `ModAPI.player.onGround`
+ } else if (PROPERTY === "isdead") {
+ code = `ModAPI.player.isDead`
+ } else if (PROPERTY === "ismoving") {
+ code = `ModAPI.player.isMoving()`
+ }
+ return code;
+ })
+
+ registerBlock(`${categoryPrefix}setpropertynumber`, {
+ message0: 'set player property %1 to %2',
+ args0: [
+ {
+ "type": "field_dropdown",
+ "name": "PROPERTIES",
+ "options": [
+ [ "X position", "xposition"],
+ [ "Y position", "yposition"],
+ [ "Z position", "zposition"],
+ [ "X motion", "Xmotion"],
+ [ "Y motion", "Ymotion"],
+ [ "Z motion", "Zmotion"],
+ [ "food level", "foodLevel" ],
+ [ "food saturation level", "foodSaturationLevel" ],
+ [ "experience", "experience" ],
+ [ "experience level", "experiencelevel" ],
+ [ "walk speed", "walkspeed" ],
+ ]
+ },
+ {
+ "type": "input_value",
+ "name": "INPUT",
+ "check": "Number"
+ }
+ ],
+ previousStatement: null,
+ nextStatement: null,
+ inputsInline: true,
+ colour: categoryColor
+ }, (block) => {
+ const PROPERTY = block.getFieldValue('PROPERTIES');
+ let INPUT = javascriptGenerator.valueToCode(block, 'INPUT', javascriptGenerator.ORDER_ATOMIC);
+ if (INPUT == "") {
+ INPUT = 0;
+ }
+ let code;
+ if (PROPERTY === "foodLevel") {
+ code = `ModAPI.player.setFoodLevel({foodLevelIn: Math.round(${INPUT})})`;
+ } else if (PROPERTY === "foodSaturationLevel") {
+ code = `ModAPI.player.setFoodSaturationLevel({foodSaturationLevelIn: ${INPUT}})`
+ } else if (PROPERTY.indexOf('position') === 1) {
+ code = `ModAPI.player.${PROPERTY.charAt(0)} = ${INPUT}`
+ } else if (PROPERTY.indexOf('motion') === 1) {
+ code = `ModAPI.player.motion${PROPERTY.charAt(0)} = ${INPUT}`
+ } else if (PROPERTY === "experience") {
+ code = `ModAPI.player.experience = ${INPUT}`;
+ } else if (PROPERTY === "experiencelevel") {
+ code = `ModAPI.player.experienceLevel = ${INPUT}`;
+ } else if (PROPERTY === "walkspeed") {
+ code = `ModAPI.player.setSpeed({speed: Math.round(${INPUT})})`;
+ }
+ return code+';ModAPI.player.reload();';
+ })
+
+ registerBlock(`${categoryPrefix}getpropertynumber`, {
+ message0: "get player property %1",
+ args0: [
+ {
+ "type": "field_dropdown",
+ "name": "PROPERTIES",
+ "options": [
+ [ "food level", "foodLevel" ],
+ [ "food saturation level", "foodSaturationLevel" ],
+ [ "experience", "experience" ],
+ [ "experience level", "experiencelevel" ],
+ [ "fall distance", "falldistance" ],
+ [ "total armor protection", "armorprotection" ],
+ [ "walk speed", "walkspeed" ],
+ ]
+ },
+ ],
+ output: "Number",
+ inputsInline: true,
+ colour: categoryColor
+ }, (block) => {
+ const PROPERTY = block.getFieldValue('PROPERTIES');
+ let code;
+ if (PROPERTY === "foodLevel") {
+ code = 'ModAPI.player.foodStats.foodLevel';
+ } else if (PROPERTY === "foodSaturationLevel") {
+ code = `ModAPI.player.foodStats.foodSaturationLevel`
+ } else if (PROPERTY === "experience") {
+ code = `ModAPI.player.experience`
+ } else if (PROPERTY === "experiencelevel") {
+ code = `ModAPI.player.experienceLevel`
+ } else if (PROPERTY === "falldistance") {
+ code = `ModAPI.player.fallDistance`
+ } else if (PROPERTY === "walkspeed") {
+ code = `ModAPI.player.getSpeed()`
+ } else if (PROPERTY === "armorprotection") {
+ code = `ModAPI.player.getTotalArmorValue()`
+ }
+
+ return [code, javascriptGenerator.ORDER_ATOMIC];
+ })
+
+ registerBlock(`${categoryPrefix}execommand`, {
+ message0: 'execute command %1 as player',
+ args0: [
+ {
+ "type": "input_value",
+ "name": "COMMAND"
+ }
+ ],
+ previousStatement: null,
+ nextStatement: null,
+ inputsInline: true,
+ colour: categoryColor
+ }, (block) => {
+ const COMMAND = javascriptGenerator.valueToCode(block, 'COMMAND', javascriptGenerator.ORDER_ATOMIC);
+ const code = `
+ if (${COMMAND}.charAt(0)==="/") {
+ ModAPI.player.sendChatMessage({message: ${COMMAND}})
+ }`;
+ return `${code}\n`;
+ })
+
+ registerBlock(`${categoryPrefix}sendchat`, {
+ message0: 'send %1 message in chat',
+ args0: [
+ {
+ "type": "input_value",
+ "name": "COMMAND"
+ }
+ ],
+ previousStatement: null,
+ nextStatement: null,
+ inputsInline: true,
+ colour: categoryColor
+ }, (block) => {
+ const COMMAND = javascriptGenerator.valueToCode(block, 'COMMAND', javascriptGenerator.ORDER_ATOMIC);
+ const code = `
+ if (${COMMAND}.charAt(0)!=="/") {
+ ModAPI.player.sendChatMessage({message: ${COMMAND}})
+ }`;
+ return `${code}\n`;
+ })
+
+
+ registerBlock(`${categoryPrefix}whengamekeypressed`, {
message0: 'when in game key %1 pressed do %2 %3',
args0: [
{
@@ -355,9 +593,9 @@ function register() {
const keyBoard = [
["SPACE", "57"],
["UP ARROW", "200"],
- ["UP DOWN", "208"],
- ["UP LEFT", "203"],
- ["UP RIGHT", "205"],
+ ["DOWN ARROW", "208"],
+ ["LEFT ARROW", "203"],
+ ["RIGHT ARROW", "205"],
["A", "30"],
["B", "48"],
["C", "46"],
diff --git a/src/resources/blocks/sensing.js b/src/resources/blocks/sensing.js
index f6fc90d..54a8937 100644
--- a/src/resources/blocks/sensing.js
+++ b/src/resources/blocks/sensing.js
@@ -133,8 +133,81 @@ function register() {
}, (block) => {
return [`ModAPI.getFPS()`, javascriptGenerator.ORDER_ATOMIC];
})
+
+ registerBlock(`${categoryPrefix}keypressed`, {
+ message0: "is key %1 pressed?",
+ args0: [
+ {
+ "type": "field_dropdown",
+ "name": "KEY2",
+ "options": keyBoard
+ },
+ ],
+ output: "Boolean",
+ inputsInline: true,
+ colour: categoryColor
+ }, (block) => {
+ const KEY2 = block.getFieldValue('KEY2');
+ return [`pressedKeys[${KEY2}]===true?true:false`, javascriptGenerator.ORDER_ATOMIC];
+ })
}
+const keyBoard = [
+ ["SPACE", "32"],
+ ["UP ARROW", "38"],
+ ["DOWN ARROW", "40"],
+ ["LEFT ARROW", "37"],
+ ["RIGHT ARROW", "39"],
+ ["A", "65"],
+ ["B", "66"],
+ ["C", "67"],
+ ["D", "68"],
+ ["E", "69"],
+ ["F", "70"],
+ ["G", "71"],
+ ["H", "72"],
+ ["I", "73"],
+ ["J", "74"],
+ ["K", "75"],
+ ["L", "76"],
+ ["M", "77"],
+ ["N", "78"],
+ ["O", "79"],
+ ["P", "80"],
+ ["Q", "81"],
+ ["R", "82"],
+ ["S", "83"],
+ ["T", "84"],
+ ["U", "85"],
+ ["V", "86"],
+ ["W", "87"],
+ ["X", "88"],
+ ["Y", "89"],
+ ["Z", "90"],
+ ["0", "48"],
+ ["1", "49"],
+ ["2", "50"],
+ ["3", "51"],
+ ["4", "52"],
+ ["5", "53"],
+ ["6", "54"],
+ ["7", "55"],
+ ["8", "56"],
+ ["9", "57"],
+ ["F1", "112"],
+ ["F2", "113"],
+ ["F3", "114"],
+ ["F4", "115"],
+ ["F5", "116"],
+ ["F6", "117"],
+ ["F7", "118"],
+ ["F8", "119"],
+ ["F9", "120"],
+ ["F10", "121"],
+ ["F11", "122"],
+ ["F12", "123"],
+];
+
Blockly.Extensions.register('single_character_validation', function() {
this.getField('KEY').setValidator(function(newValue) {
return newValue.substring(Math.max(newValue.length - 1, 0),newValue.length);
diff --git a/src/resources/compiler/index.js b/src/resources/compiler/index.js
index 39f0b56..9fc38f2 100644
--- a/src/resources/compiler/index.js
+++ b/src/resources/compiler/index.js
@@ -14,9 +14,14 @@ class Compiler {
if (code.indexOf('ModAPI.player') > -1) {
start+= "ModAPI.require('player');";
}
- if (code.indexOf('variables["') > -1) {
+ if (code.indexOf('variables[') > -1) {
start+= 'let variables = [];';
}
+ if (code.indexOf('pressedKeys[') > -1) {
+ start+= `var pressedKeys = {};
+ window.onkeyup = function(e) { pressedKeys[e.keyCode] = false; }
+ window.onkeydown = function(e) { pressedKeys[e.keyCode] = true; }`;
+ }
if (code.indexOf('document.createElement("eaglerpage")') > -1) {
let style = "width:100%; height: 100%; position: fixed; top: 0; left: 0; z-index: 10; color: white; font-family: Minecraftia, sans-serif; overflow-y: scroll; overflow-x: hidden; background-image: url(data:image/png;base64,UklGRhoBAABXRUJQVlA4TA0BAAAvn8AnAIWjtpEECdnA2N0DsTROy7xUqfrWw0jbyLkJKTz0+I20jTT/Bo89e1YR/Wfktm0Y+wNKLobT7QP/n/B7Z/naW26QHoTpHB7LFouyKHlzeHxfCStSuj9KdbC8z1IJ5iWiyQed48vtYJ+lUu0t4VwranS1XMIutSiLYlbb8G54uf2p3VPSfRZtSrlsPFjOzZZrd/us3B3uK+HcHJQql+xbLMrS/WqNpm6DeZ/VIPVYaN/KzUbp91nd9xl5pYu50dU2W417nbdTj5l2Ne92uM9qXNpyf6+oXkabHKXaZ1HS4Iaqpim+1KIJ+0M49/LjNbTGP5mrrMZEuc7Uzcb1ViOJ6TuOt4NGJs+zDgA=); background-color: rgb(60,60,60); background-blend-mode: multiply; background-size: 64px; ".replaceAll('; ', ';\n ')
start+= `