ModelRegistryEvent для метадаты item'а

Версия Minecraft
1.12.2
83
3
В учебнике говорится: "Создадим метод с событием ModelRegistryEvent ". Я не понимаю, что означает "метод с событием". Он (метод) должен возвращать ModelRegistryEvent или что?
"(не забудьте зарегистрировать его!) " - кого? Метод или событие? Регистрировать где, в init в CommomProxy?
Действительно ли мета лучше для создания однотипных предметов по типу оконной рамы (из дуба, березы, акации..)? Или же для каждой рамы создавать свой класс (но это же тупо)?

На всякий случай, чтобы не искать: для чайников про мету
 
Решение
Всё, я понял тебя. У меня была такая же проблема. Я её решил так: отдельная регистрация для предметов в подтипами в которой, я прохожусь for-ом по массиву материалов private static final ArrayList<BlockPlanks.EnumType> handleMaterials = new ArrayList<>(Stream.of(BlockPlanks.EnumType.values()).collect(Collectors.toList())); и создаю новый предмет с этим материалом.
Получается что-то вроде этого:
Код:
public BaseItem(String name, String type) {
        this.setRegistryName(name);
        this.setUnlocalizedName(name);
        switch (type) {
            case "item":
                ItemsRegister.addItem(name, this);
            case "subtype":
                break; //Тут можно что-то делать, ну вдруг понадобится
        }
    }
...
7,099
324
1,509
83
3
Тааак, т.е.:

Код:
public void methodWithEvent(){
    if(MinecraftForge.EVENT_BUS.post(new ModelRegistryEvent(/*здесь ничего?*/))){
        //Код из учебника, если на этом примере разбирать
       
        final Item APPLE = ItemsRegister.APPLE;
        for (AppleTypes type : AppleTypes.values()){
            ModelLoader.setCustomModelResourceLocation(APPLE, type.ordinal(), new ModelResourceLocation(APPLE.registryName() + "_" + type.name.toLowerCase(), "inventory"));
        }
    }
}

Хм, а регать где? Или для этого уже нужно EventsHandler юзать. Так, стоп. А EventsHandler то нигде не светится, ни в классе мода, ни в проксях.
 
83
3
Аааа! Это так делается? Но до сих пор не понял, а что именно регистрировать в CommonProxy в preInit нужно?

Код:
@SubscribeEvent
public void methodWithEvent(ModelRegistryEvent e){
    final Item APPLE = ItemsRegister.APPLE;
    for (AppleTypes type : AppleTypes.values()){
        ModelLoader.setCustomModelResourceLocation(APPLE, type.ordinal(), new ModelResourceLocation(APPLE.registryName() + "_" + type.name.toLowerCase(), "inventory"));
    }
}
 
7,099
324
1,509
83
3
Эх, а ведь я уже думал, что стал понимать:D
Тут_название_вашего_класса - это как раз класс item'а с метой. Значит в нем должен быть methodWitchEvent
Соответственно MinecraftForge.EVENT_BUS.register(new Тут_название_вашего_класса()) находится в классе EventsHandler
Прошу прощения, пока у меня не сложилась целостная картина работы с метой (а точнее пока что с ее регистрацией).

И еще вопрос появился. В учебнике говорится про метод getSubItems , но где он вызывается? Да и methodWithEvent тоже пока без дела создан:(
 
7,099
324
1,509
Пожалуйста, прочитай полностью хотя бы одну статью про события(я же выше дал ссылки). Все сразу станет понятно, что делать.
ModelRegistryEvent - это событие во время которого можно зарегистрировать модели для предметов(и блоков) при помощи ModelLoader.setCustomModelResourceLocation
 

ReyMagos

Тег-бомбастер
412
7
121
Java:
@Mod.EventBusSubscriber(modid = ModID) //аннотация перед классом
public class MyClass {
  
    @SubscribreEvent // аннотация перед методом
    public static void myMethod(ModelRegistryEvent event) { // обязательно статик
        //что то делаешь
    }
}
В 1.12.2 можно в начале класса писать @Mod.EventBusSubscriber(modid = *твой айди*) и тогда ничего регистрировать не надо.
А в начале твоего метода, который принимает в себя ивент, как аргумент надо писать @SubscribeEvent.
 
Последнее редактирование:
83
3
Вернулся, перепрочитал, что-то понял, что-то не понял, запутался.
Rey838, так вот собственно этот MyClass и есть EventsHandler. Этот код есть и у меня, из учебника. Что регистрировать - понятно (шину). Где регистрировать - понятно (в preInit в CommonProxy). Что сделать, чтобы не регистрировать - тоже понятно (твой ответ).

И со структурой тоже, вроде, разобрался. В игре по-прежнему N одинаковых item'ов, их unlocalizedName общий. И я предполагаю, что ошибка в том, что методы
getByMeta из enum StaffTypes из class ItemStaff,
getSubItems из class ItemStaff,
registerStaffs(ModelRegistryEvent e) из EventsHandler
нигде не используются.
Вопрос: что должно вызывать эти методы?

На всякий случай EventsHandler и класс item'а:
Java:
@Mod.EventBusSubscriber(modid = Witch.MODID)
public class EventsHandler {
    @SubscribeEvent
    public static void registerStaffs(ModelRegistryEvent e){
        final Item stuff = ItemsRegister.itemsMap.get("staff");
        for (ItemStaff.StaffTypes type : ItemStaff.StaffTypes.values()) {
            ModelLoader.setCustomModelResourceLocation(stuff, type.ordinal(), new ModelResourceLocation(stuff.getRegistryName() + "_", "inventory"));
        }
    }
}
Java:
public class ItemStaff extends Item {
    public static final String name = "staff";

    public ItemStaff(){
        this.setRegistryName(name);
        this.setUnlocalizedName(name);
        this.setCreativeTab(Witch.CTAB);
        this.setMaxStackSize(1);
        this.setHasSubtypes(true);
    }

    public enum StaffTypes {
        //от нуля
        oak, spruce, birch, jungle, acacia, darkoak;

        //получение типа по метадате
        public static StaffTypes getByMeta(int meta) {
            for (StaffTypes type : values()) {
                if (type.ordinal() == meta) return type;
            }
            return null;
        }
    }
    @Override
    public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> items) {
        if (tab == Witch.CTAB){
            for (StaffTypes type : StaffTypes.values()){
                items.add(new ItemStack(this, 1, type.ordinal()));
            }
        }
    }

}
 

