Skocz do zawartości
  • 0

Przedmioty z configu


Virosel

Pytanie

Cześć,

Chciałem zapytać w jaki sposób mogę wyciągnąć z configu wiele ItemStack'ów, np.: DHx5Iav.png

"Tytuł" listy, to slot, a co do reszty łatwo się domyślić. Z góry dzięki za pomoc.

 

 

 

     

Edytowane przez Wojciu
Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/
Udostępnij na innych stronach

  • Odpowiedzi 83
  • Dodano
  • Ostatniej odpowiedzi

Top użytkownicy dla tego pytania

Rekomendowane odpowiedzi

  • 0
for (final String s : cfg.getConfigurationSection("Items.Sell").getKeys(false)) {
	final String path = "Items.Sell." + s;
	final ItemStack item = new ItemStack(Material.matchMaterial(cfg.getString(path + ".material")), 1);
}

Powinno działać, nie testowane

Skrót cfg to konfiguracja pliku, którą można uzyskać poprzez FileConfiguration lub YamlConfiguration, poniżej linki przydatne

https://bukkit.gamepedia.com/Configuration_API_Reference

https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/configuration/file/YamlConfiguration.html

https://hub.spigotmc.org/javadocs/spigot/org/bukkit/configuration/file/FileConfiguration.html

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249757
Udostępnij na innych stronach

  • 0
39 minut temu, HotAngel2K17 napisał:

for (final String s : cfg.getConfigurationSection("Items.Sell").getKeys(false)) {
	final String path = "Items.Sell." + s;
	final ItemStack item = new ItemStack(Material.matchMaterial(cfg.getString(path + ".material")), 1);
}

Powinno działać, nie testowane

Skrót cfg to konfiguracja pliku, którą można uzyskać poprzez FileConfiguration lub YamlConfiguration, poniżej linki przydatne

https://bukkit.gamepedia.com/Configuration_API_Reference

https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/configuration/file/YamlConfiguration.html

https://hub.spigotmc.org/javadocs/spigot/org/bukkit/configuration/file/FileConfiguration.html

 

 

Czyli w miejsce "cfg" moge wpisac odniesienie do Main'a, tak?

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249762
Udostępnij na innych stronach

  • 0
26 minut temu, Virosel napisał:

 

 

Czyli w miejsce "cfg" moge wpisac odniesienie do Main'a, tak?

Nie (chyba, że źle zrozumiałem), zgaduję, że przedmioty znajdują się w pliku config.yml, czyli podstawowy config.

Możesz uzyskać cfg tak:

FileConfiguration cfg = plugin.getConfig();

plugin możesz uzyskać poprzez odniesienie do instancji klasy głównej lub z pomocą czegoś takiego:

Main plugin;

public Klasa(Main plugin) {
	this.plugin = plugin
}

public void load() {
	FileConfiguration cfg = plugin.getConfig();
}

Main to jest nazwa twojej klasy.

a instancję klasy np. w taki sposób (w klasie glównej)

public static Klasa getInstance() {
	return getPlugin(Klasa.class);
}

 

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249765
Udostępnij na innych stronach

  • 0
2 minuty temu, HotAngel2K17 napisał:

Nie (chyba, że źle zrozumiałem), zgaduję, że przedmioty znajdują się w pliku config.yml, czyli podstawowy config.

Możesz uzyskać cfg tak:


FileConfiguration cfg = plugin.getConfig();

plugin możesz uzyskać poprzez odniesienie do instancji klasy głównej lub z pomocą czegoś takiego:


Main plugin;

public Klasa(Main plugin) {
	this.plugin = plugin
}

public void load() {
	FileConfiguration cfg = plugin.getConfig();
}

Main to jest nazwa twojej klasy.

a instancję klasy np. w taki sposób (w klasie glównej)


public static Klasa getInstance() {
	return getPlugin(Klasa.class);
}

 

 

 

