package tc.oc.pgm.match;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import org.bukkit.Color;
import org.bukkit.command.CommandSender;
import tc.oc.api.docs.PlayerId;
import tc.oc.commons.bukkit.chat.NameStyle;
import tc.oc.commons.bukkit.util.BukkitUtils;
import tc.oc.commons.core.chat.Audience;
import tc.oc.commons.bukkit.chat.Named;
import tc.oc.commons.core.chat.Component;
import tc.oc.commons.core.chat.Components;
import tc.oc.pgm.filters.Filterable;
import tc.oc.pgm.filters.query.IPartyQuery;
import javax.annotation.Nullable;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
public interface Party extends Named, IPartyQuery, Filterable<IPartyQuery> {
enum Type { Participating, Observing }
@Override
default Party getParty() {
return this;
}
/**
* The name of this party at match load time (for privileged viewers). This cannot change at any time during the match.
*/
String getDefaultName();
/**
* The current name of the party (for privileged viewers). May change at any time during the match.
*/
default String getName() {
return getDefaultName();
}
/**
* The current name of the party. May change at any time during the match.
*/
default String getName(@Nullable CommandSender viewer) {
return getName();
}
/**
* Should the name of the party be treated as a plural word grammatically?
* This applies to all possible names returned from any of the name methods.
*/
boolean isNamePlural();
ChatColor getColor();
default Color getFullColor() {
return BukkitUtils.colorOf(getColor());
}
/**
* The party's name (for privileged viewers) with color and no other decorations, legacy formatting
*/
default String getColoredName() {
return getColor() + getName();
}
/**
* The party's name with color and no other decorations, legacy formatting
*/
default String getColoredName(@Nullable CommandSender viewer) {
return getColor() + getName(viewer);
}
/**
* The party's name with color and no other decorations
*/
default BaseComponent getComponentName() {
return new Component(getName(), getColor());
}
@Override default BaseComponent getStyledName(NameStyle style) {
return getComponentName();
}
/**
* Everything before the player's name in chat output
*/
default BaseComponent getChatPrefix() {
return Components.blank();
}
/**
* All players currently in this party
*/
Set<MatchPlayer> getPlayers();
default Stream<MatchPlayer> players() {
return getPlayers().stream();
}
/**
* Party member with the given ID, or null if they are not in this party
*/
@Nullable MatchPlayer getPlayer(PlayerId playerId);
default Optional<MatchPlayer> player(PlayerId playerId) {
return players().filter(mp -> playerId.equals(mp.getPlayerId()))
.findAny();
}
/**
* Called by {@link Match} to add a player to this party.
*
* This method should not be called from anywhere else. This method only
* needs to modify the party's internal state. Everything else is
* handled by {@link Match}.
*/
boolean addPlayerInternal(MatchPlayer player);
/**
* Called by {@link Match} to remove a player from this party.
*
* This method should not be called from anywhere else. This method only
* needs to modify the party's internal state. Everything else is
* handled by {@link Match}.
*/
boolean removePlayerInternal(MatchPlayer player);
/**
* If true, the party will be automatically added to the match when the first
* player joins it, and automatically removed when it becomes empty. If false,
* the party will never be added or removed by core PGM, and the providing
* module must handle this.
*/
default boolean isAutomatic() {
return false;
}
Type getType();
default boolean isParticipatingType() {
return getType() == Type.Participating;
}
default boolean isParticipating() {
return isParticipatingType() && getMatch().isRunning();
}
default boolean isObservingType() {
return getType() == Type.Observing;
}
default boolean isObserving() {
return isObservingType() || !getMatch().isRunning();
}
Audience audience();
@Override
default Optional<? extends Filterable<? super IPartyQuery>> filterableParent() {
return Optional.of(getMatch());
}
@Override
default Stream<? extends Filterable<? extends IPartyQuery>> filterableChildren() {
return getPlayers().stream();
}
}