Изменить lore предмета в окне результата крафта

Версия Minecraft
1.7.10
210
1
19
У меня есть итем с энергией. Заряжаю я его крафтом со слитками. При крафте перехватываю нбттэг, увеличиваю в нем кол-во энергии на какое-то количество (не полное) и кидаю в итем на выходе.

Java:
    @SideOnly(Side.CLIENT)
    public void addInformation(ItemStack item, EntityPlayer player, List lore, boolean par4)
    {
        int left = maxenergy;
        if(item.stackTagCompound != null){left = item.stackTagCompound.getInteger("Energy");}

        lore.add(StatCollector.translateToLocal("lores.antirad"));

        double leftpercent = (double)left / maxenergy;
        if(leftpercent >= 0.75D)        { lore.add(StatCollector.translateToLocal("lores.antirad.highenergy") + left + "/" + maxenergy); }
        else if(leftpercent >= 0.25D)    { lore.add(StatCollector.translateToLocal("lores.antirad.midenergy") + left + "/" + maxenergy); }
        else                             { lore.add(StatCollector.translateToLocal("lores.antirad.lowenergy") + left + "/" + maxenergy); }
        if(player.isPotionActive(RHPotionEffects.radiation)){
            int level = player.getActivePotionEffect(RHPotionEffects.radiation).getAmplifier() + 1;
            lore.add(StatCollector.translateToLocal("lores.antirad.radiationlevel") + level);
        }
    }

В классе предмета визуализация кол-ва энергии реализуется так. Но на выходе я вижу такое:
CbomGLqhlA.png


Мне нужно в код выше вставить процедуру, которая будет писать не 1200/1200, а столько, сколько получится. Один слиток добавляет 400. Если у предмета оставалось 200, то в окне выхода должно быть написано 600/1200. Как подсчитать - ежу понятно. Непонятно, как определить в процедуре AddInformation, что мышка наведена именно на слот выхода крафта. Подскажите, пожалуйста.
 
210
1
19
Вот мой рецепт:
Java:
            GameRegistry.addShapelessRecipe(new ItemStack(RHItems.antiRad, 1), new Object[] {RHItems.antiRad, RHItems.uraniumIngot}); i++;

А вот так я обеспечиваю зарядку:
Java:
        ItemStack resultstack = e.crafting;

        // Antirad Refill (energy = 1200, 400 per ingot)
        if(result == RHItems.antiRad){
            IInventory craftnet = e.craftMatrix;
            ItemStack lookfor = null;
            for(int i = 0; i < craftnet.getSizeInventory(); i++){
                if(craftnet.getStackInSlot(i) == null || craftnet.getStackInSlot(i).getItem() == null){continue;}
                if(craftnet.getStackInSlot(i).getItem() == RHItems.antiRad){lookfor = craftnet.getStackInSlot(i);} // нашли итем антирад
            }
            if(lookfor == null){return;}
            NBTTagCompound tag = new NBTTagCompound();
            if(lookfor.stackTagCompound == null){
                tag.setInteger("Energy", RHItem_AntiRad.maxenergy);
                tag.setInteger("Alarm", 0);
                lookfor.setTagCompound(tag);
            }
            int energy = lookfor.stackTagCompound.getInteger("Energy");
            energy += 400;
            if(energy > RHItem_AntiRad.maxenergy){energy = RHItem_AntiRad.maxenergy;}
            resultstack.setTagCompound(new NBTTagCompound());
            resultstack.stackTagCompound.setInteger("Energy", energy);
            resultstack.stackTagCompound.setInteger("Alarm", 0);
        }

Если не считать, что мой код написан через задний проход, отдаляясь от основной темы, как добиться желаемого результата?
Проблемы бы не было, если бы один слиток заряжал в любом случае предмет до полного.
 
Последнее редактирование:
1,007
36
206
Вот пример, как регистрировать ты уже знаешь.
Java:
public class RecipeTracker implements IRecipe
{
    private ItemStack item;
    private Random random = new Random();

