Custom mod element

Started by Azzier on Tue, 09/06/2022 - 14:07

Topic category: Help with MCreator software

Last seen on 09:50, 28. Nov 2022
Joined Oct 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
Custom mod element
Tue, 09/06/2022 - 14:07

I'm making custom mod element with new java plugins. The only problem I ran into was how to get a mod list of items (of the type I created) in procedure blocks.

 

When you create custom entity it's available in procedure blocks as "CUSTOM: <name>". Can't really find a way to do this with custom mod element. 

It uses a custom Blockly…
Tue, 09/06/2022 - 16:08

It uses a custom Blockly argument. Check how this block is made in its Json file.

Last seen on 09:50, 28. Nov 2022
Joined Oct 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
From what i understand, it…
Wed, 09/07/2022 - 05:59

From what i understand, it uses blockly named field_data_list_selector. This calls a method in mcreator that opens this selector in line 59.

 

```

javabridge.openEntrySelector(this.type, {

```

 

However in mcreator source code (i mean file net/mcreator/ui/blockly/BlocklyJavaScriptBridge.java), after looking at the class i assume it handles it, i guess it does not return custom mod elements, only built in ones (mcreator uses switch case for different mod elements), otherwise returns nothing or datalist only. :<

Last seen on 12:54, 7. Sep 2022
Joined Nov 2017
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
You can try setting the…
Wed, 09/07/2022 - 11:50

You can try setting the custom element recipe type to ITEM or BLOCK. This should add your mod element to the list of blocks/items

Last seen on 09:50, 28. Nov 2022
Joined Oct 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
It doesn't help. Im preety…
Thu, 09/08/2022 - 09:59

It doesn't help.

Im preety sure its about this method in javascript "field_data_list_selector.js" in line 58

