Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

[Problem] Pisanie pluginu na stoniarki


Rekomendowane odpowiedzi

Opublikowano

Witam mam pewien problem z napisaniem pluginu na stoniarki... Ma ktos jakies propozycje, aby kamien regenerowalo nad kamieniem kresu o nazwie "Stoniarka"? Bo jak postawie dowolny "ender stone" to i tak generuje. Moglby ktos do tego kodu dodac, aby dzialalo jak nalezy? Za wszelka pomoc dziekuje + nagroda lajki. PS: Prosze nie pisac wez juz masz gotowy plugin eastStone, kukuStone itd. Nie chce innych.

 

@EventHandler
public void blockPlace(BlockPlaceEvent event){
Block block = event.getBlock();
final Location loc = block.getLocation();
final Location loc1 = new Location(loc.getWorld(), loc.getX(), loc.getY() + 1.0D, loc.getZ());
if(block.getType() == Material.ENDER_STONE && (loc1.getBlock().getType() == Material.AIR)){
Bukkit.getScheduler().runTaskLater(Main.getPlugin(), new Runnable(){
public void run(){
if(loc.getBlock().getType() == Material.ENDER_STONE){
loc1.getBlock().setType(Material.STONE);
}
}
}, 10L);
}
}
Opublikowano

Generowanie kamienia po położeniu ender stone'a:

@EventHandler
	public void PlaceEnder(BlockPlaceEvent event) {
		Location loc = event.getBlock().getLocation();
		Location stone = new Location(loc.getWorld(), loc.getX(), loc.getY()+1, loc.getZ());
		if(event.getBlock().getType().equals(Material.ENDER_STONE)) {
			event.getPlayer().sendMessage(ChatColor.YELLOW + "Postawiles generator kamienia!");
				Bukkit.getScheduler().runTaskLater((Plugin) this, new Runnable() {
					public void run() {
						stone.getBlock().setType(Material.STONE);
					}
				}, 2*20L);
		}
	}

Generowanie kamienia po zniszczeniu kamienia:

@EventHandler
	public void BlockBreakEvent(BlockBreakEvent event) {
		Location loc = event.getBlock().getLocation();
		Location ender = new Location(loc.getWorld(), loc.getX(), loc.getY()-1, loc.getZ());
		if(event.getBlock().getType().equals(Material.STONE)) {
			if(ender.getBlock().getType().equals(Material.STONE)) {
				Bukkit.getScheduler().runTaskLater((Plugin) this, new Runnable() {
					public void run() {
						loc.getBlock().setType(Material.STONE);
					}
				}, 2*20L);
			}
		}
	}

W razie pytań zapraszam na priv!

 

Liczę na like :D

Opublikowano

@Screams Chodzi o to, ze jak postawie nawet zwykly ender stone to generuje STONE. A ja chce aby stoniarka tworzyla sie tylko po polozeniu ender stone o nazwie "Stoniarka" i dopiero wtedy ma  generowac stone.  Tak samo jak sie zniszczy stoniarke to wypada ender stone o nazwie "Stoniarka" a jak sie zniszczy zwykly ender stone to wypada zwykly...

Opublikowano
ItemStack i = p.getItemInHand();

if (i.getType().equals(Material.ENDER_STONE) && i.getItemMeta().getDisplayName().equals("Stoniarka"))

 

juz pomijam sprawdzanie czy nazwa nie jest nullem

dodatkowo zamiast robic sryliard taskow dla kazdej stoniarki radze zrobic 1 w onenable 

Opublikowano

@@xWatx

Przy tworzeniu bloku stoniarki możesz dodać do niego metadane. Później, gdy gracz zniszczy jakiś blok, możesz za ich pomocą określić, czy to blok stoniarki, czy nie.

to nie działa do BlockPlaceEvent i BlockBreakEvent.

 

@Screams Chodzi o to, ze jak postawie nawet zwykly ender stone to generuje STONE. A ja chce aby stoniarka tworzyla sie tylko po polozeniu ender stone o nazwie "Stoniarka" i dopiero wtedy ma  generowac stone.  Tak samo jak sie zniszczy stoniarke to wypada ender stone o nazwie "Stoniarka" a jak sie zniszczy zwykly ender stone to wypada zwykly...

