Своя стрела для ванильного лука "прямым способом")

Версия Minecraft
1.12+
917
22
332
:)
Собственно, я рехнулся сделал свою стрелу, свой entity, свой рендер стрелы, и в целом всё работает. Даже лук используя мои стрелы готов стрелять. Но стрелу призывает ванильную. Делать свой лук нежелательно, и хотелось бы решить всё мирным путём (без хуков).
Надеюсь на ваш совет!
P.S. Напишите если потребуется код.
 
3,005
192
592
Ты хочешь что бы _ванильный_ лук стрелял _твоими_ стрелами, так?
 
3,005
192
592
Значит нужно делать хуки.
Потому что это !ВанильныЙ! лук и это !ТвоИ! стрелы.
Без хуков или ASM ты не сделаешь.
 
917
22
332
Значит нужно делать хуки.
Потому что это !ВанильныЙ! лук и это !ТвоИ! стрелы.
Без хуков или ASM ты не сделаешь.
Спасибо, за совет, и за участие.
Тем не менее я нашёл способ с радиусом поражения немного поменьше в виде ForgeEventFactory.onArrowLoose
Оно меня не совсем устраивает, однако не костыль.
Здесь, я прерываю ванильный метод, ещё до создания экземпляра EntityArrow, и аналогичным кодом вызываю свой entity.
Вот, может кому-то пригодится...
В EventHandler нужно добавить эти три метода:
Java:
    @SubscribeEvent
    public static void onPlayerLooseArrow(ArrowLooseEvent event) {
        EntityPlayer player = event.getEntityPlayer();
        boolean flag = event.hasAmmo();
        ItemStack stack = findAmmo(player);
        if (flag && stack.getItem() == ListItem.ENDER_ARROW) {
            event.setCanceled(true);
            World world = event.getWorld();
            if (stack.isEmpty()) stack = new ItemStack(Items.ARROW);

            float f = ItemBow.getArrowVelocity(event.getCharge());

            if ((double)f >= 0.1D) {
                boolean flag1 = player.capabilities.isCreativeMode || ((EnderArrow) stack.getItem()).isInfinite(stack, stack, player);

                if (!world.isRemote) {
                    EnderArrow arrow = (EnderArrow)(stack.getItem());
                    EMEnderArrow entityarrow = arrow.createArrow(world, player);
                    entityarrow.setAim(player, player.rotationPitch, player.rotationYaw, 0.0F, f * 3.0F, 1.0F);

                    if (f == 1.0F) entityarrow.setIsCritical(true);

                    int j = EnchantmentHelper.getEnchantmentLevel(Enchantments.POWER, stack);

                    if (j > 0) entityarrow.setDamage(entityarrow.getDamage() + (double)j * 0.5D + 0.5D);

                    int k = EnchantmentHelper.getEnchantmentLevel(Enchantments.PUNCH, stack);

                    if (k > 0) entityarrow.setKnockbackStrength(k);

                    if (EnchantmentHelper.getEnchantmentLevel(Enchantments.FLAME, stack) > 0) entityarrow.setFire(100);

                    stack.damageItem(1, player);

                    if (flag1 || player.capabilities.isCreativeMode) entityarrow.pickupStatus = EntityArrow.PickupStatus.CREATIVE_ONLY;

                    world.spawnEntity(entityarrow);
                }

                world.playSound((EntityPlayer)null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_ARROW_SHOOT, SoundCategory.PLAYERS, 1.0F, 1.0F / (new Random().nextFloat() * 0.4F + 1.2F) + f * 0.5F);

                if (!flag1 && !player.capabilities.isCreativeMode) {
                    stack.shrink(1);

                    if (stack.isEmpty()) {
                        player.inventory.deleteStack(stack);
                    }
                }

                player.addStat(StatList.getObjectUseStats(stack.getItem()));
            }
        }
    }

    private static ItemStack findAmmo(EntityPlayer player) {
        if (isEnderArrow(player.getHeldItem(EnumHand.OFF_HAND))) { return player.getHeldItem(EnumHand.OFF_HAND);}
        else if (isEnderArrow(player.getHeldItem(EnumHand.MAIN_HAND))) return player.getHeldItem(EnumHand.MAIN_HAND);
        else for (int i = 0; i < player.inventory.getSizeInventory(); ++i) {
            ItemStack stack = player.inventory.getStackInSlot(i);
  
            if (isEnderArrow(stack)) return stack;
        }
  
        return ItemStack.EMPTY;
    }

    private static boolean isEnderArrow(ItemStack stack) {
        return stack.getItem() == ListItem.ENDER_ARROW;
    }
 
Последнее редактирование:
3,005
192
592
3,005
192
592
Но совместимость, будет лучше.
Совместимость с чем? С ванилью? Возможно.
С модами? Ну, скорее всего **ЛЮБОЙ** лук, который скопирован с ванили (как мне кажется 90+ %) будут сломаны и будут стрелять твоими чудо стрелами..
Ну, за то не хуки, что сказать...
 
917
22
332
Честно, не понимаю. Я выполняю точную копию ванильного метода поиска стрел - findAmmo, и если это мои стрелы, прерываю метод из лука, и выполняю свой код. Какая разница, каким луком кто будет стрелять, если моих стрел нет - мой код просто не выполнится. Разве не так?
 
Последнее редактирование:

GoogleTan

Картошка :3
1,354
43
310
Предмет стрелы унаследуй от майновской стрелы и переопредели метод createArrow:
Java:
    public EntityArrow createArrow(World worldIn, ItemStack stack, EntityLivingBase shooter)
    {
        EntityTntArrow entitytippedarrow = new EntityTntArrow(worldIn, shooter);
        entitytippedarrow.setPotionEffect(stack);
        return entitytippedarrow;
    }
И без костылей.
 
917
22
332
Предмет стрелы унаследуй от майновской стрелы и переопредели метод createArrow:
Java:
    public EntityArrow createArrow(World worldIn, ItemStack stack, EntityLivingBase shooter)
    {
        EntityTntArrow entitytippedarrow = new EntityTntArrow(worldIn, shooter);
        entitytippedarrow.setPotionEffect(stack);
        return entitytippedarrow;
    }
И без костылей.
Это так не работает. Сейчас уже не помню почему, но кажется в самом луке, в методе onUseFinish, жёстко закодированы стрелы. Не instanceof, а x == Items.ARROW || x == Items.TRIPPED_ARROW. Да, моя стрела будет потрачена. Нет, entity стрелы будет стандартным, ванильным. Возможно я и ошибся тогда. В любом случае, спасибо за уточнение, я посмотрю это ещё раз, когда найду время.
 
Сверху