Sie sind nicht angemeldet.

  • Anmelden

RincewindCoding

User / Kunde

  • »RincewindCoding« ist männlich
  • »RincewindCoding« ist der Autor dieses Themas

Beiträge: 10

  • Nachricht senden

1

Samstag, 4. August 2018, 13:17

Spigot 1.13 (Partikel)



Einleitung

Durch die 1.13 wurde in der SpigotAPI und in dem NMS-Code vieles geändert. Viele alte Codeschnipsel, unter anderem für Partikel, funkionieren mit dem NMS-Code aus der 1.13 nicht mehr. In diesem Tutorial werfen wir einen Blick auf die neuen Möglichkeiten und Einschränkungen der 1.13 für Partikel.


Welche Werte besitzt ein Partikel
Beim Erstellen eines neuen Partikel müssen verschiedene Werte angegeben werden:
  • Location: Wo befindet sich der Partikel in der Welt
  • Long Distance: Wie weit wird ein Partikel von einem Spieler angezeigt. Dieser Wert ist keine Zahl, sondern ein Boolean. False für 32 Blöcke; True für 512 Blöcke.
  • Offset X/Y/Z: Der Offset beschreibt, wie weit ein Partikel zufällig von seiner präzisen Location abweicht. Wenn der Wert OffsetX beispielsweise auf 1 gesetzt wird, wird die X-Koordinate des Partikel zufällig verändert. Je größer der Wert für die Offsets, desto größer die Veränderung entlang der fraglichen Achse. Bei einigen Partikeln haben diese Werte einen anderen Effekt (s.u.).
  • Data / Speed: Dieser Wert ist eine Dezimalzahl, die sich stärker von Partikel zu Partikel unterscheidet. Bei fast allen Partikeln bewirkt dieser Wert, dass das Partikel in eine zufällige Richtung von seiner Location wegfliegt. Je höher dieser Wert, desto höher die Geschwindigkeit und desto weiter fliegt das Partikel. Aus diesem Grund wird bei diesem Wert häufig von Speed gesprochen. Die Richtung, in die das Partikel fliegt kann nicht weiter spezifiziert werden.
  • Count: Zusätzlich kann beim Erstellen eines Partikels mit angegeben werden, wie viele Partikel auf einmal erstellt werden sollen. Das ergibt grade in Kombination mit den Offset-Werten Sinn und spart Rechenleistung.
  • Complex-Data: Seit der 1.13 besitzen einige Partikel ein zusätzliches Datenobjekt. Dieses ist keine Zahl sondern bei dem Partikel itemuse ein ItemStack.
Das noch aus der 1.12 bekannte Integer-Array wurde für die 1.13 entfernt. Das Array diente bei den Block- und Itempartikeln dazu, das Material (bzw. die Id) anzugeben. Diese Werte werden ab der 1.13 durch die Complex-Data dargestellt.


Complex-Data
Vier Partikel beanspruchen diesen Wert: block (wenn bspw. ein Spieler über einen Block sprintet oder einen abbaut), dust (Redstonepartikel), fallingdust (wenn bspw. Sand oder Gravel in der Luft hängt), item (wenn bspw. ein Spieler ein Item isst oder ein Werkzeug kaputt geht).

Partikel: block
Für dieses Partikel ist die Data ein Blockdata-Objekt, das mit der 1.13 überarbeitet worden ist. Dieses Objekt enthält jede mögliche Information über den Block.

Partikel: dust
Der Redstonedust definiert über das Data-Objekt seine Farbe und, neu durch die 1.13, seine Größe. Die Farbe wird bei diesem Partikel also nicht mehr wie noch in der 1.12 durch die Offset-Werte eingestellt. Zusätzlich zu der Farbe kann durch eine Dezimalzahl die Größe des Partikels definiert werden, mit einem minimalen Wert von 0 und einem maximalen Wert von 4. Bei einem Wert von 4 ist das Partikel so groß wie möglich (ca. die Höhe eines Halfslabs).

