diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/page/PageCalculation.java b/common/src/main/java/net/onelitefeather/cygnus/common/page/PageCalculation.java
index 01ea13d..8da41b6 100644
--- a/common/src/main/java/net/onelitefeather/cygnus/common/page/PageCalculation.java
+++ b/common/src/main/java/net/onelitefeather/cygnus/common/page/PageCalculation.java
@@ -4,24 +4,27 @@
import net.onelitefeather.cygnus.common.config.GameConfig;
/**
- * This class calculates the amount of pages that should be allocated for the dynamic page system.
- * The amount of pages is calculated based on the amount of players online.
- * If the amount of players online is less than 4, the minimum amount of pages will be returned.
- * Otherwise, the amount of pages will be calculated based on the amount of players online.
+ * Utility class for calculating the number of pages allocated for the dynamic page system.
+ * The page count is based on the number of current online players.
*
* @author theEvilReaper
- * @version 1.0.0
+ * @version 1.1.0
* @since 1.0.0
*/
+
public final class PageCalculation {
private static final int PLAYER_SIZE_FOR_DYNAMIC_PAGE_ALLOCATION = 4;
private static final int PAGE_COUNT_MULTIPLIER = 2;
/**
- * Calculates the amount of pages that should be allocated for the dynamic page system.
+ * Calculates the number of pages to allocate for the dynamic page system.
+ *
+ * If the number of online players (excluding one) is less than {@value #PLAYER_SIZE_FOR_DYNAMIC_PAGE_ALLOCATION},
+ * {@link GameConfig#MIN_PAGE_COUNT} is returned. Otherwise, the page count is determined by
+ * multiplying the adjusted player count by {@value #PAGE_COUNT_MULTIPLIER}.
*
- * @return the amount of pages that should be allocated
+ * @return the number of pages to allocate, at least {@link GameConfig#MIN_PAGE_COUNT}
*/
public static int calculatePageAmount() {
int currentPlayers = MinecraftServer.getConnectionManager().getOnlinePlayers().size();
diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/page/PageEntity.java b/common/src/main/java/net/onelitefeather/cygnus/common/page/PageEntity.java
index f7ff101..3887cd3 100644
--- a/common/src/main/java/net/onelitefeather/cygnus/common/page/PageEntity.java
+++ b/common/src/main/java/net/onelitefeather/cygnus/common/page/PageEntity.java
@@ -22,14 +22,13 @@
import java.util.concurrent.CompletableFuture;
/**
- * The {@link PageEntity} is a custom entity which represents a page that can be collected by the player.
- * The entity is used to display the page and to interact with it.
- * To improve the interaction the entity has a hitbox which is used to detect the interaction.
+ * Represents a collectible page entity that can be picked up by a player.
+ * The entity consists of a visual display and an interaction hitbox to improve pickup detection.
*
* @author theEvilReaper
- * @version 1.0.0
+ * @version 1.1.0
* @since 1.0.0
- **/
+ */
@SuppressWarnings("java:S3252")
public final class PageEntity extends Entity {
diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/page/PageProvider.java b/common/src/main/java/net/onelitefeather/cygnus/common/page/PageProvider.java
index 7700f2b..b554a75 100644
--- a/common/src/main/java/net/onelitefeather/cygnus/common/page/PageProvider.java
+++ b/common/src/main/java/net/onelitefeather/cygnus/common/page/PageProvider.java
@@ -3,13 +3,15 @@
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Direction;
import net.minestom.server.utils.validate.Check;
import net.onelitefeather.cygnus.common.Messages;
+import net.onelitefeather.cygnus.common.page.event.PageDiscoveryCompletedEvent;
import net.onelitefeather.cygnus.common.util.Helper;
import net.theevilreaper.aves.util.Broadcaster;
-import net.theevilreaper.aves.util.functional.VoidConsumer;
+import net.theevilreaper.xerus.api.phase.GamePhase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,8 +28,10 @@
import static net.onelitefeather.cygnus.common.config.GameConfig.MIN_ACTIVE_PAGE_COUNT;
/**
+ * Handles the logic to manage and spawn pages during the {@link GamePhase}.
+ *
* @author theEvilReaper
- * @version 1.0.0
+ * @version 1.1.0
* @since 1.0.0
**/
@SuppressWarnings("java:S3252")
@@ -37,7 +41,6 @@ public final class PageProvider {
private static final Lock CACHE_LOCK = new ReentrantLock();
private static final Lock PAGE_LOCK = new ReentrantLock();
- private final VoidConsumer pageFinishFunction;
private final List globalCache;
private final Map activePages;
private final Map usedResources;
@@ -47,8 +50,7 @@ public final class PageProvider {
private Component pageStatus = Component.empty();
- public PageProvider(VoidConsumer pageFinishFunction) {
- this.pageFinishFunction = pageFinishFunction;
+ public PageProvider() {
this.globalCache = new ArrayList<>();
this.usedResources = new HashMap<>();
this.activePages = new HashMap<>();
@@ -57,13 +59,18 @@ public PageProvider(VoidConsumer pageFinishFunction) {
this.currentPageCount = 1;
}
- public void loadPageData(Set positions) {
+ /**
+ * Loads the required page data from the given set of {@link PageResource}s.
+ *
+ * @param resources given set of page resources
+ */
+ public void loadPageData(Set resources) {
Check.argCondition(!globalCache.isEmpty(), "Can't load pages twice");
- if (positions.isEmpty()) {
+ if (resources.isEmpty()) {
throw new IllegalStateException("Can't load a map without any pages");
}
- this.globalCache.addAll(positions);
+ this.globalCache.addAll(resources);
}
public void collectStartPages(Instance instance) {
@@ -90,6 +97,11 @@ public void collectStartPages(Instance instance) {
LOGGER.info("This current page count is {}", currentPageCount);
}
+ /**
+ * Sets the max page amount.
+ *
+ * @param maxPageAmount to set
+ */
public void setMaxPageAmount(int maxPageAmount) {
if (this.maxPageAmount != 0) {
throw new IllegalStateException("The max page amount can't be set twice");
@@ -97,6 +109,9 @@ public void setMaxPageAmount(int maxPageAmount) {
this.maxPageAmount = maxPageAmount;
}
+ /**
+ * Spawns all pages that are currently in the active page map.
+ */
public void spawn() {
this.updatePageDisplay();
try {
@@ -119,7 +134,6 @@ public void cleanUp() {
}
public void triggerTTLHandling(UUID uuid) {
- // Fix #8: isEmpty-Check VOR removeEntity, damit activePages.get(uuid) noch gültig ist
if (this.globalCache.isEmpty()) {
this.activePages.get(uuid).enableInteraction();
return;
@@ -140,7 +154,6 @@ public void triggerTTLHandling(UUID uuid) {
pageEntity.teleport(Helper.updatePosition(newPos.position().asPos(), newPos.face()));
- // Fix #6: activePages.put unter PAGE_LOCK statt CACHE_LOCK
try {
PAGE_LOCK.lock();
this.activePages.put(pageEntity.getHitBoxUUID(), pageEntity);
@@ -161,7 +174,7 @@ public void triggerPageFound(Player player, UUID uuid) {
updatePageData(pageEntity);
if (this.currentFoundedPageCount >= maxPageAmount) {
- this.pageFinishFunction.apply();
+ EventDispatcher.call(new PageDiscoveryCompletedEvent());
}
}
diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/page/PageResource.java b/common/src/main/java/net/onelitefeather/cygnus/common/page/PageResource.java
index 1455aae..436522c 100644
--- a/common/src/main/java/net/onelitefeather/cygnus/common/page/PageResource.java
+++ b/common/src/main/java/net/onelitefeather/cygnus/common/page/PageResource.java
@@ -8,7 +8,8 @@
* during the GamePhase. It includes a string variable that represents the face used in the setup process.
* When spawning a page entity, it uses the opposite face from the provided face.
*
- * @param position The position at which to spawn a page.
- * @param face The face used in the resource setup process.
+ * @param position at which to spawn a page
+ * @param face used in the resource setup process
*/
-public record PageResource(Point position, Direction face) { }
\ No newline at end of file
+public record PageResource(Point position, Direction face) {
+}
\ No newline at end of file
diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/page/event/PageDiscoveryCompletedEvent.java b/common/src/main/java/net/onelitefeather/cygnus/common/page/event/PageDiscoveryCompletedEvent.java
new file mode 100644
index 0000000..ce5178b
--- /dev/null
+++ b/common/src/main/java/net/onelitefeather/cygnus/common/page/event/PageDiscoveryCompletedEvent.java
@@ -0,0 +1,13 @@
+package net.onelitefeather.cygnus.common.page.event;
+
+import net.minestom.server.event.Event;
+
+/**
+ * Event will be fired when each available page has been discovered by the players.
+ *
+ * @author theEvilReaper
+ * @version 1.0.0
+ * @since 2.3.1
+ */
+public class PageDiscoveryCompletedEvent implements Event {
+}
diff --git a/common/src/test/java/net/onelitefeather/cygnus/common/page/PageProviderTest.java b/common/src/test/java/net/onelitefeather/cygnus/common/page/PageProviderTest.java
index 84d5e96..d36dd05 100644
--- a/common/src/test/java/net/onelitefeather/cygnus/common/page/PageProviderTest.java
+++ b/common/src/test/java/net/onelitefeather/cygnus/common/page/PageProviderTest.java
@@ -15,7 +15,7 @@ void testPageTwiceLoading() {
Set pageResources = Set.of(
new PageResource(Pos.ZERO, Direction.NORTH)
);
- PageProvider pageProvider = new PageProvider(() -> {});
+ PageProvider pageProvider = new PageProvider();
assertNotNull(pageProvider);
pageProvider.loadPageData(pageResources);
@@ -31,7 +31,7 @@ void testPageTwiceLoading() {
@Test
void testEmptyPageResourceUsage() {
- PageProvider pageProvider = new PageProvider(() -> {});
+ PageProvider pageProvider = new PageProvider();
assertNotNull(pageProvider);
Set pageResources = Set.of();
diff --git a/game/src/main/java/net/onelitefeather/cygnus/Cygnus.java b/game/src/main/java/net/onelitefeather/cygnus/Cygnus.java
index fa22702..98df69d 100644
--- a/game/src/main/java/net/onelitefeather/cygnus/Cygnus.java
+++ b/game/src/main/java/net/onelitefeather/cygnus/Cygnus.java
@@ -1,7 +1,9 @@
package net.onelitefeather.cygnus;
+import net.onelitefeather.cygnus.common.page.event.PageDiscoveryCompletedEvent;
import net.onelitefeather.cygnus.event.GameStartEvent;
import net.onelitefeather.cygnus.listener.game.GameStartListener;
+import net.onelitefeather.cygnus.listener.page.PageDiscoveryCompleteListener;
import net.onelitefeather.cygnus.map.GameMapProvider;
import net.onelitefeather.cygnus.map.event.GameMapLoadedEvent;
import net.theevilreaper.aves.map.provider.AbstractMapProvider;
@@ -96,7 +98,7 @@ public Cygnus() {
this.staminaService = new StaminaService();
this.gameConfig = new GameConfigReader(path).getConfig();
MinecraftServer.getConnectionManager().setPlayerProvider(CygnusPlayer::new);
- this.pageProvider = new PageProvider(this::handleAllPageFound);
+ this.pageProvider = new PageProvider();
this.mapProvider = new GameMapProvider(path);
this.view = new GameViewImpl(this::getViewComponent);
this.createTeams(this.gameConfig, this.teamService, this.ambientProvider);
@@ -112,12 +114,6 @@ private void initCommands() {
manager.register(new StartCommand(this.linearPhaseSeries));
}
- private void handleAllPageFound() {
- var gamePhase = (GamePhase) this.linearPhaseSeries.getCurrentPhase();
- gamePhase.setFinishEvent(new GameFinishEvent(GameFinishEvent.Reason.ALL_PAGES_FOUND));
- gamePhase.finish();
- }
-
private void initListener() {
Supplier phaseSupplier = this.linearPhaseSeries::getCurrentPhase;
var manager = MinecraftServer.getGlobalEventHandler();
@@ -155,6 +151,7 @@ private void registerGameListener() {
SlenderReviveEvent.class, new SlenderReviveListener(((GameMapProvider) this.mapProvider).getGameMap(), this.staminaService));
manager.addListener(GamePreLaunchEvent.class, new GamePreLaunchListener(this.pageProvider::setMaxPageAmount));
manager.addListener(StaminaStateChangeEvent.class, new StaminaStateChangeListener());
+ manager.addListener(PageDiscoveryCompletedEvent.class, new PageDiscoveryCompleteListener(this.linearPhaseSeries));
MinecraftServer.getPacketListenerManager().setPlayListener(ClientEntityActionPacket.class, CygnusEntityActionListener::listener);
}
diff --git a/game/src/main/java/net/onelitefeather/cygnus/listener/page/PageDiscoveryCompleteListener.java b/game/src/main/java/net/onelitefeather/cygnus/listener/page/PageDiscoveryCompleteListener.java
new file mode 100644
index 0000000..3469371
--- /dev/null
+++ b/game/src/main/java/net/onelitefeather/cygnus/listener/page/PageDiscoveryCompleteListener.java
@@ -0,0 +1,25 @@
+package net.onelitefeather.cygnus.listener.page;
+
+import net.onelitefeather.cygnus.common.page.event.PageDiscoveryCompletedEvent;
+import net.onelitefeather.cygnus.event.GameFinishEvent;
+import net.onelitefeather.cygnus.phase.GamePhase;
+import net.theevilreaper.xerus.api.phase.LinearPhaseSeries;
+import net.theevilreaper.xerus.api.phase.TimedPhase;
+
+import java.util.function.Consumer;
+
+public final class PageDiscoveryCompleteListener implements Consumer {
+
+ private final LinearPhaseSeries phaseSeries;
+
+ public PageDiscoveryCompleteListener(LinearPhaseSeries phaseSeries) {
+ this.phaseSeries = phaseSeries;
+ }
+
+ @Override
+ public void accept(PageDiscoveryCompletedEvent event) {
+ if (!(this.phaseSeries.getCurrentPhase() instanceof GamePhase gamePhase)) return;
+ gamePhase.setFinishEvent(new GameFinishEvent(GameFinishEvent.Reason.ALL_PAGES_FOUND));
+ gamePhase.finish();
+ }
+}