#Block State Settings Form

1 messages · Page 1 of 1 (latest)

flint stratus
#

currently trying to figure out how to make a form settings for block states, trying to learn something new

function blockStateSettings(block, player){
    const blockForm = new ModalFormData();
    blockForm.title('Block Settings');
    const allValues = {};
    Object.keys(block.permutation.getAllStates()).forEach((state) => {
        const validValues = BlockStates.get(state).validValues;
        allValues[state] = validValues;
    });
    for(const [key, value] of Object.entries(allValues)){
        const blockState = block.permutation.getState(key);
        const states = [];
        console.error(states);

        const displayName = key.replaceAll(`_`, ` `).slice(key.search(`:`)+1);
        const capitalizedName = displayName.charAt(0).toUpperCase() + displayName.slice(1);

        blockForm.dropdown(capitalizedName, BlockStates.get(key).validValues);
    }
    console.error(JSON.stringify(allValues));
    blockForm.show(player).then((result) => {
        if(result.canceled) return;
        const values = result.formValues;
        values.forEach((value) => {
            console.error(value);
        });
    }).catch();
}```
#

currently, I managed to get the find block states to work and it also shows the dropdown and values

#

only problem is how to apply the formValues and also set the defaultIndexValue to the state the block is in

edgy linden
# flint stratus currently, I managed to get the find block states to work and it also shows the ...

Your method won't work correctly. A block may have different state values with the same state name. Use this code:

const /** @type {Record<String, Record<String, (String | Number | Boolean)[]>>} */ PermutationStateValidValuesCache = {};
const /** @type {Record<String, (String | Number | Boolean)[]>} */ PermutationStateValuesCache = {};

/**
 * @param {Block | BlockPermutation | BlockType | String} block
 * @param {String} state
 * @returns {(Boolean | Number | String)[]}
 */
function getPermutationStateValidValues(block, state) {
    const permutation = block instanceof BlockPermutation ? block : (block instanceof Block ? block.permutation : BlockPermutation.resolve(block instanceof BlockType ? block.id : block));
    const id = permutation.type.id;
    
    if (PermutationStateValidValuesCache[id] == undefined) PermutationStateValidValuesCache[id] = {};
    else if (PermutationStateValidValuesCache[id][state] != undefined) return PermutationStateValidValuesCache[id][state];

    if (PermutationStateValuesCache[id] == undefined) {
        for (const blockStateType of BlockStates.getAll()) {
            const validStates = (PermutationStateValuesCache[blockStateType.id] || []).concat(blockStateType.validValues);
            PermutationStateValuesCache[blockStateType.id] = Array.from((new Set(validStates)).values());
        }
    };

    const values = PermutationStateValuesCache[state];
    const validValues = [];
    
    for (const value of values) {
        try { permutation.withState(state, value); } catch { continue; }
        validValues.push(value);
    }

    PermutationStateValidValuesCache[id][state] = validValues;
    return validValues;
}
#

and also, u can use my "Block State Editor" as an example:

/** @param {import('@minecraft/server').Player} player @param {import('@minecraft/server').Block} block */
function openBlockEditMenu(player, block) {
    if (player.commandPermissionLevel < CommandPermissionLevel.GameDirectors) return;

    const menu = new ModalFormData();
    menu.title('Block Editor');

    menu.header('Type');
    menu.label('Tags: ' + block.getTags().join(', '));
    menu.textField('TypeId', block.typeId, { defaultValue: block.typeId });

    menu.divider();

    menu.header('States');
    for (const state of Object.keys(block.permutation.getAllStates())) {
        const validValues = f.getPermutationStateValidValues(block.permutation, state).map(String);
        menu.dropdown(state, validValues, {
            defaultValueIndex: validValues.indexOf(String(block.permutation.getState(state)))
        });
    }

    menu.show(player).then(data => {
        if (data.canceled || !player.isValid || !block.isValid) return;

        if (data.formValues[2] != block.typeId) {
            block.setType(data.formValues[2]);
        } else {
            const stateValuesIndex = data.formValues.slice(5, 5+Object.keys(block.permutation.getAllStates()).length);
            let newPermutation = block.permutation;

            Object.keys(block.permutation.getAllStates()).forEach((state, index) => {
                newPermutation = newPermutation.withState(state, f.getPermutationStateValidValues(newPermutation, state)[stateValuesIndex[index]]);
            });

            block.setPermutation(newPermutation);
        }
    });
}
flint stratus
naive island
#

Hmm

naive island
flint stratus
#

woah