Skip to content

Commit

Permalink
feat: bossbar (#447)
Browse files Browse the repository at this point in the history
  • Loading branch information
smartcmd authored Oct 13, 2024
1 parent bef3e85 commit 4fc006d
Show file tree
Hide file tree
Showing 7 changed files with 358 additions and 0 deletions.
4 changes: 4 additions & 0 deletions api/src/main/java/org/allaymc/api/AllayAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.allaymc.api.bossbar.BossBar;
import org.allaymc.api.command.selector.EntitySelectorAPI;
import org.allaymc.api.command.tree.CommandNodeFactory;
import org.allaymc.api.command.tree.CommandTree;
Expand Down Expand Up @@ -155,6 +156,9 @@ private void defaultAPIRequirements() {
requireImpl(EntitySelectorAPI.class, EntitySelectorAPI.API::set);
requireImpl(CommandTree.CommandTreeFactory.class, CommandTree.FACTORY::set);
requireImpl(CommandNodeFactory.class, CommandNodeFactory.FACTORY::set);

// Misc
requireImpl(BossBar.BossBarFactory.class, BossBar.FACTORY::set);
}

private record ApiBindingAction<T>(Supplier<T> bindingAction, Consumer<T> afterBound) {}
Expand Down
131 changes: 131 additions & 0 deletions api/src/main/java/org/allaymc/api/bossbar/BossBar.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package org.allaymc.api.bossbar;

import org.allaymc.api.ApiInstanceHolder;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.jetbrains.annotations.Range;
import org.jetbrains.annotations.UnmodifiableView;

import java.util.Collection;

/**
* BossBar will be shown at the top of the screen.
*
* @author daoge_cmd
*/
public interface BossBar {

ApiInstanceHolder<BossBarFactory> FACTORY = ApiInstanceHolder.create();

/**
* Create a new boss bar.
*
* @return the boss bar.
*/
static BossBar create() {
return FACTORY.get().create();
}

/**
* Add a viewer to the boss bar.
*
* @param viewer the viewer to add.
*/
void addViewer(EntityPlayer viewer);

/**
* Remove a viewer from the boss bar.
*
* @param viewer the viewer to remove.
*/
void removeViewer(EntityPlayer viewer);

/**
* Remove all viewers from the boss bar.
*/
default void removeAllViewers() {
getViewers().forEach(this::removeViewer);
}

/**
* Get the viewers of the boss bar.
*
* @return the viewers of the boss bar.
*/
@UnmodifiableView
Collection<EntityPlayer> getViewers();

/**
* Get the color of the boss bar.
*
* @return the color of the boss bar.
*/
BossBarColor getColor();

/**
* Set the color of the boss bar.
*
* @param color the color to set.
*/
void setColor(BossBarColor color);

/**
* Get the style of the boss bar.
*
* @return the style of the boss bar.
*/
BossBarStyle getStyle();

/**
* Set the style of the boss bar.
*
* @param style the style to set.
*/
void setStyle(BossBarStyle style);

/**
* Check if the boss bar will darken the sky
*
* @return {@code true} if the boss bar will darken the sky, otherwise {@code false}.
*/
boolean isDarkenSky();

/**
* Set if the boss bar will darken the sky.
*
* @param darkenSky {@code true} if the boss bar will darken the sky, otherwise {@code false}.
*/
void setDarkenSky(boolean darkenSky);

/**
* Get the progress of the boss bar.
*
* @return the progress of the boss bar, between 0 and 1.
*/
@Range(from = 0, to = 1)
float getProgress();

/**
* Set the progress of the boss bar.
*
* @param progress the progress to set, between 0 and 1.
*/
void setProgress(@Range(from = 0, to = 1) float progress);

/**
* Get the title of the boss bar.
*
* @return the title of the boss bar.
*/
String getTitle();

/**
* Set the title of the boss bar.
*
* @param name the title to set.
*/
void setTitle(String name);

interface BossBarFactory {
BossBar create();
}
}
17 changes: 17 additions & 0 deletions api/src/main/java/org/allaymc/api/bossbar/BossBarColor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.allaymc.api.bossbar;

/**
* Represents the color of boss bar.
*
* @author daoge_cmd
*/
public enum BossBarColor {
PINK,
BLUE,
RED,
GREEN,
YELLOW,
PURPLE,
REBECCA_PURPLE,
WHITE
}
29 changes: 29 additions & 0 deletions api/src/main/java/org/allaymc/api/bossbar/BossBarStyle.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.allaymc.api.bossbar;

/**
* Represents the style of a boss bar.
*
* @author daoge_cmd
*/
public enum BossBarStyle {
/**
* Makes the boss bar solid (no segments)
*/
SOLID,
/**
* Splits the boss bar into 6 segments
*/
SEGMENTED_6,
/**
* Splits the boss bar into 10 segments
*/
SEGMENTED_10,
/**
* Splits the boss bar into 12 segments
*/
SEGMENTED_12,
/**
* Splits the boss bar into 20 segments
*/
SEGMENTED_20
}
5 changes: 5 additions & 0 deletions server/src/main/java/org/allaymc/server/Allay.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.allaymc.api.block.property.BlockPropertyProcessor;
import org.allaymc.api.block.type.BlockType;
import org.allaymc.api.blockentity.type.BlockEntityType;
import org.allaymc.api.bossbar.BossBar;
import org.allaymc.api.command.selector.EntitySelectorAPI;
import org.allaymc.api.command.tree.CommandNodeFactory;
import org.allaymc.api.command.tree.CommandTree;
Expand All @@ -27,6 +28,7 @@
import org.allaymc.api.utils.Identifier;
import org.allaymc.api.MissingImplementationException;
import org.allaymc.api.world.generator.WorldGenerator;
import org.allaymc.server.bossbar.AllayBossBar;
import org.allaymc.server.command.selector.AllayEntitySelectorAPI;
import org.allaymc.server.command.tree.AllayCommandNodeFactory;
import org.allaymc.server.command.tree.AllayCommandTree;
Expand Down Expand Up @@ -155,6 +157,9 @@ private static void initAllayAPI() throws MissingImplementationException {
api.bind(CommandTree.CommandTreeFactory.class, () -> AllayCommandTree::create);
api.bind(CommandNodeFactory.class, AllayCommandNodeFactory::new);

// Misc
api.bind(BossBar.BossBarFactory.class, () -> AllayBossBar::new);

api.implement("allay");
log.info(I18n.get().tr(TrKeys.A_API_IMPLEMENTED, AllayAPI.getInstance().getCoreName(), GitProperties.getBranch() + "-" + GitProperties.getCommitIdAbbrev() + " " + GitProperties.getBuildVersion(), AllayAPI.API_VERSION));
}
Expand Down
117 changes: 117 additions & 0 deletions server/src/main/java/org/allaymc/server/bossbar/AllayBossBar.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package org.allaymc.server.bossbar;

import com.google.common.base.Preconditions;
import lombok.Getter;
import org.allaymc.api.bossbar.BossBar;
import org.allaymc.api.bossbar.BossBarColor;
import org.allaymc.api.bossbar.BossBarStyle;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.cloudburstmc.protocol.bedrock.packet.BossEventPacket;
import org.jetbrains.annotations.Range;
import org.jetbrains.annotations.UnmodifiableView;

import java.util.*;
import java.util.function.Consumer;

/**
* @author daoge_cmd
*/
public class AllayBossBar implements BossBar {

protected Set<EntityPlayer> viewers = new HashSet<>();
@Getter
protected String title = "";
@Getter
protected float progress = 1.0f;
@Getter
protected BossBarColor color = BossBarColor.PINK;
@Getter
protected BossBarStyle style = BossBarStyle.SOLID;
@Getter
protected boolean darkenSky = false;

@Override
public void addViewer(EntityPlayer viewer) {
viewers.add(viewer);
var pk = new BossEventPacket();
pk.setBossUniqueEntityId(viewer.getRuntimeId());
pk.setAction(BossEventPacket.Action.CREATE);
pk.setTitle(title);
pk.setHealthPercentage(progress);
pk.setDarkenSky(darkenSky ? 1 : 0);
pk.setColor(color.ordinal());
pk.setOverlay(style.ordinal());
viewer.sendPacket(pk);
}

@Override
public void removeViewer(EntityPlayer viewer) {
viewers.remove(viewer);
var pk = new BossEventPacket();
pk.setBossUniqueEntityId(viewer.getRuntimeId());
pk.setAction(BossEventPacket.Action.REMOVE);
viewer.sendPacket(pk);
}

@Override
public @UnmodifiableView Collection<EntityPlayer> getViewers() {
return Collections.unmodifiableSet(viewers);
}

@Override
public void setColor(BossBarColor color) {
this.color = color;
updateProperties();
}

@Override
public void setStyle(BossBarStyle style) {
this.style = style;
updateProperties();
}

@Override
public void setDarkenSky(boolean darkenSky) {
this.darkenSky = darkenSky;
sendPacketToViewers(pk -> {
pk.setAction(BossEventPacket.Action.UPDATE_PROPERTIES);
pk.setDarkenSky(darkenSky ? 1 : 0);
});
}

@Override
public void setProgress(@Range(from = 0, to = 1) float progress) {
Preconditions.checkArgument(progress >= 0 && progress <= 1, "Progress must be between 0 and 1");
this.progress = progress;
sendPacketToViewers(pk -> {
pk.setAction(BossEventPacket.Action.UPDATE_PERCENTAGE);
pk.setHealthPercentage(progress);
});
}

@Override
public void setTitle(String name) {
this.title = name;
sendPacketToViewers(pk -> {
pk.setAction(BossEventPacket.Action.UPDATE_NAME);
pk.setTitle(name);
});
}

protected void updateProperties() {
sendPacketToViewers(pk -> {
pk.setAction(BossEventPacket.Action.UPDATE_STYLE);
pk.setColor(color.ordinal());
pk.setOverlay(style.ordinal());
});
}

protected void sendPacketToViewers(Consumer<BossEventPacket> processor) {
viewers.forEach(viewer -> {
var pk = new BossEventPacket();
pk.setBossUniqueEntityId(viewer.getRuntimeId());
processor.accept(pk);
viewer.sendPacket(pk);
});
}
}
Loading

0 comments on commit 4fc006d

Please sign in to comment.