• Es freut uns dass du in unser Minecraft Forum gefunden hast. Hier kannst du mit über 130.000 Minecraft Fans über Minecraft diskutieren, Fragen stellen und anderen helfen. In diesem Minecraft Forum kannst du auch nach Teammitgliedern, Administratoren, Moderatoren , Supporter oder Sponsoren suchen. Gerne kannst du im Offtopic Bereich unseres Minecraft Forums auch über nicht Minecraft spezifische Themen reden. Wir hoffen dir gefällt es in unserem Minecraft Forum!

Item aus Inventar abfragen

Mr_Redstone19

Schafhirte
Registriert
31 Januar 2018
Beiträge
103
Alter
50
Diamanten
0
Hallo,
Ja ich weiß.. Ich hab eine ähnliche Frage schon gestellt, aber irgendwie ging es noch nie so wirklich mit dem Item Abfragen..
Was soll passieren: Wenn man ein Item anklickt, soll überprüft werden, ob der Spieler das Item im Inventar hat. Wenn ja, sollen ihm 2 Items abgezogen werden, oder halt der ganze ItemStack entfernt werden, wenn nur noch 2 Items übrig sind.

Das hab ich dazu programmiert:
Code:
for(ItemStack itemStack : player.getInventory().getContents()){
    if(itemStack.getType() == Material.CLAY_BRICK){
        if(itemStack.getAmount() >= 2){
            player.sendMessage("Du hast mehr als 2");
        }else{
            player.sendMessage("Du hast weniger als 2");
        }
    }else{
        player.sendMessage("Du hast dieses Item nicht");
    }
}

Das ganze hab ich gemacht, um das Item überhaupt erstmal zu überprüfen.
Die Nachricht "Du hast mehr als 2"/"Du hast weniger als 2" gibt er mir tatsächlich aus, wenn das Item auf dem 1. Slot in der Schnellzugriffsleiste liegt.
Ansonsten kommt der Fehler:

Error:
[11:02:40] [Server thread/ERROR]: Could not pass event InventoryClickEvent to BedWars v1.0
org.bukkit.event.EventException
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:310) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
    at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:1630) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at net.minecraft.server.v1_8_R3.PacketPlayInWindowClick.a(SourceFile:31) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at net.minecraft.server.v1_8_R3.PacketPlayInWindowClick.a(SourceFile:9) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_222]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_222]
    at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:715) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [spigot.jar:git-Spigot-db6de12-18fbb24]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_222]
Caused by: java.lang.NullPointerException
    at me.madebyproxxy.spigot.bedwars.listeners.ingame.VillagerInteract.onShop2(VillagerInteract.java:119) ~[?:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_222]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_222]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_222]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_222]
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot.jar:git-Spigot-db6de12-18fbb24]
    ... 15 more

Hat jemand eine Idee, woran es liegt/kennt jemand eine andere Möglichkeit?

LG
 

Mr_Redstone19

Schafhirte
Registriert
31 Januar 2018
Beiträge
103
Alter
50
Diamanten
0
Ah, hab doch noch eine Frage. Wie kann ich die Nachricht einbauen, dass kein Item vorhanden ist?
Wenn ich das als else an die Material-Abfrage hänge, kommt nichts und wenn ich es als else an die != null-Abfrage hänge, kommt es logischerweise 36 mal.
 

SirYwell

PlotSquared Entwickler
Registriert
30 Juni 2017
Beiträge
540
Diamanten
488
Minecraft
SirYwell
Auch wenn du so dein Problem lösen kannst, würde ich gerne eine Alternative vorschlagen:
Du kannst die Methode all(material) verwenden, um eine Map mit allen Slots zurückzubekommen, an denen ItemStacks des Typs material sind. Wenn die Map leer ist, hat der Spieler das Item nicht im Inventar.
Ansonsten kannst du über die Map iterieren, bis du (maximal) 2 Items entfernt hast. Das dürfte dir einiges erleichtern.
 

Mr_Redstone19

Schafhirte
Registriert
31 Januar 2018
Beiträge
103
Alter
50
Diamanten
0
Okay danke. Mal eine neue Methode, da jz aber die "alte" funktioniert und ich mich wenig mit Maps auskenne (Ja, sie sind wichtig, ich lerne sie auch gerade), würde ich lieber bei der Methode bleiben. Wo kann man die Nachricht bei der alten Methode denn einbauen?
Mit alte Methode mein ich die For-Schleife mit dem .getContents()
 

Luki_xx

Schafhirte
Registriert
12 Juni 2019
Beiträge
107
Diamanten
378
Minecraft
Luki_xx
Hallo. Also es gibt aus meiner Sicht zwei Möglichkeiten wie du das machen könntest.
Die erste:
Java:
    public static int getAmount(Inventory inv, ItemStack item)
    {
            int amount = 0;
            for(ItemStack contents : inv.getContents()) {
            if(contents == null || contents.getType() == Material.AIR) continue;
            if(contents.isSimilar(item))amount += contents.getAmount();
            }return amount;
    }