Partikel: fallingdust
Wie auch bei dem Block-Partikel ein Blockdate-Objekt aus dem die Farbe des Partikels (clientseitig) errechnet wird. Es gibt keine Möglichkeit, die Farbe über einen RGB-Colorcode anzugeben.

Partikel: item
Ein Item-Partikel besteht aus einen Itemstack-Objekt


Partikel erstellen: Bukkit- / SpigotAPI
Um ein Partikel an einen Spieler zu senden, bietet Bukkit ein paar (sehr einschränkende) Möglichkeiten von Haus aus an. Da jedes Partikel in einer Welt erstellt wird, befinden sich die fraglichen Methoden in der Klasse World. Für die Auswahl eines bestimmten Partikel bietet Spigot das Enum Particle. Die folgenden Partikel werden an alle Spieler in der Welt gesendet, wenn sie sich in der fraglichen Reichweite befinden (s. Fußnoten).

Spoiler Spoiler

Beispiele

Quellcode

1
2
3
4
5
6
World world = /* ... */
Location location = /* ... */

world.spawnParticle(Particle.FLAME, location, 1); // Erstellt eine Flamme an der Location
world.spawnParticle(Particle.FLAME, location, 10); // Erstellt zehn Flammen an der Location
world.spawnParticle(Particle.FLAME, location, 10, 2.0D, 3.0D, 2.0D, 5.0D); // Erstellt zehn Flammen an der Location mit einem Offset von (X=2, Y=3, Z=2) und einem Speed von 5

Beispiele für die Complex-Data

Quellcode

1
2
3
4
5
World world = /* ... */
Location location = /* ... */

world.spawnParticle(Particle.ITEM_CRACK, location, 1, new ItemStack(Material.APPLE)); // Ein Apfel, der gegessen wird
world.spawnParticle(Particle.REDSTONE, location, 1, new Particle.DustOption(Color.BLUE, 2.0F)); // Ein blaues Redstone-Partikel mit der Größe 2

Partikel nur an bestimmte Spieler senden

Quellcode

1
2
3
4
Player player = /* ... */
Location location = /* ... */

player.spawnParticle(Particle.FLAME, location, 1); // Die Flamme wird nur einem bestimmten Spieler gesendet

Fußnoten
  • Der boolsche Wert für die Sichtweite des Partikels kann über Spigot nicht eingestellt werden. Ein Partikel wird immer nur 32 Blöcke weit angezeigt.
  • Das Enum Particle stellt die Konstanten BLOCK_DUST und BLOCK_CRACK bereit. Diese verweisen seit der 1.13 auf das selbe Partikel.
  • Ich habe in der SpigotAPI keine Möglichkeit gefunden eine eigene BlockData zu erstellen, weshalb es keine Beispiele für die Partikel block und fallingdust gibt.

Partikel erstellen: NMS
Die Partikel über NMS zu senden, ermöglicht eine geringfügig verbesserte Konfiguration der Partikel (bspw. der Long-Distance-Wert) und kann Performancevorteile haben. Der Code wird auf der anderen Seite allerdings deutlich unleserlicher.
Vor den Beispielen eine kleine Übersicht an Methoden, die zur Verfügung stehen:

Spoiler Spoiler

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* Sendet das Partikel an alle Spieler in der Welt (longDistance => false)
* 
* @return Die Anzahl an Spielern, die das erstelle Partikel zu sehen bekommen (unter Berücksichtigung der 32 Blockreichweite).
*/
WorldServer#a(ParticleParam particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double speed) : int

/**
* Sendet das Partikel an alle Spieler in der Welt (longDistance => false), die den angegeben Spieler 'player' sehen können.
* Ob der angegebene Spieler 'player' für einen anderen Spieler 'target' zu sehen ist, wird durch die Spigotmethode org.bukkit.entity.Player#canSee(Player) definiert.
* 
* @return Die Anzahl an Spielern, die das erstelle Partikel zu sehen bekommen (unter Berücksichtigung der 32 Blockreichweite & #canSee(Player)).
*/
WorldServer#sendParticles(EntityPlayer player, ParticleParam particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double speed) 