    @Override
    public boolean matches(InventoryCrafting inv, World worldIn)
    {
        ItemStack itemTracker = null;
        ItemStack trackedItem = null;
        item = null;

        int nonNullSlots = 0;
        for(int i = 0; i < inv.getSizeInventory(); i++)
        {
            ItemStack stack = inv.getStackInSlot(i);
            if(stack != null)
            {
                nonNullSlots++;
                if(stack.getItem() == StatTrak.itemTracker || stack.getItem() == StatTrak.itemDefectiveTracker)
                {
                    itemTracker = stack;
                }
                else
                {
                    trackedItem = stack;
                }
            }
        }
        if(nonNullSlots == 2)
        {
            item = trackedItem;
            String s = itemTracker.getDisplayName();
            if(itemTracker.getItem() == StatTrak.itemDefectiveTracker)
            {
                s = StatCollector.translateToLocal("defective-stattrak-message-" + random.nextInt(10));
            }
            String q = StatCollector.translateToLocal("item.stattrak-tracker.name");
            String message = StatCollector.translateToLocal("stattrak-killcount");
            if(!s.equals(q)) message = s;
            if(!item.hasTagCompound()) item.setTagCompound(new NBTTagCompound());
            NBTTagCompound tags = item.getTagCompound();
            tags.setString("stattrak-message", s);
            return true;
        }
        return false;
    }

    @Override
    public ItemStack getCraftingResult(InventoryCrafting inv)
    {
        if(item == null) return null;
        ItemStack a = item.copy();
        a.addEnchantment(StatTrak.STATTRAK, 1);
        return a;
    }

    @Override
    public int getRecipeSize()
    {
        return 2;
    }

    @Override
    public ItemStack getRecipeOutput()
    {
        if(item == null) return null;
        ItemStack a = item.copy();
        a.addEnchantment(StatTrak.STATTRAK, 1);
        return a;
    }
}
 
210
1
19
Не соображаю (особенно с утра).
Сделал вот так:

Java:
GameRegistry.addRecipe(new RHRecipe(new ItemStack(RHItems.antiRad, 1), new Object[] {RHItems.antiRad, RHItems.uraniumIngot}));

Класс RHRecipe:

Java:
package ru.lao.rha.recipes;

import java.util.Random;

import ru.lao.rha.lists.RHItems;

import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;

public class RHRecipe implements IRecipe {

    private ItemStack item;
    private Random random = new Random();
    private ItemStack result;


    public RHRecipe(ItemStack result, Object ... params){
        CraftingManager.getInstance().addRecipe(result, params);
        this.result = result;
    }


    @Override
    public boolean matches(InventoryCrafting inv, World worldIn)
    {
        item = null;
        for(int i = 0; i < inv.getSizeInventory(); i++)
        {
            ItemStack stack = inv.getStackInSlot(i);
            if(stack != null)
            {
                if(stack.getItem() == RHItems.antiRad){item = stack;}
                return true;
            }
        }
        return false;
    }

    @Override
    public ItemStack getCraftingResult(InventoryCrafting inv)
    {
        if(item == null) return null;
        ItemStack in = item.copy();
        ItemStack out = item.copy();
        int energy = in.stackTagCompound.getInteger("Energy") + 400;
        out.stackTagCompound.setInteger("Energy", energy);
        return out;
    }

    @Override
    public int getRecipeSize()
    {
        return 2;
    }

    @Override
    public ItemStack getRecipeOutput()
    {
        if(item == null) return null;
        ItemStack in = item.copy();
        ItemStack out = item.copy();
        int energy = in.stackTagCompound.getInteger("Energy") + 400;
        out.stackTagCompound.setInteger("Energy", energy);
        return out;
    }
}
Клиент не запускается. Лог:
Код:
[12:14:57] [Client thread/ERROR] [FML]:
    States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
    UCHI    mcp{9.05} [Minecraft Coder Pack] (minecraft.jar)
    UCHI    FML{7.10.99.99} [Forge Mod Loader] (forgeSrc-1.7.10-10.13.4.1558-1.7.10.jar)
    UCHI    Forge{10.13.4.1558} [Minecraft Forge] (forgeSrc-1.7.10-10.13.4.1558-1.7.10.jar)
    UCHE    rha{1.0} [Russian Hostility Addon] (bin)
    UCHI    rhmusic{1.0} [RH Music] (RHMusic.jar)
