Как создать массив с вещами и случайно доставать оттуда один предмет

Версия Minecraft
1.12.2
2,932
44
598
Доброго времени суток Земляне и Чужие!
Сегодня у меня появился вопрос: Как сделать массив который будет хранить предметы со стаками, и доставать рандомно один предмет из списка.
Я попытался такое провернуть через лист, но не получилось:
Java:
    @Override
    public ActionResult<ItemStack> onItemRightClick(World World, final EntityPlayer EntityPlayer, EnumHand hand) {

            ItemStack[] drops = new ItemStack[] {
            new ItemStack(DiceRegister.DICE, 1, 0),
            new ItemStack(DiceRegister.DICE, 1, 1),
            new ItemStack(DiceRegister.DICE, 1, 2),
            new ItemStack(DiceRegister.DICE, 1, 3),
            new ItemStack(DiceRegister.DICE, 1, 4),
            new ItemStack(DiceRegister.DICE, 1, 5)
            };
        
        ItemStack itemStack = EntityPlayer.getHeldItem(hand);

        if (!World.isRemote) {

            EntityPlayer.getCooldownTracker().setCooldown(this, 5);

            ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
            EntityPlayer.inventory.addItemStackToInventory(drops[World.rand.nextInt(drops.length - 1)]);

        }

        return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, itemStack);

    }
 
Решение
Попробуй так:
Java:
    private static List<ItemStack> DROPS;

    static {
        DROPS = Lists.newArrayList(
                new ItemStack(Items.DYE, 1, 0),
                new ItemStack(Items.DYE, 1, 1),
                new ItemStack(Items.DYE, 1, 2),
                new ItemStack(Items.DYE, 1, 3),
                new ItemStack(Items.DYE, 1, 4),
                new ItemStack(Items.DYE, 1, 5)
        );
    }

    @Override
    public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
        if (!world.isRemote) {
            player.getCooldownTracker().setCooldown(this, 5);
            ItemStack toDrop = DROPS.get(world.rand.nextInt(DROPS.size())).copy();
            if...
3,005
192
592
Гарик, вроде ж была уже тема от тебя, с тем же самым таском, разве нет?

И там вроде бы уже обсуждалось как и что сделать.
 
3,005
192
592
Попробуй так:
Java:
    private static List<ItemStack> DROPS;

    static {
        DROPS = Lists.newArrayList(
                new ItemStack(Items.DYE, 1, 0),
                new ItemStack(Items.DYE, 1, 1),
                new ItemStack(Items.DYE, 1, 2),
                new ItemStack(Items.DYE, 1, 3),
                new ItemStack(Items.DYE, 1, 4),
                new ItemStack(Items.DYE, 1, 5)
        );
    }

    @Override
    public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
        if (!world.isRemote) {
            player.getCooldownTracker().setCooldown(this, 5);
            ItemStack toDrop = DROPS.get(world.rand.nextInt(DROPS.size())).copy();
            if (!player.addItemStackToInventory(toDrop)) {
                player.dropItem(toDrop, false);
            }
        }
        return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand));
    }
 
2,932
44
598
Спасибо огромное! Всё усвоил, всё запомнил! ;)
Если кому-то надо::
private static List<ItemStack> DROPS;

    @Override
    public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {

        DROPS = Lists.newArrayList(
                new ItemStack(DiceRegister.DICE, 1, 0),
                new ItemStack(DiceRegister.DICE, 1, 1),
                new ItemStack(DiceRegister.DICE, 1, 2),
                new ItemStack(DiceRegister.DICE, 1, 3),
                new ItemStack(DiceRegister.DICE, 1, 4),
                new ItemStack(DiceRegister.DICE, 1, 5)
        );

        if (!world.isRemote) {

            player.getCooldownTracker().setCooldown(this, 5);
            ItemStack toDrop = DROPS.get(world.rand.nextInt(DROPS.size())).copy();

            player.inventory.clearMatchingItems(new ItemStack(DiceRegister.DICE).getItem(), -1, 1, null);

            if (!player.addItemStackToInventory(toDrop)) {
                player.dropItem(toDrop, false);
            }
        }
        return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand));
    }
 
3,005
192
592
1,200
37
237
не удалит старый лист
Я, конечно, не знаю как работает сборщик, но что-то мне подсказывает, что этот лист будет существовать до полного удаления предмета из игры...
UPD: А, так ты его переопределяешь... А зачем каждый раз?
 

Eifel

Модератор
1,623
78
608
Есть такая штука как статический блок, все что в этом блоке выполняется один раз при загрузке класса. Я думаю это то, что тебе нужно

UPD. а да, он и есть в примере. Но ты почему-то все сделал наоборот
 
1,200
37
237
статический блок
Тогда загрузка класса должна быть после инициализации всех предметов в списке лута (на случай предметов из модов), иначе NullPo словим (по крайней мере на 1.7, в 1.12 мб просто пустые стаки будут).
 
2,932
44
598
3,005
192
592
Тогда нужно инициализировать лист ПОСЛЕ регистрации предметов. Например - в Init / postInit.
 
1,200
37
237
Так это блок что ли?

Это не оправдывает то, что ты сунул static {} в метод.

Либо лист собирай после инициализации всех его составляющих (как написал Doc), либо сам блок (или что это у тебя) с листом (если через static {} наполняешь) инициализируй последним.
 
Сверху