/**
* Sendet das Partikel an den angegebenen Spieler in der Welt. Durch diese Methode kann erstmalig der Wert für Long-Distance definiert werden.
* Das Partikel wird nur an den Spieler gesendet, wenn sich der Spieler in der aufrufenden Welt befindet und in der Reichweite (32 oder 512 Blöcke).
* 
* @return True, wenn das Partikel an den Spieler gesendet worden ist, andernfalls false.
*/
WorldServer#a(EntityPlayer target, ParticleParam particle, boolean longDistance, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double speed) : boolean

Code-Beispiele

Spoiler Spoiler

Quellcode

1
2
3
4
5
6
7
8
9
10
11
org.bukkit.World world = /* ... */
WorldServer nmsWorld = ((CraftWorld) world).getHandle();

nmsWorld.a(Particles.y, < x, y, z>, 1, <offsetX, offsetY, offsetZ, speed>); // Erstellt einen Flammen-Partikel in der Welt (s. Fußnote 1)

org.bukkit.Color color = /* ... */;
nmsWorld.a(new ParticleParamRedstone(color.getRed / 255.0F, color.getGreen() / 255.0F, color.getBlue() / 255.0F, 1.0F)); // Erstellt einen Redstone-Partikel beliebiger Farbe mit der Größe 1.

nmsWorld.a(new ParticleParamItem(Particles.C, new net.minecraft.server.v1_13_R1.ItemStack(Items.APPLE)), < x, y, z>, 1, <offsetX, offsetY, offsetZ, speed>); // Erstellt Apfel-Partikel
nmsWorld.a(new ParticleParamBlock(Particles.d, Blocks.STONE.getBlockData()), < x, y, z>, 1, <offsetX, offsetY, offsetZ, speed>); // Erstellt Stein-Partikel beim Abbauen
nmsWorld.a(new ParticleParamBlock(Particles.v, Blocks.STONE.getBlockData()), < x, y, z>, 1, <offsetX, offsetY, offsetZ, speed>); // Erstellt Stein-Partikel als Fallingdust

Fußnoten
  • Die Klasse Particles ist das NMS-Equivalent zu dem von Spigot bereitgestellten Enum Particle. Eine genaue Auflistung findet sich weiter unten.
  • Die Farbe der Redstone-Partikel im Spektrum RGB durch eine Dezimalzahl zwischen 0 und 1 dargestellt, nicht wie bei Spigot zwischen 0 und 255.

Potionpartikel färben
Um Potionpartikel (Particle.SPELL_MOB / Particles.s) zu färben, muss der Wert Count auf 0 und der Wert Speed auf 1 gesetzt werden. Durch die Offset-Werte kann jetzt der Farbton definiert werden.

Quellcode

1
2
org.bukkit.Color color = /* ... */
world.spawnParticle(Particle.SPELL_MOB, location, 0, color.getRed / 255.0F, color.getGreen() / 255.0F, color.getBlue() / 255.0F, 1); // Ein Potionpartikel in einer beliebigen Farbe.

Wenn der Count-Wert auf >0 gesetzt wird, funkionieren die Offset-Werte wie bei allen anderen Partikeln auch. Bei einem Speed-Wert >0 und einem Count-Wert >0, erhalten die Partikel eine zufällige Farbe.


Partikel Liste
Für die folgenden Partikel gilt bei den Werten offsetX/-Y/-Z und speed das oben beschriebene Verhalten.

Spoiler Spoiler