[12:14:57] [Client thread/ERROR] [FML]: The following problems were captured during this phase
[12:14:57] [Client thread/ERROR] [FML]: Caught exception from rha
java.lang.ClassCastException: ru.lao.rha.items.RHItem_AntiRad cannot be cast to java.lang.Character
    at net.minecraft.item.crafting.CraftingManager.addRecipe(CraftingManager.java:209) ~[forgeSrc-1.7.10-10.13.4.1558-1.7.10.jar:?]
    at ru.lao.rha.recipes.RHRecipe.<init>(RHRecipe.java:22) ~[bin/:?]
    at ru.lao.rha.recipes.Tools.addRecipes(Tools.java:18) ~[bin/:?]
    at ru.lao.rha.recipes._Recipes.init(_Recipes.java:44) ~[bin/:?]
    at ru.lao.rha.proxies.RHCommon.init(RHCommon.java:203) ~[bin/:?]
    at ru.lao.rha.proxies.RHClient.init(RHClient.java:77) ~[bin/:?]
    at ru.lao.rha.Main.init(Main.java:56) ~[bin/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_60]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_60]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_60]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_60]
    at cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:532) ~[forgeSrc-1.7.10-10.13.4.1558-1.7.10.jar:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_60]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_60]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_60]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_60]
    at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.post(EventBus.java:275) ~[guava-17.0.jar:?]
    at cpw.mods.fml.common.LoadController.sendEventToModContainer(LoadController.java:212) ~[forgeSrc-1.7.10-10.13.4.1558-1.7.10.jar:?]
    at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:190) ~[forgeSrc-1.7.10-10.13.4.1558-1.7.10.jar:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_60]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_60]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_60]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_60]
    at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) ~[guava-17.0.jar:?]
    at com.google.common.eventbus.EventBus.post(EventBus.java:275) ~[guava-17.0.jar:?]
    at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:119) [LoadController.class:?]
    at cpw.mods.fml.common.Loader.initializeMods(Loader.java:737) [Loader.class:?]
    at cpw.mods.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:311) [FMLClientHandler.class:?]
    at net.minecraft.client.Minecraft.startGame(Minecraft.java:597) [Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:942) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_60]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_60]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_60]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_60]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
    at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
    at GradleStart.main(Unknown Source) [start/:?]
[12:14:57] [Client thread/INFO] [STDOUT]: [net.minecraft.client.Minecraft:displayCrashReport:388]: ---- Minecraft Crash Report ----
// I bet Cylons wouldn't have this problem.
 
210
1
19
Убрал 22 строчку - она лишняя. Всё заработало.
Изменил matches:
Java:
    @Override
    public boolean matches(InventoryCrafting inv, World worldIn)
    {
        item = null;
        boolean refill = false;
        for(int i = 0; i < inv.getSizeInventory(); i++)
        {
            ItemStack stack = inv.getStackInSlot(i);
            if(stack != null)
            {
                if(stack.getItem() == result.getItem()){item = stack;}
                if(stack.getItem() == RHItems.uraniumIngot){refill = true;}
            }
        }
        if(item != null && refill)return true;
        return false;
    }

И прям совсем заработало. Эх, все бы писали в своём коде подробные комментарии, как это делаю я... Доделываю.

Не понял, в чем разница между getCraftingResult и getRecipeOutput?
 
Последнее редактирование:

timaxa007

Модератор
5,831
409
672
Не понял, в чем разница между getCraftingResult и getRecipeOutput?
Если я не ошибаюсь. Один для вывода видимости результата в слоте выхода, а второй что будет после взятии из слота выхода.
 
210
1
19
Я так и подумал. В общем, я закончил, тестировать буду вечером на сервере.
Вот что у меня получилось после удаления всего мусора.

