Minecraft Java Plugin Block neu Spawnen

01/31/2014 16:50 nawiat100#1
Hey Leute ^^

Mal was einfaches diesmal, aber ich stehe vor einer Wand iwi :p.

Ich frage unten durch ein Event ab welcher Block zerstört wurde, dann noch wo genau er stand. Danach soll er "replaced" werden, also genau dort wo der alte war neu Spawnen.

geht nur iwi noch net XD jemand ne Idee? wenn net ist auch nich schlimm :p

bei "b.setTypeID" sagt er:

"The method setTypeID(float, float, float, int) is undefined for the type Block"

Danke
Nawiat100
01/31/2014 17:03 ComputerBaer#2
Wie wäre es denn mit "b.setTypeID(19);"?
Die eigenen Koordinaten kennt der Block doch wohl und deshalb wird er die auch kaum als Parameter erwarten.

[Only registered and activated users can see links. Click Here To Register...]

Edit:
Noch besser wäre "b.setType(org.bukkit.Material.SPONGE);"
01/31/2014 17:07 nawiat100#3
naja nur ist der block dann einfach weg XD er wird nicht erneut danach gespawnt! deswegen wollte ich die Kords. abspeichern und den block ne sekunde danach Spwanen ^^
01/31/2014 17:15 lordsill#4
zum Beispiel so:

Code:
@EventHandler
public void onBreak(BlockBreakEvent event)
{
  final Location loc = event.getBlock().getLocation();
  final Block block = event.getBlock();
  this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
      @Override
      public void run() {
           Block b = loc.getBlock();
           b.setType(block.getType());
      }
    }, 20);
}
Die 20 ist der vorletzten Zeile sind die Ticks, bis der Block wieder "respawnen" soll.
20 Ticks = 1 Sekunde

# Enthält einen Fehler, den ich jetzt nicht nachkorregiere. Siehe für eine funktionierende Version einen Beitrag unter mir
01/31/2014 17:33 ComputerBaer#5
Da habe ich wohl gekonnt den wichtigsten Teil überlesen und mich nur auf die merkwürdige Verwendung von setTypeId konzentriert.

Ich denke bei lordsill ist noch ein kleiner Fehler drin und so ist es besser:
Code:
@EventHandler
public void onBreak(BlockBreakEvent event)
{
  final Location loc = event.getBlock().getLocation();
  final Material type = event.getBlock().getType();

  this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
      @Override
      public void run() {
          Block b = loc.getBlock();
          b.setType(type);
      }
    }, 20);
}
Es macht eigentlich keinen Sinn sich den Typ des entfernten Blocks erst beim respawnen zu holen, weil der zu dem Zeitpunkt schon Luft ist und somit wäre der neue Block auch nur Luft.

Die 20 Ticks kannst du auch auf 1 reduzieren, wenn es nicht nach einer Sekunde sondern imgrunde sofort geschehen soll.

Edit:
Wenn meine Vermutung richtig ist, sollte das auch so funktionieren:
Code:
@EventHandler
public void onBreak(BlockBreakEvent event)
{
  final Block b = event.getBlock();
  final Material type = b.getType();

  this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
      @Override
      public void run() {
         b.setType(type);
      }
    }, 20);
}
Da kannst du die Lösung wählen, die dir besser gefällt. Ich denke diese Zweite sollte ein ganz klein wenig besser sein als die Erste.
01/31/2014 21:39 Howaner#6
Warum einen Scheduler machen, wenn man das Event doch einfach canceln kann?
Code:
@EventHandler (priority = EventPriority.LOW)
public void onBlockBreak(BlockBreakEvent event) {
	if (event.isCancelled()) return;
	Block block = event.getBlock();
	block.setType(Material.SPONGE);
	event.setCancelled(true);
}
02/01/2014 21:44 nawiat100#7
ich werde alles bei gelegenheit mal durchtesten ^^

danke

sollte denke ich gehen, danke euch. aber er sagt bei getServer

"The method getServer() is undefined for the type Listen"

@Howaner

dein code ging ^^ danke dir :p
02/01/2014 22:53 ComputerBaer#8
Quote:
Originally Posted by nawiat100 View Post
"The method getServer() is undefined for the type Listen"
Ja, das liegt daran das getServer zum JavaPlugin und nicht zum Listener gehört.

Wenn du eine Referenz auf dein Hauptklasse hast könntest du es so machen:
Code:
  plugin.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
Hierbei enthält "plugin" die Refenz auf deine Hauptklasse (extends JavaPlugin). Diese solltest du im Konstruktor des Listeners mit übergeben haben.

Wenn du keine Referenz hast könntest du es auch so machen:
Code:
  Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
Quote:
Originally Posted by nawiat100 View Post
@Howaner

dein code ging ^^ danke dir :p
Der Code von lordsill und mir funktioniert auch, wenn du die letze Korrektur gemacht hast. Diesen "Fehler" kannst du aber weder uns, noch wir dir, zuschreiben.

Es ist nicht ganz klar geworden was du tun willst, daher sind diese zwei unterscheidlichen Lösungen entstanden.

Die Lösung von lordsill und mir respawnt den Block, so wie du es beschrieben hattest, nach einer Sekunde wieder, wobei ich jetzt im nachhinein sagen muss, dass der Code nur ein von vielen Möglichkeiten abdeckt was ein Block alles sein kann. (So wären z.B. Wollefarben, Schildtexte oder Kisteninhalte nicht wiederhergestellt worden)

Die Lösung von Howaner bricht einfach das Event ab und verhindert damit, dass der Block überhaupt abgebaut wird. Das entspricht zwar nicht genau dem was du beschrieben hattest, ist dafür aber auch von den Fehlern der anderen Lösung befreit.