A jednak mimo wszystko działa, wpisałem po prostu Main.getInst.getConfig() i cała reszta. Dzięki za pomoc :)

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249766
Udostępnij na innych stronach

  • 0
37 minut temu, Virosel napisał:

 

Póki nie zamknęli pytania to poruszę jeszcze jeden wątek, nie wiesz może w jaki sposób dodać enchanty do tych itemków?

is.addEnchantment(Enchantment.ENCHANT, poziom);

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249780
Udostępnij na innych stronach

  • 0
13 minut temu, Virosel napisał:

 

Chodzi mi bardziej o to, żeby wyciągnąć te enchanty z configu.

no to w configu możesz np zrobić coś takiego:

Items:
	Sell:
		1:
			#co tam chcesz
			enchantments:
				- 'durability:3'
				- 'damage_all:5'

No i w tej pętli coś takiego

Map<Enchantment, Integer> map = new HashMap<>(); 
for (String s : cfg.getStringList(path + ".enchantments")) {
	Enchantment ench = Enchantment.getByName(s.split(":")[0].toUpperCase());
  	if (ench == null) continue;
  	int level = Integer.parseInt(s.split(":")[1]);
  	map.put(ench, level);
}
  
is.addEnchantments(map);

 

Edytowane przez HotAngel2K17
Jeżeli dajesz enchany większe od maksymalnych leveli lub enchant, który nie mozna dodać do danego przedmiotu użyj "is.addUnsafeEnchantments​"
Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249797
Udostępnij na innych stronach

  • 0
2 godziny temu, HotAngel2K17 napisał:
3 godziny temu, HotAngel2K17 napisał:

no to w configu możesz np zrobić coś takiego:



Items:
	Sell:
		1:
			#co tam chcesz
			enchantments:
				- 'durability:3'
				- 'damage_all:5'

No i w tej pętli coś takiego



Map<Enchantment, Integer> map = new HashMap<>(); 
for (String s : cfg.getStringList(path + ".enchantments")) {
	Enchantment ench = Enchantment.getByName(s.split(":")[0].toUpperCase());
  	if (ench == null) continue;
  	int level = Integer.parseInt(s.split(":")[1]);
  	map.put(ench, level);
}
  
is.addEnchantments(map);

 

 

Jeszcze jedno pytanie, w jaki sposób mogę sprawdzić jaka jest cena danego itemku w evencie kliknięcia? Resztę pewnie będę wiedział jak zrobić.

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249809
Udostępnij na innych stronach

  • 0
5 minut temu, Virosel napisał:

 

Jeszcze jedno pytanie, w jaki sposób mogę sprawdzić jaka jest cena danego itemku w evencie kliknięcia? Resztę pewnie będę wiedział jak zrobić.

jak wroce to ci pomoge na pv, bo to bedzie bardziej skomplikowane

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249810
Udostępnij na innych stronach

  • 0
6 godzin temu, Virosel napisał:

Ok, dzięki

Chyba najprościej będzie zrobić jakąś mapkę 

Map<ItemStack, Integer> map = new HashMap<>();