to tak nie działa. z tego co zauważyłem to np. ItemStack cos = new ItemStack(Material.SPONGE); po położeniu staje się normalnym Material.SPONGE. Możesz dodać zapis lokalizacji bloku po PlayerInteractEvent do ArrayList i później przy rozwaleniu Stone sprawdzać czy ten enderstone to stonierka

Opublikowano

przy polozeniu bloku sprawdz czy item w rece gracza ma displayname , jezeli tak to sprawdz czy == twoja nazwa i wtedy zapisz gdzies ta lokalizacje i generuj blok

Opublikowano

@1361622928-U485574.pngAranthor probowalem, ale cos nie pyklo moglbys dodac to do klasy?

 

Nie działało, ponieważ coś zrobiłeś źle. Poniżej zamieszczam działający przykładowy kod do obsługi stoniarki.

@EventHandler
public void onPlaceBlock(BlockPlaceEvent e) {
    if (e.getPlayer().getItemInHand() != null && e.getPlayer().getItemInHand().hasItemMeta()) {
        if (e.getPlayer().getItemInHand().getItemMeta().getDisplayName().equals("Stoniarka")) {
            e.getBlock().setMetadata("stoniarka", new FixedMetadataValue(Main.getInstance(), true));
        }
    }
}

@EventHandler
public void onBreakBlock(BlockBreakEvent e) {
    if (e.getBlock().getMetadata("stoniarka").size() > 0 && e.getBlock().getMetadata("stoniarka").get(0).asBoolean()) {
        //zniszczony blok jest stoniarką
    }
}
    
Opublikowano

#offtop

widze ze 3 pseudo programistow zebralo sie w 1 temacie to ciekawie bedzie

 

ale wy głupoty pierdolicie, najpierw stworz stonecontainera w ktorym w hashsetcie zapisujesz lokalizacje stoniarek a potem w ondisable loopuj przez tego seta, serializuj lokacje do configu i odwrotnie przy onEnable. stworz 1 taska ktory dla kazdej stoniarki co np 3 sekundy regeneruje blok

 

Przetestowałeś kod, który napisałem? Założę się, że nie - "przyszedłeś" i się tylko wymądrzasz jak na razie.

 

Poza tym, już ktoś wyżej zaproponował zapisywanie lokalizacji stoniarek do jakiejś kolekcji. Tylko po co to robić, skoro można to zrobić prościej za pomocą metadanych.

Opublikowano

#offtop

widze ze 3 pseudo programistow zebralo sie w 1 temacie to ciekawie bedzie

 

ale wy głupoty pierdolicie, najpierw stworz stonecontainera w ktorym w hashsetcie zapisujesz lokalizacje stoniarek a potem w ondisable loopuj przez tego seta, serializuj lokacje do configu i odwrotnie przy onEnable. stworz 1 taska ktory dla kazdej stoniarki co np 3 sekundy regeneruje blok

Tyś chory chyba jest. Jak ty masz zamiar zapisywać i odczytywać tyle rzeczy z configu to ło luju.

Po co się trudzić z pluginami jak już istnieją takie.

 

@topic:

Najlepiej pobaw się SQLite bo to będzie najbardziej wydajny sposób. Innym sposobem jest jak już @1361622928-U485574.pngAranthor napisał Metadata. :>

 

p.s: Jak jednak wolałbyś używać sposobu owej osoby to mogę ci polecić pewny Util który umożliwia zapisywanie Map, List itp. do pliku a potem sobie to odczytuje.

Opublikowano

tylko że geniuszu nie wiesz, ze block metadata sie nie zapisuje po restarcie/reloadzie.

 

@@StrikeKiller123 miałeś rację co do metadanych, zwracam honor za niesłuszne uwagi.

 

 

 

ALE

Znalazłem inny sposób na identyfikację stoniarki, nie wymagający żadnego zapisu danych do pliku konfiguracyjnego. I tym razem go sprawdziłem - działa po restarcie. :P

Chodzi mi o dwie metody: setData() i getData(). Obie są oznaczone jako przestarzałe, lecz działają poprawnie na wersji 1.7.9.

 

Za pomocą setData() można przypisać do bloku jakąś liczbę, która potem będzie sprawdzana podczas jego niszczenia za pomocą getData(). W ten sposób można odróżnić blok stoniarki od zwykłego kamienia kresu.

 

Może to wyglądać mniej więcej tak:

@EventHandler
    public void onBreakBlock(BlockBreakEvent e) {
    if (e.getBlock().getData() == (byte) 7) {
        //Zniszczony blok jest stoniarką
    }
}