Инициализация рецептов:
Java:
jetpacks = GameRegistry.findItem("simplyjetpacks", "jetpacks");
if(jetpacks != null){
        GameRegistry.addRecipe(new RHRecipe(new ItemStack(jetpacks, 1, 101), RHItems.uraniumIngot, 18000, 18000));
        GameRegistry.addRecipe(new RHRecipe(new ItemStack(jetpacks, 1, 102), RHItems.uraniumIngot, 36000, 18000)); 
        GameRegistry.addRecipe(new RHRecipe(new ItemStack(jetpacks, 1, 103), RHItems.uraniumIngot, 72000, 18000));
        GameRegistry.addRecipe(new RHRecipe(new ItemStack(jetpacks, 1, 104), RHItems.uraniumIngot, 144000, 18000));
        GameRegistry.addRecipe(new RHRecipe(new ItemStack(jetpacks, 1, 1), RHItems.uraniumIngot, 18000, 18000));
        GameRegistry.addRecipe(new RHRecipe(new ItemStack(jetpacks, 1, 2), RHItems.uraniumIngot, 36000, 18000));
        GameRegistry.addRecipe(new RHRecipe(new ItemStack(jetpacks, 1, 3), RHItems.uraniumIngot, 72000, 18000));
        GameRegistry.addRecipe(new RHRecipe(new ItemStack(jetpacks, 1, 4), RHItems.uraniumIngot, 144000, 18000));
}
GameRegistry.addRecipe(new RHRecipe(new ItemStack(RHItems.antiRad), RHItems.uraniumIngot, RHItem_AntiRad.maxenergy, 400)); i++;


Реализация:
Java:
package ru.lao.rha.recipes;

import java.util.Random;

import ru.lao.rha.lists.RHItems;

import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;

public class RHRecipe implements IRecipe {

    private ItemStack item;
    private Item filler;
    private ItemStack result;
    private int fillers;
    private int maxenergy;
    private int energyperitem;   
    
    /**
     * Заправка итемов
     * @param result - выходной итем (он же входной)
     * @param filler - итем, которым заправляем
     * @param maxenergy - максимум энергии
     * @param energyperitem - энергии за одну единицу заправки
     */
    public RHRecipe(ItemStack result, Item filler, int maxenergy, int energyperitem){
        this.result = result;
        this.filler = filler;
        this.maxenergy = maxenergy;
        this.energyperitem = energyperitem;
    }
    
    @Override
    public boolean matches(InventoryCrafting inv, World worldIn)
    {
        int items = 0;
        fillers = 0; item = null;
        for(int i = 0; i < inv.getSizeInventory(); i++){
            ItemStack stack = inv.getStackInSlot(i);
            if(stack != null){
                if(stack.getItem() == result.getItem()){item = stack; items++;}
                if(stack.getItem() == filler){fillers++;}
            }
        }
        if(item != null && fillers > 0 && items == 1){return true;} // есть заправляемый итем, он точно один в сетке, есть минимум топлива
        return false;
    }

    @Override
    public ItemStack getCraftingResult(InventoryCrafting inv){return CalculatedStack();}

    @Override
    public ItemStack getRecipeOutput(){return CalculatedStack();}

    private ItemStack CalculatedStack() {
        if(item == null) return null;
        if(item.stackTagCompound == null){
            NBTTagCompound virgin = new NBTTagCompound();
            virgin.setInteger("Energy", maxenergy);
            item.setTagCompound(virgin);
        }
        ItemStack in = item.copy();
        ItemStack out = item.copy();
        int oldenergy = in.stackTagCompound.getInteger("Energy");
        int newenergy = oldenergy + fillers * energyperitem;
        if(newenergy - maxenergy > (energyperitem - 1)){return null;} // при чрезмерном заряде не разрешать крафт
        if(newenergy > maxenergy){newenergy = maxenergy;}
        out.stackTagCompound.setInteger("Energy", newenergy);
        return out;
    }

    @Override
    public int getRecipeSize(){ return 2; }
}

19ef9z2seX.png



Замечания по коду есть? И заодно последний вопрос. Что это: "getRecipeSize"?
 

timaxa007

Модератор
5,831
409
672
Что это: "getRecipeSize"?
Вроде как отвечает, сколько слотов входа будут задействованы. Но оно лишь используется для сортировки, что-то вроде для обозначения приоритета.
 
Сверху