# Particle.BARRIER (Particles.c)
# Particle.CLOUD (Particles.g)
# Particle.CRIT (Particles.h)
# Particle.DAMAGE_INDICATOR (Particles.i)
# Particle.DRAGON_BREATH (Particles.j)
# Particle.SPELL (Particles.n) weiße Potionpartikel
# Particle.CRIT_MAGIC (Particles.p)
# Particle.END_ROD (Particles.r)
# Particle.EXPLOSION_HUGE (Particles.t) vollständige Explosion
# Particle.EXPLOSION_LARGE (Particles.u) einzelner Explosionspartikel
# Particle.FIREWORKS_SPARK (Particles.w)
# Particle.WATER_WAKE (Particles.x) Partikel eines Fischers, der auf die Angel zuschwimmt
# Particle.FLAME (Particles.y)
# Particle.SPELL_INSTANT (Particles.B) weiße Instantpotionpartikel
# Particle.SMOKE_LARGE (Particles.F) große schwarze Rauchpartikel
# Particle.EXPLOSION_NORMAL (Particles.J) große weiße Wolken (aus Explosionen)
# Particle.SMOKE_NORMAL (Particles.M) kleine schwarze Rauchpartikel
# Particle.SPIT (Particles.N)
# Particle.TOTEM (Particles.P) von dem "Totem Of Undying"
# Particle.SPELL_WITCH (Particles.S)
# Particle.BUBBLE_POP (Particles.T) wenn eine Wasserblase platzt
# Particle.SQUID_INK (Particles.V)

Für diese Partikel gilt nur die oben beschriebene Definition von offsetX/-Y/-Z. Der Wert für Speed hat keinen Einfluss.

Spoiler Spoiler

# Particle.VILLAGER_ANGRY (Particles.b)
# Particle.DRIP_LAVA (Particles.k)
# Particle.DRIP_WATER (Particles.l)
# Particle.VILLAGER_HAPPY (Particles.z)
# Particle.HEART (Particles.A)
# Particle.SLIME (Particles.D)
# Particle.SNOWBALL (Particles.E)
# Particle.LAVA (Particles.G)
# Particle.TOWN_AURA (Particles.H) Myceliumpartikel
# Particle.WATER_DROP (Particles.L) wenn Regentropfen den Boden treffen
# Particle.SWEEP_ATTACK (Particles.O)
# Particle.WATER_SPLASH (Particles.R) wenn ein Entity ins Wasser fällt
# Particle.DOLPHIN (Particles.X)

Diese Partikel fliegen bei einem Speed-Wert >0 in die angegebene Position hinein und nicht wie alle anderen hinaus.

Spoiler Spoiler

# Particle.ENCHANTMENT_TABLE (Particles.q)
# Particle.PORTAL (Particles.K)
# Particle.NAUTILUS (Particles.W)

Diese Partikel werden ausschließlich in einem Wasserblock angezeigt. Der Speed-Wert funktioniert nicht für alle Partikel

Spoiler Spoiler

# Particle.WATER_BUBBLE (Particles.e) normale Luftblasen (Speed-Wert funktioniert normal)
# Particle.BUBBLE_COLUMN_UP (Particles.f) aufsteigende Luftblasen (Speed-Wert hat keine Funktion)
# Particle.SUSPENDED_DEPTH (Particles.Q) einzelne Partikel im Wasser (Speed-Wert hat keine Funktion)
# Particle.BUBBLE_COLUMN_UP (Particles.U) kreisförmig absteigende Luftblasen (Speed-Wert hat keine Funktion)

Besondere Partikel

Spoiler Spoiler

# Particle.NOTE (Particles.I) bei einem Speed-Wert >0 wird eine zufällige Farbe gesetzt; offset funktioniert normal
# Particle.MOB_APPEARANCE (Particles.o) der Spieler sieht vor sich einen Elderguardian; Position-/ Speed- und Offset-Werte haben keine Funktion

Färbbare Partikel

Spoiler Spoiler

# Particle.SPELL_MOB_AMBIENT (Particles.a) leicht durchsichtige Potion-Partikel
# Particle.SPELL_MOB (Particles.s) normale Potion-Partikel

RincewindCoding

User / Kunde

  • »RincewindCoding« ist männlich
  • »RincewindCoding« ist der Autor dieses Themas

Beiträge: 10

  • Nachricht senden

2

Donnerstag, 1. November 2018, 08:16

Hier einmal ein kleiner Nachtrag:

Lucascrafterlp hat mich freundlicher Weise darauf hingewiesen, dass in Spigot/Bukkit sogar einen sehr einfachen Weg gibt, eine BlockData zu erstellen mit Bukkit#createBlockData(...).

MfG,
Rincewind