@EventHandler
public void onPlaceBlock(BlockPlaceEvent e) {
    if (e.getPlayer().getItemInHand().getType().equals(Material.ENDER_STONE) && e.getPlayer().getItemInHand().hasItemMeta()) {
        if (e.getPlayer().getItemInHand().getItemMeta().getDisplayName().equals("nazwa_stoniarki")) {
                e.getBlockPlaced().setData((byte) 7);
        }
    }
}
Opublikowano

@1361622928-U485574.pngAranthor jak dodaje "event.getBlockPlaced().setData((byte) 7);", "if (e.getBlock().getData() == (byte) 7) {"

 

to skresla mi "setData" i "getData"

@EventHandler
public void blockPlace(BlockPlaceEvent event){
Block block = event.getBlock();
final Location loc = block.getLocation();
final Location loc1 = new Location(loc.getWorld(), loc.getX(), loc.getY() + 1.0D, loc.getZ());
   if (event.getPlayer().getItemInHand().getType().equals(Material.ENDER_STONE) && event.getPlayer().getItemInHand().hasItemMeta() && (loc1.getBlock().getType() == Material.AIR)){
       if (event.getPlayer().getItemInHand().getItemMeta().getDisplayName().equals(ChatColor.GOLD + "Stoniarka")){
                event.getBlockPlaced().setData((byte) 7);
        Bukkit.getScheduler().runTaskLater(Main.getPlugin(), new Runnable(){
        public void run(){
        if(loc.getBlock().getType() == Material.ENDER_STONE){
        loc1.getBlock().setType(Material.STONE);
        }
        }
        }, 10L);
       }
   }
}
}

