diff --git a/src/main/java/org/spongepowered/api/effect/ForwardingViewer.java b/src/main/java/org/spongepowered/api/effect/ForwardingViewer.java new file mode 100644 index 0000000000..3e41bfddee --- /dev/null +++ b/src/main/java/org/spongepowered/api/effect/ForwardingViewer.java @@ -0,0 +1,112 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.api.effect; + +import net.kyori.adventure.audience.ForwardingAudience; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.world.World; +import org.spongepowered.math.vector.Vector3i; + +import java.util.Collection; +import java.util.function.Supplier; + +/** + * ForwardingViewer represents some group of {@link Viewer}s + */ +public interface ForwardingViewer extends Viewer, ForwardingAudience { + + @Override + Iterable audiences(); + + /** + * Creates {@link ForwardingViewer} from provided viewers supplier. + * + * @param viewersSupplier The viewers supplier + * @return The forwarding viewer + */ + static ForwardingViewer of(final Supplier> viewersSupplier) { + return Sponge.game().factoryProvider().provide(Factory.class).of(viewersSupplier); + } + + /** + * Creates {@link ForwardingViewer} from provided viewers. + * + * @param viewers The viewers + * @return The forwarding viewer + */ + static ForwardingViewer of(final Collection viewers) { + return Sponge.game().factoryProvider().provide(Factory.class).of(viewers); + } + + /** + * Creates {@link ForwardingViewer} from provided viewers. + * + * @param viewers The viewers + * @return The forwarding viewer + */ + static ForwardingViewer of(final Viewer... viewers) { + return Sponge.game().factoryProvider().provide(Factory.class).of(viewers); + } + + /** + * Creates {@link ForwardingViewer} that will only affect viewers + * in the given area of the given world. + * + * @param world The world + * @param center The center of the area + * @param radius The radius of the area + * @return The forwarding viewer + */ + static ForwardingViewer allAround(final World world, final Vector3i center, final int radius) { + return Sponge.game().factoryProvider().provide(Factory.class).allAround(world, center, radius); + } + + /** + * Creates {@link ForwardingViewer} that will only affect viewers + * in the given radius from the given entity. + * + * @param entity The entity + * @param radius The radius + * @return The forwarding viewer + */ + static ForwardingViewer allAround(final Entity entity, final int radius) { + return Sponge.game().factoryProvider().provide(Factory.class).allAround(entity, radius); + } + + + interface Factory { + + ForwardingViewer of(Supplier> viewersSupplier); + + ForwardingViewer of(Collection viewers); + + ForwardingViewer of(Viewer... viewers); + + ForwardingViewer allAround(World world, Vector3i center, int radius); + + ForwardingViewer allAround(Entity entity, int radius); + } +} diff --git a/src/main/java/org/spongepowered/api/effect/Viewer.java b/src/main/java/org/spongepowered/api/effect/Viewer.java index d0e23ae2a9..9fe9d4d80c 100644 --- a/src/main/java/org/spongepowered/api/effect/Viewer.java +++ b/src/main/java/org/spongepowered/api/effect/Viewer.java @@ -41,54 +41,52 @@ /** * A Viewer is something that sees effects. - * The Viewer class contains methods for spawning particles and playing sound - * effects. + * E.g. the Viewer class contains methods for spawning particles and playing + * sound effects. */ public interface Viewer extends Audience { /** - * Sends the effect of being in a particular Vanilla world environment, such as the Nether, + * Sends the effect of being in a particular world environment, such as the Nether, * as an effect to the viewer. * - *

For example, specifying {@link WorldTypes#THE_NETHER} will create a red skybox and - * red hazy fog on the vanilla minecraft client

+ *

For example, specifying {@link WorldTypes#THE_NETHER} will create an empty skybox + * and hazy fog on the vanilla minecraft client

* * @param worldType The world type */ void sendWorldType(WorldType worldType); /** - * Spawn a {@link ParticleEffect} at a given position. - * All players within a default radius around the position will see the - * particles. + * Spawn the given {@link ParticleEffect} at the given position. * * @param particleEffect The particle effect to spawn - * @param position The position at which to spawn the particle effect + * @param position The position */ default void spawnParticles(final ParticleEffect particleEffect, final Vector3d position) { - this.spawnParticles(Objects.requireNonNull(particleEffect, "particleEffect"), Objects.requireNonNull(position, "position"), Integer.MAX_VALUE); + Objects.requireNonNull(position, "position"); + this.spawnParticles(particleEffect, position.x(), position.y(), position.z()); } /** - * Spawn a {@link ParticleEffect} at a given position. - * All players within a given radius around the position will see the - * particles. + * Spawn the given {@link ParticleEffect} at the given position. * * @param particleEffect The particle effect to spawn - * @param position The position at which to spawn the particle effect - * @param radius The radius around the position where the particles can be - * seen by players + * @param x The x position + * @param y The y position + * @param z The z position */ - void spawnParticles(ParticleEffect particleEffect, Vector3d position, int radius); + void spawnParticles(ParticleEffect particleEffect, double x, double y, double z); /** - * Plays a sound. + * Plays the given {@link Sound} at the given position. * - * @param sound the sound - * @param pos the position to play the sound at + * @param sound The sound + * @param position The position */ - default void playSound(final @NonNull Sound sound, final Vector3d pos) { - this.playSound(sound, pos.x(), pos.y(), pos.z()); + default void playSound(final @NonNull Sound sound, final Vector3d position) { + Objects.requireNonNull(position, "position"); + this.playSound(sound, position.x(), position.y(), position.z()); } /** @@ -98,16 +96,44 @@ default void playSound(final @NonNull Sound sound, final Vector3d pos) { * position will cancel the currently playing one. * * @param position The position - * @param musicDiscType The music disc + * @param musicDisc The music disc + */ + default void playMusicDisc(final Vector3i position, final MusicDisc musicDisc) { + Objects.requireNonNull(position, "position"); + this.playMusicDisc(position.x(), position.y(), position.z(), musicDisc); + } + + /** + * Plays the given {@link MusicDisc} at the given position. The benefit of playing + * {@link MusicDisc} instead of a {@link SoundType} allows you to stop them through + * the {@link #stopMusicDisc(Vector3i)}. Playing a new {@link MusicDisc} at the same + * position will cancel the currently playing one. + * + * @param x The x position + * @param y The y position + * @param z The z position + * @param musicDisc The music disc */ - void playMusicDisc(Vector3i position, MusicDisc musicDiscType); + void playMusicDisc(int x, int y, int z, MusicDisc musicDisc); /** * Stops the {@link MusicDisc} that is playing at the given position. * * @param position The position */ - void stopMusicDisc(Vector3i position); + default void stopMusicDisc(final Vector3i position) { + Objects.requireNonNull(position, "position"); + this.stopMusicDisc(position.x(), position.y(), position.z()); + } + + /** + * Stops the {@link MusicDisc} that is playing at the given position. + * + * @param x The x position + * @param y The y position + * @param z The z position + */ + void stopMusicDisc(int x, int y, int z); /** * Sends a client-only block change. @@ -119,7 +145,7 @@ default void playSound(final @NonNull Sound sound, final Vector3d pos) { */ default void sendBlockChange(final Vector3i position, final BlockState state) { Objects.requireNonNull(position, "position"); - this.sendBlockChange(position.x(), position.y(), position.z(), Objects.requireNonNull(state, "state")); + this.sendBlockChange(position.x(), position.y(), position.z(), state); } /** diff --git a/src/main/java/org/spongepowered/api/world/World.java b/src/main/java/org/spongepowered/api/world/World.java index 1a81f4bc66..40f46a19d8 100644 --- a/src/main/java/org/spongepowered/api/world/World.java +++ b/src/main/java/org/spongepowered/api/world/World.java @@ -24,9 +24,8 @@ */ package org.spongepowered.api.world; -import net.kyori.adventure.audience.Audience; -import net.kyori.adventure.audience.ForwardingAudience; import org.spongepowered.api.Server; +import org.spongepowered.api.effect.ForwardingViewer; import org.spongepowered.api.effect.Viewer; import org.spongepowered.api.entity.Entity; import org.spongepowered.api.entity.living.player.Player; @@ -51,12 +50,11 @@ */ @DoNotStore public interface World, L extends Location> extends - ForwardingAudience, + ForwardingViewer, WorldLike, LocationCreator, PhysicsAwareMutableBlockVolume, ContextSource, - Viewer, ArchetypeVolumeCreator, WeatherUniverse, RegistryHolder { @@ -92,7 +90,7 @@ default W world() { Collection players(); @Override - default Iterable audiences() { + default Iterable audiences() { return this.players(); }