Damit fragst du mal die Anzahl ab, danach kannst du abfragen ob die Zahl größer gleich 2 ist, alle Items dieses Typs aus dem Inventar entfernen und anzahl-2 wieder hinzufügen.


Ist die einfachste aber nicht die beste Möglichkeit (grade wenig Zeit).
 

SirYwell

PlotSquared Entwickler
Registriert
30 Juni 2017
Beiträge
540
Diamanten
488
Minecraft
SirYwell
Ich geh jetzt mal davon aus, dass die Items auch entfernt werden soll, wenn weniger als 2 Items vorhanden sind. Wenn das zutrifft, dann kannst du auch mit der first-Methode arbeiten:


Remove Items:
Material material = ...; // das gesuchte Item
int toRemve = 2; // Konstante, wie viel entfernt werden soll
int removed = 0;
int index = -1;
while ((index = inventory.first(material)) != -1 && removed < toRemove) {
    if (inventory.getItem(index).getAmount() + removed <= toRemove) {
        removed += inventory.getItem(index).getAmount();
        inventory.setItem(index, null);
    } else { // Stack ist groß genug, dass einfach die Menge reduziert werden kann
        removed = toRemove;
        inventory.getItem(index).setAmount(inventory.getItem(index).getAmount() - toRemove);
    }
}

Wenn der Spieler das Item nicht im Inventar hat, ist removed nach Ablauf des Codes immer noch 0, somit kannst du auch das einfach herausfinden.
 

Mr_Redstone19

Schafhirte
Registriert
31 Januar 2018
Beiträge
103
Alter
50
Diamanten
0
So. Soweit funktioniert alles, jedoch hab ich noch 2 kleine Probleme.
Ich hab das jetzt so geändert, dass man nur noch 1 Item braucht und keine 2 mehr.

Hier mein Code zum Abfragen der anzahl der Items:
Java:
public int getAmountBronze(Inventory inventory) {
        int amount = 0;
        
        ItemStack itemStack2 = new ItemStack(Material.CLAY_BRICK, 1);
        ItemMeta itemMeta = itemStack2.getItemMeta();
        itemMeta.setDisplayName("§cBronze");
        itemStack2.setItemMeta(itemMeta);
        
        for(ItemStack itemStack : inventory.getContents()) {
            if(itemStack != null) {
                if(itemStack.isSimilar(itemStack2)) {
                    amount += itemStack.getAmount();
                }
            }
        }
        return amount;
    }

und das hier ist der Code, der die Items dann removed:

Java:
int i = getAmountBronze(player.getInventory());
                if(i == 0) {
                    player.sendMessage(main.prefix + "§7Du hast §cnicht genügend §7Ressoucen für dieses Item!");
                    player.playSound(player.getLocation(), Sound.ANVIL_LAND, 1, 1);
                }else if(i >= 1) {
                    if(i == 1) {
                        player.getInventory().addItem(new ItemAPI(Material.SANDSTONE, (byte)0, 2).buildNorm());
                        player.getInventory().remove(itemStack2);
                    }else {
                        player.getInventory().addItem(new ItemAPI(Material.SANDSTONE, (byte)0, 2).buildNorm());
                        for(ItemStack itemStack : player.getInventory().getContents()) {
                            if(itemStack != null) {
                                if(itemStack.isSimilar(itemStack2)) {
                                    itemStack.setAmount(itemStack.getAmount() -1);
                                }
                            }
                        }
                    }
                }

Jedoch gibt es 2 Probleme.
1. Wenn ich 2 Slots habe, wo je nur ein Item drauf ist, removed er kein Item mehr und gibt mir aber immer mehr Sandstein.
2. Wenn ich 2 Stacks habe, dann removed er mir von jedem Stack ein Item und gibt mir aber nur 2 Sandstein. Er soll aber nur ein Item von einem der beiden Stacks entfernen.

ich steh gerade auf dem Schlauch und weiß gerade nicht weiter..
Kennt da jemand die Lösung?
 

Luki_xx

Schafhirte
Registriert
12 Juni 2019
Beiträge
107
Diamanten
378
Minecraft
Luki_xx
Soviel mal zu deinem zweiten Problem. Du musst gehst ja jeden Inventar Slot durch, nach dem du es gefunden hast musst du abbrechen.

Java:
for(ItemStack itemStack : player.getInventory().getContents()) {
    if(itemStack != null) {
        if(itemStack.isSimilar(itemStack2)) {
            itemStack.setAmount(itemStack.getAmount() -1);
            break;
         }
     }
}

Bezüglich Problem 1 habe ich noch nicht gefunden. Allerdings muss ich sagen das du die Namen ja auch net gerade günstig gewählt hast. Ich würde dir heute Abend dafür einen schöneren Code schicken, von mir aus auf deine Art.( mit Erklärung)
 
Oben