A jak wygladalo by zapisywanie lokalizacji bloku i przy niszczeniu odczytywanie czy to jest ta lokalizacja, ktora byla przy interact event? Moglby ktos podac przyklad? Nie moge znajsc tego w Internecie. :(

Opublikowano

Mam problem @1361622928-U485574.pngAranthor z tym:

@EventHandler
public void blockBreak(BlockBreakEvent event){
 
ItemStack test = new ItemStack (Material.ENDER_STONE);
ItemMeta testMeta = ender_stone.getItemMeta();
 
testMeta.setDisplayName(ChatColor.GOLD + "Stoniarka");
test.setItemMeta(testMeta);
 
final Block block = event.getBlock();
Location loc = block.getLocation();
final Location loc1 = new Location(loc.getWorld(), loc.getX(), loc.getY() - 1.0D, loc.getZ());
if(block.getType() == Material.STONE && (loc1.getBlock().getType() == Material.ENDER_STONE)){
Bukkit.getScheduler().runTaskLater(Main.getPlugin(), new Runnable(){
public void run(){
if(loc1.getBlock().getType() == Material.ENDER_STONE){
block.setType(Material.STONE);
}
}
}, 10L);
}
   if (event.getBlock().getMetadata("Stoniarka").size() > 0 && event.getBlock().getMetadata("Stoniarka").get(0).asBoolean() && (event.getBlock().getData() == (byte) 7)){
    event.setCancelled(true);
    event.getBlock().setType(Material.AIR);
    event.getPlayer().getWorld().dropItemNaturally(event.getBlock().getLocation(), (test));
   }
}

Skresla mi wyraz przy event.getBlockPlaced().setData((byte) 7);    setData i przy if (event.getBlock().getData() == (byte) 7) getData  , wiesz co nalezy zrobic aby dzialalo?  Wklej sb ten kod do eclipsa i zobacz, jak te wyrazy skresla... :( Prosze o pomoc

Opublikowano

@1361622928-U485574.pngAranthor jak dodaje "event.getBlockPlaced().setData((byte) 7);", "if (e.getBlock().getData() == (byte) 7) {"

 

to skresla mi "setData" i "getData"

 

Te metody zostały oznaczone jako przestarzałe, dlatego są skreślone.

 

 

A jak wygladalo by zapisywanie lokalizacji bloku i przy niszczeniu odczytywanie czy to jest ta lokalizacja, ktora byla przy interact event? Moglby ktos podac przyklad? Nie moge znajsc tego w Internecie. :(

List<Location> list = new ArrayList<Location>(); //lista przechowująca lokalizacje stoniarek

@EventHandler
    public void onBreakBlock(BlockBreakEvent e) {
    for (Location l : list) {
        if (l.equals(e.getBlock().getLocation())) {
                //Zniszczony blok jest stoniarką
        }
    }
}

@EventHandler
public void onPlaceBlock(BlockPlaceEvent e) {
    if (e.getPlayer().getItemInHand().getType().equals(Material.ENDER_STONE) && e.getPlayer().getItemInHand().hasItemMeta()) {
        if (e.getPlayer().getItemInHand().getItemMeta().getDisplayName().equals("nazwa_stoniarki")) {
            list.add(e.getBlockPlaced().getLocation());
        }
    }
}
Opublikowano

@1361622928-U485574.pngAranthor teraz nie generuje stone nawet:

 

List<Location> list = new ArrayList<Location>();
 
@EventHandler
public void blockPlace(BlockPlaceEvent event){
Block block = event.getBlock();
final Location loc = block.getLocation();
final Location loc1 = new Location(loc.getWorld(), loc.getX(), loc.getY() + 1.0D, loc.getZ());
   if (event.getPlayer().getItemInHand().getType().equals(Material.ENDER_STONE) && event.getPlayer().getItemInHand().hasItemMeta() && (loc1.getBlock().getType() == Material.AIR)){
       if (event.getPlayer().getItemInHand().getItemMeta().getDisplayName().equals(ChatColor.GOLD + "Stoniarka")){
           for (Location l : list) {
            l.add(event.getBlockPlaced().getLocation());
            Bukkit.getScheduler().runTaskLater(Main.getPlugin(), new Runnable(){
            public void run(){
            if(loc.getBlock().getType() == Material.ENDER_STONE){
            loc1.getBlock().setType(Material.STONE);
            }
        }
        }, 10L);
           }
       }
   }
}
}
Opublikowano

@@xWatx, po co używasz pętli for, gdy obsługujesz wydarzenie BlockPlaceEvent? Spójrz jeszcze raz na przykład, który podałem.

 

Stone będzie się generował, gdy usuniesz pętlę for.

Opublikowano

@@xWatx, dzieje się tak dlatego, że nie zapisujesz listy stoniarek podczas wyłączania pluginu i nie ładujesz jej podczas włączania.

Dużo łatwiej jest użyć metod getData() oraz setData() - nie musisz wtedy używać plików konfiguracyjnych. Mimo tego, że są oznaczone jako przestarzałe, działają bardzo dobrze i nie zwracaj uwagi na to, że są przekreślone.

Opublikowano

@1361622928-U485574.pngAranthor z setData() getData() ladnie chodzi, po /reload dalej jest Stoniarka lub po restarcie znowu jest Stoniarka, ale jest maly problem. Jak wpisze /reload, a nastepnie zrestartuje serwer po wykopaniu stoniarki wypada zwykly ender stone.

Opublikowano

@1361622928-U485574.pngAranthor Chodzi o to, ze jak wpisze /reload i nastepnie dowale restart serwera to po wlaczeniu serwera stoniarka zamienia sie w zwykly ender stone (po wykopaniu stoniarki). A jak wpisze /reload i nie dowale restartu to jest normalnie.

Opublikowano
 

Nie dziwiles sie geniuszu, dlaczego nikt tego nie uzywa?

Przez takie wlasnie bugi m.in jest to funkcja deprecated.

 

Domyślałem się, że musi być powód dla którego ją tak oznaczyli, tylko nie wiedziałem, o co dokładnie chodziło.

 

 

 

PS. Ilu jeszcze kolejnych "programistuff defeloperuff" zobacze na tym forum? Najpierw jakis Demon, potem soldier, potem jakis aranthorn .. a pewnie za 2 msc Klocuch12

 

Czasem trzeba spróbować podejść do problemu z innej strony, a dopiero później zrezygnować, jak pojawią się sytuacje bez wyjścia. Przynajmniej próbowałem zrobić to na inny sposób, niż za pomocą plików. A ty zaraz wylatujesz z bólem dupy, że pseudo programiści itp. Weź się ogarnij w końcu...

 

PS: Widzę, że milczałeś, gdy napisałem o możliwości użycia metod getData() i setData() i odezwałeś się dopiero teraz, gdy pojawiły się problemy, co sugeruje, że też nie wiedziałeś, jakie problemy mogą powodować, panie "profesjonalisto".

 

 

@@xWatx jeśli nie odpowiada ci działanie tych metod, to musisz zmienić podejście - zapisywać lokalizacje stoniarek do pliku.

 

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...