klucz (itemstack) to będzie przedmiot do kupienia (Key w mapce zawsze jest po to, żeby za jego pomocą określić przypisaną mu wartość, przykład: 

Map<Integer, String> map = new HashMap<>();
  
/w jakiejś metodzie czy coś.
  map.put(1, "liczba jeden");
  
/również w jakiejś metodzie.
  final String text = map.get(1);
  System.out.println(text); /*wyświetli w konsoli "liczba jeden"*/ ale println to tylko przykład

wartość (Integer) to będzie cena tego przedmiotu

Do tej mapki przy pętli możesz dodać przedmiot oraz jego cenę

 

W evencie od klikania:

@EventHanler
public void onClick(InventoryClickEvent e) {
	/* sprawdzasz co tam chcesz, nazwe inventory itd.*/
	ItemStack is = e.getCurrentItem(); /jest to kliknięty przemiot
	if (!map.containsKey(is)) {
		/w tym przypadku taki przedmiot nie istnieje w mapce, czyli powinieneś wykonać return, żeby nie wywaliło błędu
		return;
	}

	int price = map.get(is); /tu jest cena przedmiotu

 

Edytowane przez HotAngel2K17
Ewentualnie zamiast ItemStack w mapce możesz użyć Material
Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249848
Udostępnij na innych stronach

  • 0
2 godziny temu, HotAngel2K17 napisał:

Chyba najprościej będzie zrobić jakąś mapkę 


Map<ItemStack, Integer> map = new HashMap<>();

klucz (itemstack) to będzie przedmiot do kupienia (Key w mapce zawsze jest po to, żeby za jego pomocą określić przypisaną mu wartość, przykład: 


Map<Integer, String> map = new HashMap<>();
  
/w jakiejś metodzie czy coś.
  map.put(1, "liczba jeden");
  
/również w jakiejś metodzie.
  final String text = map.get(1);
  System.out.println(text); /*wyświetli w konsoli "liczba jeden"*/ ale println to tylko przykład

wartość (Integer) to będzie cena tego przedmiotu

Do tej mapki przy pętli możesz dodać przedmiot oraz jego cenę

 

W evencie od klikania:


@EventHanler
public void onClick(InventoryClickEvent e) {
	/* sprawdzasz co tam chcesz, nazwe inventory itd.*/
	ItemStack is = e.getCurrentItem(); /jest to kliknięty przemiot
	if (!map.containsKey(is)) {
		/w tym przypadku taki przedmiot nie istnieje w mapce, czyli powinieneś wykonać return, żeby nie wywaliło błędu
		return;
	}

	int price = map.get(is); /tu jest cena przedmiotu

 

 

Czyli cały ten kod skopiować, czy tylko to, co jest w evencie?

 

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249862
Udostępnij na innych stronach

  • 0
22 minuty temu, Virosel napisał:

 

Czyli cały ten kod skopiować, czy tylko to, co jest w evencie?

 

tobie potrzebne będzie to co w evencie :) ale musisz zrobić gdzieś sobie tą mapkę

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249864
Udostępnij na innych stronach

  • 0
28 minut temu, HotAngel2K17 napisał:

tobie potrzebne będzie to co w evencie :) ale musisz zrobić gdzieś sobie tą mapkę

Ok. tą mapę chyba najlepiej będzie stworzyć w miejscu, gdzie plugin wyciąga itemki z configu. Jutro sprawdzę :)

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249871
Udostępnij na innych stronach

  • 0
32 minuty temu, Virosel napisał:

Ok. tą mapę chyba najlepiej będzie stworzyć w miejscu, gdzie plugin wyciąga itemki z configu. Jutro sprawdzę :)

najlepiej mieć osobną klasę, w której będą zapisywane wszystkie rzeczy z configu a w innych klasach się tylko do niej odwoływać:)

Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249872
Udostępnij na innych stronach

  • 0
15 godzin temu, kerpson napisał:

najlepiej mieć osobną klasę, w której będą zapisywane wszystkie rzeczy z configu a w innych klasach się tylko do niej odwoływać:)

Zrobiłem to tak:

Stworzyłem klasę ItemManager (kod niżej):

    public static Map<ItemStack, Integer> map = new HashMap<>();
    public static int getItemPrice(ItemStack is){
        int price = map.get(is);
        return price;
    }

    public static void setItem(ItemStack is, int price){
        map.put(is, price);
    }