javabridge.openEntrySelector(this.type, {

I understant this calls a method in MCreator in "net.mcreator.ui.blockly.BlocklyJavascriptBridge". It activates method in lne 123:

public void openEntrySelector(@Nonnull String type, JSObject callback) {
String var10000;
        switch (type) {
            case "entity":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadAllEntities(w).stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.entity.message", new Object[0]), L10N.t("dialog.selector.entity.title", new Object[0]));
                break;
            case "spawnableEntity":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadAllSpawnableEntities(w).stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.entity.message", new Object[0]), L10N.t("dialog.selector.entity.title", new Object[0]));
                break;
            case "biome":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadAllBiomes(w).stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.biome.message", new Object[0]), L10N.t("dialog.selector.biome.title", new Object[0]));
                break;
            case "sound":
                var10000 = this.openStringEntrySelector(ElementUtil::getAllSounds, L10N.t("dialog.selector.sound.message", new Object[0]), L10N.t("dialog.selector.sound.title", new Object[0]));
                break;
            case "effect":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadAllPotionEffects(w).stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.potion_effect.message", new Object[0]), L10N.t("dialog.selector.potion_effect.title", new Object[0]));
                break;
            case "potion":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadAllPotions(w).stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.potion.message", new Object[0]), L10N.t("dialog.selector.potion.title", new Object[0]));
                break;
            case "achievement":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadAllAchievements(w).stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.advancement.message", new Object[0]), L10N.t("dialog.selector.advancement.title", new Object[0]));
                break;
            case "particle":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadAllParticles(w).stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.particle.message", new Object[0]), L10N.t("dialog.selector.particle.title", new Object[0]));
                break;
            case "procedure":
                var10000 = this.openStringEntrySelector((w) -> {
                    return (String[])w.getModElements().stream().filter((mel) -> {
                        return mel.getType() == ModElementType.PROCEDURE;
                    }).map(ModElement::getName).toArray((x$0) -> {
                        return new String[x$0];
                    });
                }, L10N.t("dialog.selector.procedure.message", new Object[0]), L10N.t("dialog.selector.procedure.title", new Object[0]));
                break;
            case "enchantment":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadAllEnchantments(w).stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.enchantment.message", new Object[0]), L10N.t("dialog.selector.enchantment.title", new Object[0]));
                break;
            case "arrowProjectile":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadArrowProjectiles(w).stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.projectile.message", new Object[0]), L10N.t("dialog.selector.projectile.title", new Object[0]));
                break;
            case "fireballProjectile":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadFireballProjectiles().stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.projectile.message", new Object[0]), L10N.t("dialog.selector.projectile.title", new Object[0]));
                break;
            case "throwableProjectile":
                var10000 = this.openDataListEntrySelector((w) -> {
                    return ElementUtil.loadThrowableProjectiles().stream().filter((e) -> {
                        return e.isSupportedInWorkspace(w);
                    }).toList();
                }, L10N.t("dialog.selector.projectile.message", new Object[0]), L10N.t("dialog.selector.projectile.title", new Object[0]));
                break;
            default:
                if (type.startsWith("procedure_retval_")) {
                    VariableType variableType = VariableTypeLoader.INSTANCE.fromName(StringUtils.removeStart(type, "procedure_retval_"));
                    var10000 = this.openStringEntrySelector((w) -> {
                        return ElementUtil.getProceduresOfType(w, variableType);
                    }, L10N.t("dialog.selector.procedure.message", new Object[0]), L10N.t("dialog.selector.procedure.title", new Object[0]));
                } else {
                    var10000 = !DataListLoader.loadDataList(type).isEmpty() ? this.openDataListEntrySelector((w) -> {
                        return DataListLoader.loadDataList(type).stream().filter((e) -> {
                            return e.isSupportedInWorkspace(w);
                        }).toList();
                    }, L10N.t("dialog.selector." + type + ".message", new Object[0]), L10N.t("dialog.selector." + type + ".title", new Object[0])) : "," + L10N.t("blockly.extension.data_list_selector.no_entry", new Object[0]);
                }
        }

        String retval = var10000;
        callback.call("callback", new Object[]{retval});
    }

 

I suspect that's why I can't do it. I don't see there any code that would return list of custom elements user made from my mod element (only datalist if exists).

Last seen on 09:50, 28. Nov 2022
Joined Oct 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
    Okay, it works now but i…
Tue, 09/13/2022 - 10:05

 

 

Okay, it works now but i had to make 3 custom classes and 2 static methods: 

  • BlocklyJavascriptBridge, just added small if in Default case that checks if there exists modelement type with given type in string
  • BlocklyPanel, it was necessary for using this class i mentioned above
  • ProcedureGUI, just to add my custom BlocklyPanel as a bridge, but class replaces original gui
// part of method in line 128 in BlocklyJavascriptBridge

default -> {
                if (registryExists(type)) {
                    yield openDataListEntrySelector(
                            w -> loadAllCustomElements(w,type).stream().filter(e -> e.isSupportedInWorkspace(w)).toList(),
                            L10N.t("dialog.selector."+ type +".message"), L10N.t("dialog.selector."+ type +".title"));
                }

 

// code for returning if customelement exists

private static boolean registryExists(String type) {
        for (ModElementType<?> mod : ModElementTypeLoader.REGISTRY){
            if(mod.getRegistryName().equals(type)){
                return true;
            }
        }
        return false;
    }
//two methods made like other in ElementUtil, but to return custom mod elements

public static List<DataListEntry> loadAllCustomElements(Workspace workspace, String type) {
        List<DataListEntry> retval = getCustomElementsOfType(workspace, type);
        retval.addAll(DataListLoader.loadDataList(type));
        Collections.sort(retval);
        return retval;
    }

    private static List<DataListEntry> getCustomElementsOfType(@Nonnull Workspace workspace, String type) {
        return workspace.getModElements().stream().filter(mu -> mu.getType().getRegistryName().equals(type)).map(DataListEntry.Custom::new)
                .collect(Collectors.toList());
    }