Refactored Score system

This commit is contained in:
Elias Müller 2023-09-30 21:58:08 +02:00
parent 4fc8503d63
commit eecdeff77c
33 changed files with 248 additions and 103 deletions

Binary file not shown.

1
.idea/misc.xml generated
View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<list size="1">

2
.idea/modules.xml generated
View File

@ -4,6 +4,8 @@
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Minigames.main.iml" filepath="$PROJECT_DIR$/.idea/modules/Minigames.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Minigames.test.iml" filepath="$PROJECT_DIR$/.idea/modules/Minigames.test.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/eu.mhsl.minenet.Minigames.main.iml" filepath="$PROJECT_DIR$/.idea/modules/eu.mhsl.minenet.Minigames.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/eu.mhsl.minenet.Minigames.test.iml" filepath="$PROJECT_DIR$/.idea/modules/eu.mhsl.minenet.Minigames.test.iml" />
</modules>
</component>
</project>

View File

@ -9,4 +9,8 @@
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -9,4 +9,8 @@
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>ADVENTURE</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
</module>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>ADVENTURE</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
</module>

View File

@ -33,7 +33,11 @@ dependencies {
//https://jitpack.io/#Minestom/Minestom
//implementation 'com.github.Minestom:Minestom:aa621021e2'
implementation 'com.github.Minestom.Minestom:Minestom:79ce9570ea'
//implementation 'com.github.Minestom.Minestom:Minestom:4f7ff5b474'
// implementation 'com.github.Minestom.Minestom:Minestom:2cdb3911b0'
// implementation 'com.github.Minestom:MinestomDataGenerator:ddde11056e'
implementation 'com.github.waxeria:Minestom:e0427a36f3'
//Tools
//implementation 'com.github.Articdive.JNoise:jnoise-core:4.0.0'

View File

@ -37,7 +37,8 @@ join_notFound;Lobby not found: ;Lobby konnte nicht gefunden werden:
ns:score#;;
result;Results;Ergebnisse
thanks;Thank you for Playing;Danke für‘s spielen
finish;Finish;Fertig
finish;Yout did it;Du hast es geschafft
death;You are out;Du hast verloren
;;
ns:restriction#;;
fail;Some requirements are not met;Bedinungen sind nicht erfüllt
@ -83,3 +84,8 @@ description;Only go forward if the Trafficlights show green;Gehe nur bei Grün v
ns:game_Towerdefense#;;
name;Towerdefense;Towerdefense
description;Protect the path ????;??????
;;
ns:game_Spleef#;;
name;Spleef;Spleef;
description;Spleef other players and be the last survivor;Zerstöre Blöcke unter anderen Spielern und sei der letzte im Feld
shovelName;Snow thrower;Schneeflug
Can't render this file because it has a wrong number of fields in line 89.

View File

@ -37,7 +37,8 @@ join_notFound;Lobby not found: ;Lobby konnte nicht gefunden werden:
ns:score#;;
result;Results;Ergebnisse
thanks;Thank you for Playing;Danke für‘s spielen
finish;Finish;Fertig
finish;Yout did it;Du hast es geschafft
death;You are out;Du hast verloren
;;
ns:restriction#;;
fail;Some requirements are not met;Bedinungen sind nicht erfüllt
@ -83,3 +84,8 @@ description;Only go forward if the Trafficlights show green;Gehe nur bei Grün v
ns:game_Towerdefense#;;
name;Towerdefense;Towerdefense
description;Protect the path ????;??????
;;
ns:game_Spleef#;;
name;Spleef;Spleef;
description;Spleef other players and be the last survivor;Zerstöre Blöcke unter anderen Spielern und sei der letzte im Feld
shovelName;Snow thrower;Schneeflug
Can't render this file because it has a wrong number of fields in line 89.

View File

@ -101,7 +101,7 @@ public abstract class Game extends MineNetInstance implements Spawnable {
}, TaskSchedule.seconds(10), TaskSchedule.stop());
}
protected void onLoad(CompletableFuture<Void> callback) {
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
callback.complete(null);
}
@ -133,7 +133,7 @@ public abstract class Game extends MineNetInstance implements Spawnable {
protected void checkAbandoned() {
scheduleNextTick((instance) -> {
if(instance.getPlayers().size() == 0) this.unload();
if(instance.getPlayers().isEmpty()) this.unload();
});
}

View File

@ -18,14 +18,14 @@ import java.util.concurrent.CompletableFuture;
public class StatelessGame extends Game {
private final String name;
private final Score score = new Score(this);
private Score score;
private int timeLimit = 0;
private int timePlayed = 0;
private final boolean preventExit = false;
public StatelessGame(DimensionType dimensionType, String gameName) {
public StatelessGame(DimensionType dimensionType, String gameName, Score score) {
super(dimensionType);
this.score = score;
this.name = gameName;
}
@ -61,6 +61,9 @@ public class StatelessGame extends Game {
@Override
protected void start() {
score.setInstance(this);
score.attachListeners();
countdownStart().thenRun(() -> {
super.start();

View File

@ -2,13 +2,19 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.NoScore;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import org.jetbrains.annotations.NotNull;
public class Backrooms extends StatelessGame {
public Backrooms() {
super(Dimension.NETHER.DIMENSION, "Backrooms");
super(Dimension.NETHER.DIMENSION, "Backrooms", new NoScore());
BackroomsGenerator generator = new BackroomsGenerator();
setGenerator(unit -> generator.generateRoom(unit, 50));
}
@Override
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent playerBlockBreakEvent) {
playerBlockBreakEvent.setCancelled(false);
}
}

View File

@ -5,6 +5,7 @@ import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.data.BedwarsTeam;
import eu.mhsl.minenet.minigames.message.type.ActionBarMessage;
import eu.mhsl.minenet.minigames.score.LastWinsScore;
import eu.mhsl.minenet.minigames.util.MaterialUtil;
import eu.mhsl.minenet.minigames.util.Position;
import net.kyori.adventure.text.Component;
@ -37,7 +38,7 @@ public class Bedwars extends StatelessGame {
public Bedwars() throws IOException {
super(Dimension.OVERWORLD.DIMENSION, "Bedwars");
super(Dimension.OVERWORLD.DIMENSION, "Bedwars", new LastWinsScore());
setChunkLoader(new AnvilLoader(Resource.GAME_MAP.getPath().resolve("bedwars/test")));
Configuration config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(Resource.GAME_MAP.getPath().resolve("bedwars/test/config.yml").toFile());

View File

@ -1,6 +1,7 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.world.generator.BlockPallet;
@ -22,7 +23,7 @@ class Deathcube extends StatelessGame {
final int percentage;
public Deathcube(int radius, int height, int percentage, int pvpEnabled) {
super(Dimension.THE_END.DIMENSION, "Deathcube");
super(Dimension.THE_END.DIMENSION, "Deathcube", new FirstWinsScore());
this.radius = radius;
this.height = height + 49;
this.percentage = percentage;
@ -38,7 +39,7 @@ class Deathcube extends StatelessGame {
}
@Override
protected void onLoad(CompletableFuture<Void> callback) {
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = -radius; x <= radius; x++) {

View File

@ -2,6 +2,7 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.message.type.ActionBarMessage;
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.util.Intersect;
import eu.mhsl.minenet.minigames.instance.Dimension;
@ -24,16 +25,16 @@ import java.util.concurrent.CompletableFuture;
class Minerun extends StatelessGame {
private int minePercentage = 50;
private int width = 100;
private int length = 50;
private int minePercentage;
private int width;
private int length;
private final int preRun = 5;
private final int afterMines = 2;
private final int afterFinishLine = 10;
public Minerun(int width, int length, int minePercentage) {
super(Dimension.THE_END.DIMENSION, "Minerun");
super(Dimension.THE_END.DIMENSION, "Minerun", new FirstWinsScore());
setGenerator(new SquareTerrainGenerator(width, length + preRun + afterFinishLine, true));
this.width = width;
@ -42,7 +43,7 @@ class Minerun extends StatelessGame {
}
@Override
protected void onLoad(CompletableFuture<Void> callback) {
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
int spawnToFinishLine = preRun + length + afterMines;
Random random = new Random();
@ -97,9 +98,9 @@ class Minerun extends StatelessGame {
playerMoveEvent.setCancelled(true);
}
if(getScore().hasResult(p) && middle.z() < preRun + length + afterMines) { // player cannot go back
playerMoveEvent.setCancelled(true);
new ActionBarMessage().appendStatic(Component.text("You cannot go back on the Field!", NamedTextColor.RED)).send(p);
if(middle.z() < preRun + length + afterMines) { // player cannot go back
// playerMoveEvent.setCancelled(true);
// new ActionBarMessage().appendStatic(Component.text("You cannot go back on the Field!", NamedTextColor.RED)).send(p);
return;
}

View File

@ -2,6 +2,7 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.LastWinsScore;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularTerrainGenerator;
import io.github.bloepiloepi.pvp.config.*;
@ -17,7 +18,7 @@ import java.util.concurrent.CompletableFuture;
public class Stickfight extends StatelessGame {
public Stickfight() {
super(Dimension.OVERWORLD.DIMENSION, "Stickfight");
super(Dimension.OVERWORLD.DIMENSION, "Stickfight", new LastWinsScore());
eventNode().addChild(
PvPConfig.emptyBuilder()
@ -35,7 +36,7 @@ public class Stickfight extends StatelessGame {
}
@Override
protected void onLoad(CompletableFuture<Void> callback) {
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for (int z = -10; z <= 10; z++) {
batch.setBlock(0, 50, z, Block.SANDSTONE);

View File

@ -3,13 +3,14 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.generator.MazeGenerator;
import eu.mhsl.minenet.minigames.score.NoScore;
import net.minestom.server.entity.Player;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
public class Towerdefense extends StatelessGame {
public Towerdefense() {
super(Dimension.NETHER.DIMENSION, "Towerdefense");
super(Dimension.NETHER.DIMENSION, "Towerdefense", new NoScore());
setGenerator(new MazeGenerator());
}

View File

@ -1,6 +1,7 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.instance.Dimension;
import net.minestom.server.coordinate.Vec;
@ -18,11 +19,11 @@ class TrafficLightRace extends StatelessGame {
private int phaseCounter = 1;
public TrafficLightRace() {
super(Dimension.THE_END.DIMENSION, "Ampelrennen");
super(Dimension.THE_END.DIMENSION, "Ampelrennen", new FirstWinsScore());
}
@Override
protected void onLoad(CompletableFuture<Void> callback) {
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for (int x = -10; x <= 10; x++) {
for (int z = 5; z <= 100; z++) {

View File

@ -13,13 +13,11 @@ import eu.mhsl.minenet.minigames.instance.hub.Hub;
import eu.mhsl.minenet.minigames.instance.room.entity.GameSelector;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerDisconnectEvent;
import net.minestom.server.instance.AnvilLoader;
import team.unnamed.hephaestus.ModelDataCursor;
import team.unnamed.hephaestus.reader.ModelReader;
import team.unnamed.hephaestus.reader.blockbench.BBModelReader;
import java.util.*;
import java.util.logging.Logger;
@ -55,6 +53,7 @@ public class Room extends MineNetInstance implements Spawnable {
p.clearEffects();
p.clearTitle();
p.getInventory().clear();
p.setGameMode(GameMode.ADVENTURE);
rooms.put(p, room);
MoveInstance.move(p, room);
}

View File

@ -0,0 +1,45 @@
package eu.mhsl.minenet.minigames.score;
import eu.mhsl.minenet.minigames.message.type.TitleMessage;
import net.minestom.server.entity.Player;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
public class FirstWinsScore extends Score {
private List<Player> scores = new ArrayList<>();
private int ignoreLastPlayers = 0;
public FirstWinsScore() {}
public FirstWinsScore(int ignoreLastPlayers) {
this.ignoreLastPlayers = ignoreLastPlayers;
}
public void setIgnoreLastPlayers(int ignoreLastPlayers) {
this.ignoreLastPlayers = ignoreLastPlayers;
}
@Override
protected void checkGameEnd() {
if(this.isDone()) return;
if(instance.getPlayers().isEmpty()) return;
if(scores.size() >= instance.getPlayers().size() - ignoreLastPlayers) setDone();
}
@Override
public void addResult(Player p) {
scores.add(p);
new TitleMessage(Duration.ofMillis(1000), Duration.ofSeconds(1)).appendTranslated("score#finish").send(p);
this.checkGameEnd();
}
@Override
protected List<String> getResults() {
return scores.stream().map(Player::getUsername).toList();
}
}

View File

@ -0,0 +1,44 @@
package eu.mhsl.minenet.minigames.score;
import eu.mhsl.minenet.minigames.message.type.TitleMessage;
import net.minestom.server.entity.Player;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
public class LastWinsScore extends Score {
private List<Player> scores = new ArrayList<>();
private int ignoreLastPlayers = 0;
public LastWinsScore() {}
public LastWinsScore(int ignoreLastPlayers) {
this.ignoreLastPlayers = ignoreLastPlayers;
}
public void setIgnoreLastPlayers(int ignoreLastPlayers) {
this.ignoreLastPlayers = ignoreLastPlayers;
}
@Override
protected void checkGameEnd() {
if(this.isDone()) return;
if(instance.getPlayers().isEmpty()) return;
if(scores.size() >= instance.getPlayers().size() - ignoreLastPlayers) setDone();
}
@Override
public void addResult(Player p) {
scores.add(0, p);
new TitleMessage(Duration.ofMillis(1000), Duration.ofSeconds(1)).appendTranslated("score#death").send(p);
this.checkGameEnd();
}
@Override
protected List<String> getResults() {
return scores.stream().map(Player::getUsername).toList();
}
}

View File

@ -0,0 +1,21 @@
package eu.mhsl.minenet.minigames.score;
import net.minestom.server.entity.Player;
import java.util.List;
public class NoScore extends Score {
@Override
protected void checkGameEnd() {
}
@Override
public void addResult(Player p) {
}
@Override
protected List<String> getResults() {
return null;
}
}

View File

@ -1,87 +1,53 @@
package eu.mhsl.minenet.minigames.score;
import eu.mhsl.minenet.minigames.instance.game.Game;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.message.type.TitleMessage;
import eu.mhsl.minenet.minigames.instance.game.Game;
import net.minestom.server.entity.Player;
import net.minestom.server.event.Event;
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
import net.minestom.server.event.player.PlayerDisconnectEvent;
import java.time.Duration;
import java.util.*;
import java.util.List;
public class Score {
public abstract class Score {
private boolean isDone = false;
protected Game instance;
private boolean closed = false;
private final HashMap<Player, Integer> results = new HashMap<>();
protected final Game instance;
private Runnable callback;
public void attachListeners() {
this.instance.eventNode()
.addListener(AddEntityToInstanceEvent.class, addEntityToInstanceEvent -> checkGameEnd())
.addListener(RemoveEntityFromInstanceEvent.class, addEntityToInstanceEvent -> checkGameEnd())
.addListener(PlayerDisconnectEvent.class, addEntityToInstanceEvent -> checkGameEnd());
}
public Score(Game instance) {
abstract protected void checkGameEnd();
public abstract void addResult(Player p);
abstract protected List<String> getResults();
public boolean isDone() {
return isDone;
}
public void setDone() {
isDone = true;
new ChatMessage(Icon.STAR)
.appendTranslated("score#result")
.indent(1)
.pipe()
.list(getResults())
.indent(-1).newLine()
.appendTranslated("score#thanks")
.send(instance.getPlayers());
instance.stop();
}
protected void onGameEnd() {
this.instance.stop();
}
public void setInstance(Game instance) {
this.instance = instance;
this.callback = instance::stop;
instance.eventNode()
.addListener(AddEntityToInstanceEvent.class, this::checkGameEnd)
.addListener(RemoveEntityFromInstanceEvent.class, this::checkGameEnd)
.addListener(PlayerDisconnectEvent.class, this::checkGameEnd);
}
public void onClose(Runnable callback) {
this.callback = callback;
}
private void checkGameEnd(Event e) {
if(closed) return;
if(instance.getPlayers().size() < 1) return;
if(countResults() >= instance.getPlayers().size()) {
callback.run();
new ChatMessage(Icon.STAR)
.appendTranslated("score#result").indent(1)
.list(getMapFormatted())
.indent(-1).newLine()
.appendTranslated("score#thanks")
.send(instance.getPlayers());
closed = true;
}
}
public void addResult(Player p) {
if(closed) return;
if(results.containsKey(p)) return;
results.put(p, countResults()+1);
new TitleMessage(Duration.ofMillis(500), Duration.ofSeconds(1)).appendTranslated("score#finish").send(p);
checkGameEnd(null);
}
public boolean hasResult(Player p) {
return results.containsKey(p);
}
public HashMap<Player, Integer> getMap() {
return results;
}
public List<String> getMapFormatted() {
List<String> out = new ArrayList<>();
for (Map.Entry<Player, Integer> entry : getMap().entrySet()) {
out.add(entry.getValue() + ": " + entry.getKey().getUsername());
}
return out;
}
public int countResults() {
return results.size();
}
}

View File

@ -37,7 +37,8 @@ join_notFound;Lobby not found: ;Lobby konnte nicht gefunden werden:
ns:score#;;
result;Results;Ergebnisse
thanks;Thank you for Playing;Danke für‘s spielen
finish;Finish;Fertig
finish;Yout did it;Du hast es geschafft
death;You are out;Du hast verloren
;;
ns:restriction#;;
fail;Some requirements are not met;Bedinungen sind nicht erfüllt
@ -83,3 +84,8 @@ description;Only go forward if the Trafficlights show green;Gehe nur bei Grün v
ns:game_Towerdefense#;;
name;Towerdefense;Towerdefense
description;Protect the path ????;??????
;;
ns:game_Spleef#;;
name;Spleef;Spleef;
description;Spleef other players and be the last survivor;Zerstöre Blöcke unter anderen Spielern und sei der letzte im Feld
shovelName;Snow thrower;Schneeflug
Can't render this file because it has a wrong number of fields in line 89.