W evencie kliknięcia:

    @EventHandler
    public boolean onInventoryClick(InventoryClickEvent e) {
        Player p = (Player) e.getWhoClicked();
        String shopinvname = Main.getInst().getConfig().getString("shopSellName");

        if (e.getInventory().getTitle().equals(Utils.fixColor(shopinvname))) {
            if (e.getCurrentItem().getItemMeta() != null) {
                if (e.getCurrentItem().getItemMeta().getDisplayName() != null) {
                    e.setCancelled(true);
                    ItemStack is = e.getCurrentItem();
                    ItemMeta meta = is.getItemMeta();
                    if (!ItemManager.map.containsKey(is)) {

                    }
                    int price = ItemManager.getItemPrice(is);

                    meta.setLore(new ArrayList<>());
                    meta.setDisplayName(null);
                    is.setItemMeta(meta);

                    Material mat = is.getType();
                    int amount = is.getAmount();
                    if(p.getInventory().containsAtLeast(is, amount)){
                        CoinsManager.addMoney(p, price);
                        String msg = String.join("\n", Main.getInst().getConfig().getStringList("sellSuccess"));
                        msg = msg.replace("{ITEM}", is.getType().toString());
                        msg = msg.replace("{MONEY}", String.valueOf(amount));
                        p.getInventory().removeItem(is);
                        p.sendMessage(Utils.fixColor(msg));
                    }else{
                        p.closeInventory();
                        Utils.sendTitle(p, Utils.fixColor(Main.getInst().getConfig().getString("titles.tag")));
                        Utils.sendSubTitle(p, Utils.fixColor(Main.getInst().getConfig().getString("titles.notEnounghtItems")));
                    }
                }
            }
        }
        return true;
    }
}

 

I jeszcze kod z klasy otwierającej zakladkę sklepu:

else if (e.getCurrentItem().getItemMeta().getDisplayName().equals(r)) {
                        e.setCancelled(true);
                        Inventory inv = Bukkit.createInventory(null, 27, Utils.fixColor(Main.getInst().getConfig().getString("shopSellName")));

                        int i = 0;

                        for (final String a : Main.getInst().getConfig().getConfigurationSection("Items.Sell").getKeys(false)) {
                            final String path = "Items.Sell." + a;
                            final ItemStack item = new ItemStack(Material.getMaterial(Main.getInst().getConfig().getString(path + ".material")));
                            item.setAmount(Main.getInst().getConfig().getInt(path + ".amount"));
                            ItemMeta met = item.getItemMeta();
                            met.setDisplayName(Utils.fixColor(Main.getInst().getConfig().getString(path + ".name")));
                            List<String> lore = Main.getInst().getConfig().getStringList(path + ".lore")
                                    .stream()
                                    .map(s -> ChatColor.translateAlternateColorCodes('&', s).replace("<<", "«").replace(">>", "»"))
                                    .collect(Collectors.toList());
                            met.setLore(lore);
                            item.setItemMeta(met);
                            int price = Main.getInst().getConfig().getInt(path+".price");

                            Map<Enchantment, Integer> map = new HashMap<>();
                            for (String s : Main.getInst().getConfig().getStringList(path + ".enchantments")) {
                                Enchantment ench = Enchantment.getByName(s.split(":")[0].toUpperCase());
                                if (ench == null) continue;
                                int level = Integer.parseInt(s.split(":")[1]);
                                map.put(ench, level);
                            }

                            item.addUnsafeEnchantments(map);

                            inv.setItem(i, item);

                            ItemManager.setItem(item, i);

                            i++;
                        }


                        p.openInventory(inv);
                    }

Wszystko niby działa, ale tylko podczas pierwszej sprzedaży, później czyści się meta przedmiotu (w GUI) i kolejna sprzedaż jest nie możliwa. Pewnie jest to jakiś głupi błąd logiczny, którego nie mogę znaleźć.

 

Po usunięciu elementu "is.setItemMeta(meta);" po kliknięciu nie można tego sprzedać ani razu.

Najłatwiej chyba byłoby otworzyć całe GUI od nowa po każdej sprzedaży, lub utworzyć nowy ItemStack, który będzie równy temu, który gracz kliknął (ItemStack is1 = is; ) 

 

 

Edytowane przez Virosel
Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249917
Udostępnij na innych stronach

  • 0

Na początek porada:

Zamiast:

 if (e.getCurrentItem().getItemMeta() != null) {
                if (e.getCurrentItem().getItemMeta().getDisplayName() != null) {

Możesz dać

 if (e.getCurrentItem().hasItemMeta() && e.getCurrentItem().getItemMeta().getDisplayName() != null) {

 

Do rzeczy, tak jak wspomniałeś, najlepiej zrobić osobny itemstack czyli (bazując na itemstacku z getCurrentItem())

ItemStack remove = new ItemStack(is.getType(), 1, is.getDurability());

wtedy nie musisz się bawić w itemmeta :)

Wtedy tylko sprawdzasz czy gracz w ekwipunku posiada ten itemstack, który stworzyłeś (w moim przypadku remove) i go potem usuwać

 

A teraz wyjaśnienie co było źle ?

Usuwałeś itemmeta klikniętemu przedmiotowi i ustawiałeś jego displayname na null, a w warunku wyżej miałeś 


                if (e.getCurrentItem().getItemMeta().getDisplayName() != null) {

Myślę, że pomogłem i tym razem

 

#Edit

Robisz masakryczny błąd :(

Inventory inv = Bukkit.createInventory(null, 27, Utils.fixColor(Main.getInst().getConfig().getString("shopSellName")));

                        int i = 0;

                        for (final String a : Main.getInst().getConfig().getConfigurationSection("Items.Sell").getKeys(false)) {
                            final String path = "Items.Sell." + a;
                            final ItemStack item = new ItemStack(Material.getMaterial(Main.getInst().getConfig().getString(path + ".material")));
                            item.setAmount(Main.getInst().getConfig().getInt(path + ".amount"));
                            ItemMeta met = item.getItemMeta();
                            met.setDisplayName(Utils.fixColor(Main.getInst().getConfig().getString(path + ".name")));
                            List<String> lore = Main.getInst().getConfig().getStringList(path + ".lore")
                                    .stream()
                                    .map(s -> ChatColor.translateAlternateColorCodes('&', s).replace("<<", "«").replace(">>", "»"))
                                    .collect(Collectors.toList());
                            met.setLore(lore);
                            item.setItemMeta(met);
                            int price = Main.getInst().getConfig().getInt(path+".price");

                            Map<Enchantment, Integer> map = new HashMap<>();
                            for (String s : Main.getInst().getConfig().getStringList(path + ".enchantments")) {
                                Enchantment ench = Enchantment.getByName(s.split(":")[0].toUpperCase());
                                if (ench == null) continue;
                                int level = Integer.parseInt(s.split(":")[1]);
                                map.put(ench, level);
                            }

                            item.addUnsafeEnchantments(map);

                            inv.setItem(i, item);

                            ItemManager.setItem(item, i);

                            i++;
                        }


                        p.openInventory(inv);

za każdym razem tworzysz nowe inventory (każdy gracz ma i tak to samo) ale to mniejszy problem

Za każdym razem dodajesz do ItemManagera te same wartości z configu, lepiej zrobić jakąś klasę Config, zrobić jakiegoś voida np. loadConfig() tam ładować itemy do mapki, w głównej klasie zrobić (w onEnable()) Config.loadConfig();

Wtedy tylko dodajesz do ekwipunku itemy, a nie tworzysz je na nowo za każdym razem

No i co do ekwipunku, możesz zrobić jakąś klasę z ekwipunkiem (tam robisz ekwipunek gotowy, dodajesz do niego itemki z ItemManager), w klasie glównej załadować i stworzyć to inventory a np. w listenerze tylko otwierać te gotowe inventory. Jest to opcja, która optymalizuje kod, a zarazem kod staje się czytelniejszy i łatwiej się w nim połapać

Edytowane przez kerpson
Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249924
Udostępnij na innych stronach

  • 0
26 minut temu, kerpson napisał:

Na początek porada:

Zamiast:


 if (e.getCurrentItem().getItemMeta() != null) {
                if (e.getCurrentItem().getItemMeta().getDisplayName() != null) {

Możesz dać


 if (e.getCurrentItem().hasItemMeta() && e.getCurrentItem().getItemMeta().getDisplayName() != null) {

 

Do rzeczy, tak jak wspomniałeś, najlepiej zrobić osobny itemstack czyli (bazując na itemstacku z getCurrentItem())


ItemStack remove = new ItemStack(is.getType(), 1, is.getDurability());

wtedy nie musisz się bawić w itemmeta :)

Wtedy tylko sprawdzasz czy gracz w ekwipunku posiada ten itemstack, który stworzyłeś (w moim przypadku remove) i go potem usuwać

 

A teraz wyjaśnienie co było źle ?

Usuwałeś itemmeta klikniętemu przedmiotowi i ustawiałeś jego displayname na null, a w warunku wyżej miałeś 


                if (e.getCurrentItem().getItemMeta().getDisplayName() != null) {

Myślę, że pomogłem i tym razem

 

#Edit

Robisz masakryczny błąd :(


Inventory inv = Bukkit.createInventory(null, 27, Utils.fixColor(Main.getInst().getConfig().getString("shopSellName")));

                        int i = 0;

                        for (final String a : Main.getInst().getConfig().getConfigurationSection("Items.Sell").getKeys(false)) {
                            final String path = "Items.Sell." + a;
                            final ItemStack item = new ItemStack(Material.getMaterial(Main.getInst().getConfig().getString(path + ".material")));
                            item.setAmount(Main.getInst().getConfig().getInt(path + ".amount"));
                            ItemMeta met = item.getItemMeta();
                            met.setDisplayName(Utils.fixColor(Main.getInst().getConfig().getString(path + ".name")));
                            List<String> lore = Main.getInst().getConfig().getStringList(path + ".lore")
                                    .stream()
                                    .map(s -> ChatColor.translateAlternateColorCodes('&', s).replace("<<", "«").replace(">>", "»"))
                                    .collect(Collectors.toList());
                            met.setLore(lore);
                            item.setItemMeta(met);
                            int price = Main.getInst().getConfig().getInt(path+".price");

                            Map<Enchantment, Integer> map = new HashMap<>();
                            for (String s : Main.getInst().getConfig().getStringList(path + ".enchantments")) {
                                Enchantment ench = Enchantment.getByName(s.split(":")[0].toUpperCase());
                                if (ench == null) continue;
                                int level = Integer.parseInt(s.split(":")[1]);
                                map.put(ench, level);
                            }

                            item.addUnsafeEnchantments(map);

                            inv.setItem(i, item);

                            ItemManager.setItem(item, i);

                            i++;
                        }


                        p.openInventory(inv);

za każdym razem tworzysz nowe inventory (każdy gracz ma i tak to samo) ale to mniejszy problem

Za każdym razem dodajesz do ItemManagera te same wartości z configu, lepiej zrobić jakąś klasę Config, zrobić jakiegoś voida np. loadConfig() tam ładować itemy do mapki, w głównej klasie zrobić (w onEnable()) Config.loadConfig();

Wtedy tylko dodajesz do ekwipunku itemy, a nie tworzysz je na nowo za każdym razem

No i co do ekwipunku, możesz zrobić jakąś klasę z ekwipunkiem (tam robisz ekwipunek gotowy, dodajesz do niego itemki z ItemManager), w klasie glównej załadować i stworzyć to inventory a np. w listenerze tylko otwierać te gotowe inventory. Jest to opcja, która optymalizuje kod, a zarazem kod staje się czytelniejszy i łatwiej się w nim połapać

 

Stworzyłem mapę <ItemStack, Integer> - Integer to slot. I teraz nasuwa się pytanie, w jaki sposób dodać to do inventory. (nie pracowałem wcześniej z mapami, więc nie wiem jak to działa).

Edytowane przez Virosel
Odnośnik do komentarza
https://skript.pl/temat/39888-przedmioty-z-configu/#findComment-249926
Udostępnij na innych stronach

Nieaktywny
Ten temat został zamknięty. Brak możliwości dodania odpowiedzi.
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...