ReyMagos

Тег-бомбастер
412
7
121
Всё, я понял тебя. У меня была такая же проблема. Я её решил так: отдельная регистрация для предметов в подтипами в которой, я прохожусь for-ом по массиву материалов private static final ArrayList<BlockPlanks.EnumType> handleMaterials = new ArrayList<>(Stream.of(BlockPlanks.EnumType.values()).collect(Collectors.toList())); и создаю новый предмет с этим материалом.
Получается что-то вроде этого:
Код:
public BaseItem(String name, String type) {
        this.setRegistryName(name);
        this.setUnlocalizedName(name);
        switch (type) {
            case "item":
                ItemsRegister.addItem(name, this);
            case "subtype":
                break; //Тут можно что-то делать, ну вдруг понадобится
        }
    }
Код:
public class ItemKey extends ItemMultitexture {
    public ItemKey() {
        super("key", "item");
    }
  
    public ItemSpear(Integer handleMaterial) {
        super("key", handleMaterial);
        this.setHasSubtypes(true);
    }
}
Код:
public class ItemMultitexture extends BaseItem {
    public ItemMultitexture(String name, int handleMaterial) {
        super(BlockPlanks.EnumType.byMetadata(handleMaterial).getName().toLowerCase() + "_" + name, "subtype");
    }
}
Код:
public class ItemsRegister {
    private static final ArrayList<BlockPlanks.EnumType> handleMaterials = new ArrayList<>(Stream.of(BlockPlanks.EnumType.values()).collect(Collectors.toList()));
    private static final HashMap<String, BaseItem> items = new HashMap<>();

    public static ItemKey key = new ItemKey();

    public static void registerItems() {
        for (BaseItem item : items.values()) {
            if (item.getHasSubtypes()) {
                setRegisterForSubtypesItems(item, item.getClass().getName());
                continue;
            }
            setRegister(item);
        }
    }

    private static void setRegister(BaseItem item) {
        ForgeRegistries.ITEMS.register(item);
    }

    private static void setRegisterForSubtypesItems(BaseItem item, String className) {
        Class<?> clazz;
        Constructor<?> constructor;
        BaseItem subItem = null;
            for (BlockPlanks.EnumType type : handleMaterials) {
                try {
                    clazz = Class.forName(className);
                    constructor = clazz.getConstructor(Integer.class);
                    Object object = constructor.newInstance(type.getMetadata());
                    subItem = (BaseItem) object;
                    ForgeRegistries.ITEMS.register(subItem);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    }


    public static void addItem(String name, BaseItem item) {
        items.put(name, item);
    }

    public static Item getItem(String name) {
        return items.get(name);
    }
}
 
83
3
Rey838, ох, к сожалению, я не совсем понял тебя:( Получается, ты вместо того, чтобы создавать классы вручную, просто автоматизировал этот процесс. Хотя setHasSubtypes присутствует.

По мотивам твоего кода, был создан этот недокостыль, который решил этот вопрос.

Код:
public class ItemStaff2 extends Item {
    private static final String name = "staff";
    private String strId;
    public ItemStaff2(String _name){
        this.strId = this.name + "_" + _name;
        this.setRegistryName(this.strId);
        this.setUnlocalizedName(this.strId);
        this.setCreativeTab(Witch.CTAB);
    }
    public String getName(){
        return this.strId;
    }
    public static void init(){
        List<String> pseudMeta = new ArrayList<String>();
        pseudMeta.add("oak");
        pseudMeta.add("spruce");
        pseudMeta.add("birch");
        pseudMeta.add("jungle");
        pseudMeta.add("acacia");
        pseudMeta.add("darkoak");
        for(String pMeta : pseudMeta){
            ItemStaff2 staff2 = new ItemStaff2(pMeta);
            itemsMap.put(staff2.getName(), staff2);//itemsMap из itemsRegister
        }
    }
}
Минус в том, что это пока не оптимизированно, и придется делать для каждого объекта, который предполагает использование меты:(
 
7,099
324
1,509
@Rey838 это что ,костыль, регистрирующий много итемов вместо юза метадаты?

setCustomModelResourceLocation(stuff, type.ordinal(), new ModelResourceLocation(stuff.getRegistryName() + "_", "inventory"));
Ты устанавливаешь одну и ту же модель всем вариантам предмета. Если хочешь разные, то нужно ModelResourceLocation делать зависимой от i
Если хочешь разные имена для всех предметов, то можно юзать getLocalisedName или че-то такое
 

ReyMagos

Тег-бомбастер
412
7
121
Сверху