Referencing ItemStacks Properly

Discussion in 'Plugin Development' started by Demyxa, Aug 8, 2020.

Thread Status:
Not open for further replies.
  1. Offline

    Demyxa

    Yet another question that I could probably figure out myself but it's far too hot.

    I have two classes, let's just call them ClassA and ClassB. In class A, I have created an ItemStack, defined as follows:

    Code:
    public class ClassA {
      
     
        public static ItemStack ItemA;
    
        public static void craftItemA() {
    
            Potion potion = new Potion(PotionType.WATER);
            ItemStack ItemA = potion.toItemStack(1);
    Now in ClassB, I want to use this Item in a crafting recipe for ItemB, as such I obviously need to reference ItemA in ClassB, which I did as follows:


    Code:
    public class ClassB {
      
      
    
        public static void craftItemB() {
          
            ItemStack ItemA = ClassA.ItemA;
            Bukkit.broadcastMessage("" + ItemA);
    That last line is for me to know if the recipe loaded properly, which outputs "null" no matter what I do. To me that means I did something wrong in referencing the ItemA from ClassA, but I dunno what.
     
  2. Offline

    Strahan

    The static keyword is not meant for easing cross class access. People constantly abuse it for that. You should just use dependency injection.

    Anyway, ItemA will be null until craftItemA() has been called.
     
  3. Offline

    Demyxa

    @Strahan

    Edit (Again): Nope, still outputs null, even when calling "craftItemA" within classB.
     
    Last edited: Aug 12, 2020
  4. Offline

    bowlerguy66

    @Demyxa Why use a variable to contain the ItemStack? Will the item change? If not, you could just make craftItemA() return an ItemStack and then you could use it with static access.
    Code:
            ItemStack ItemA = ClassA.craftItemA();
     
  5. Offline

    Strahan

    It'd have helped if you posted the full code. Without seeing the process / methodology, it's difficult to say where the issue is. When I want to share something, I typically setup my plugin as such. This assumes I want a list of locked players to be available to commands and events:

    Code:
    Primary class MyPlugin {
      private List<UUID> lockedPlayers = new ArrayList<>();
    
      onEnable {
        register event(new PlayerInteract(this));
        setExecutor("blahcmd", new Blah(this));
      }
    
      public Boolean togglePlayerLock(UUID player) {
        if (isLocked(player)) {
          lockedPlayers.remove(player);
          return false;
        }
        lockedPlayers.add(player);
        return true;
      }
    
      public Boolean isLocked(UUID player) {
        return lockedPlayers.contains(player);
      }
    
      public List<UUID> getLockedPlayers() {
        return lockedPlayers;
      }
    }
    
    Event class PlayerInteract {
      private MyPlugin plugin;
    
      public PlayerInteract(MyPlugin plugin) {
        this.plugin = plugin;
      }
    
      event {
        if (plugin.isLocked(e.getPlayer().getUniqueId())) return;
        // that's my preferred method; providing "function" methods instead of "bare metal" object access
    
        if (plugin.getLockedPlayers().contains(e.getPlayer().getUniqueId())) return;
        // that's the "bare metal" object access; just getting the object and performing operations against it
      }
    }
    
    Command class Blah {
      private MyPlugin plugin;
    
      public PlayerInteract(MyPlugin plugin) {
        this.plugin = plugin;
      }
    
      onCommand {
        // I can access the locked players here in yet another class using the exact same methodology
      }
    }
    That's dependency injection. I have one instance in main, I initialize it there and it's available to any class that gets the instance.
     
  6. Offline

    Demyxa

    In that case lemme run you through it (I'm also just gonna drop the "classA" and "classB" pseudonames):

    What I'm trying to create is a medicine plugin, which also includes Morphine being craftable from Opium.

    Code:
     public void registerRecipes() {
             Bandages.craftBandages();
             IcePack.craftIcepack();
             PainKillers.craftPainKillers();
             Vitamins.craftVitamins();
             Opium.craftOpium();
             Morphium.craftMorphium();
             Antibio.craftAntiBio();
    }
    This code is in my main class, where I register all my recipes. As you can see, Opium and Morphine are different classes here.

    Code:
    public class Opium {
       
        public static ItemStack Opium20;
        public static ItemStack Opium100; //Using 2 different ItemStacks as I want the player to use 5  lesser opium to make a full dose.
    
        public static void craftOpium() {ShapedRecipe opi20 = new ShapedRecipe(Opium20);
            ShapedRecipe opi = new ShapedRecipe(Opium100);
           
            opi.shape(" P ","OOO","OBO");
            opi20.shape("MMM", "EBE", "MMM");
    
           
            opi.setIngredient('O', Opium20);
            opi.setIngredient('P', Material.BLAZE_POWDER);
            opi.setIngredient('B', Material.GLASS_BOTTLE);
           
            opi20.setIngredient('M', Material.POPPY);
            opi20.setIngredient('B', Material.GLASS_BOTTLE);
            opi20.setIngredient('E', Material.GHAST_TEAR);
    
            Bukkit.getServer().addRecipe(opi20);
            Bukkit.broadcastMessage("Rezept für Opium (20%) geladen.");
           
            Bukkit.getServer().addRecipe(opi);
    
    
    THIS code is the Opium class. I left out the entire process of giving the ItemStacks their details, it's not likely the problem.

    Code:
    public class Morphium {
       
       
        static ItemStack opium;
    
        public static void craftMorphium() {ShapedRecipe morphium = new ShapedRecipe(Morph);
    
            morphium.shape(" B ", "RRR", "OGO");
    
            morphium.setIngredient('R', Material.REDSTONE);
            morphium.setIngredient('G', Material.GLASS_BOTTLE);
            morphium.setIngredient('O', opium);
            morphium.setIngredient('B', Material.BLAZE_ROD);
    
    
            Bukkit.getServer().addRecipe(morphium);
    And this is the Morphine class. Again, just the part where I try to implement the opium itemstack into the morphine class and the recipe I wish to use.
     
Thread Status:
Not open for further replies.

Share This Page