added BuildBattle
This commit is contained in:
1 parent
096b035503
commit
7e0c126a0d
5 files changed
+304
-2
No files matched your search
@@ -9,6 +9,7 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle.Block
|
|||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace.BlockBreakRaceFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace.BlockBreakRaceFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.boatRace.BoatRaceFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.boatRace.BoatRaceFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle.BuildBattleFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.colorJump.ColorJumpFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.colorJump.ColorJumpFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory;
|
||||||
@@ -54,7 +55,8 @@ public enum GameList {
|
|||||||
PILLARS(new PillarsFactory(), GameType.PROTOTYPE),
|
PILLARS(new PillarsFactory(), GameType.PROTOTYPE),
|
||||||
BLOCKBATTLE(new BlockBattleFactory(), GameType.PVP),
|
BLOCKBATTLE(new BlockBattleFactory(), GameType.PVP),
|
||||||
COLORJUMP(new ColorJumpFactory(), GameType.JUMPNRUN),
|
COLORJUMP(new ColorJumpFactory(), GameType.JUMPNRUN),
|
||||||
PLAYERRACE(new PlayerRaceFactory(), GameType.JUMPNRUN);
|
PLAYERRACE(new PlayerRaceFactory(), GameType.JUMPNRUN),
|
||||||
|
BUILDBATTLE(new BuildBattleFactory(), GameType.PROTOTYPE);
|
||||||
|
|
||||||
private final GameFactory factory;
|
private final GameFactory factory;
|
||||||
private final GameType type;
|
private final GameType type;
|
||||||
|
|||||||
+205
@@ -0,0 +1,205 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||||
|
import eu.mhsl.minenet.minigames.score.PointsWinScore;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.title.Title;
|
||||||
|
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.PlayerBlockPlaceEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerUseItemEvent;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
|
||||||
|
public class BuildBattle extends StatelessGame {
|
||||||
|
private static final int height = 100;
|
||||||
|
private int spawnPosx = 0;
|
||||||
|
private int spawnPosz = 0;
|
||||||
|
private final int spacing = 39;
|
||||||
|
private final int rowCount = 5;
|
||||||
|
private Map<Player, Pos> spawnPositions = new WeakHashMap<>();
|
||||||
|
private int seconds;
|
||||||
|
private static final int ratingSeconds = 15;
|
||||||
|
private final Map<Player, Integer> scores = new HashMap<>();
|
||||||
|
private final Map<Player, Integer> currentVotes = new HashMap<>();
|
||||||
|
private Player currentOwner = null;
|
||||||
|
private boolean listenerRegistered = false;
|
||||||
|
private static final List<String> themes = List.of(
|
||||||
|
"Burg", "Raumschiff", "Unterwasserwelt", "Pizzeria", "Spukhaus",
|
||||||
|
"Bauernhof", "Dschungel", "Zukunftsstadt", "Piratenschiff", "Vulkan",
|
||||||
|
"Freizeitpark", "Leuchtturm", "Wikingerdorf", "Weihnachtsmarkt",
|
||||||
|
"Schloss", "Strand", "Berghütte", "Bahnhof", "Zoo", "Schule",
|
||||||
|
"Zeitreise", "Ein Haus, das auf dem Kopf steht", "Eine Stadt auf dem Rücken eines Riesen",
|
||||||
|
"Wohnen in einer Schneekugel", "Alles ist aus Süßigkeiten", "Ein Schiff in der Luft",
|
||||||
|
"Das Museum der Zukunft", "Das letzte Haus vor dem Weltuntergang",
|
||||||
|
"Wenn Schweine fliegen könnten", "Das Gefängnis für Creeper", "Die Wohnung von Herobrine",
|
||||||
|
"Ein Dönerladen im Weltall", "Ein Spa für Enderman", "Der Käse-Palast",
|
||||||
|
"Mein Zimmer nach 3 Wochen ohne Aufräumen", "Die Hüpfburg des Todes"
|
||||||
|
);
|
||||||
|
private String theme = "";
|
||||||
|
|
||||||
|
public BuildBattle(int seconds) {
|
||||||
|
super(Dimension.THE_END.key, "BluidBattle", new PointsWinScore());
|
||||||
|
this.seconds = seconds;
|
||||||
|
this.setGenerator(new BuildBattleChunkgenerator(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
this.theme = themes.get(this.rnd.nextInt(themes.size()));
|
||||||
|
|
||||||
|
Title title = Title.title(
|
||||||
|
Component.text("Thema", NamedTextColor.GOLD),
|
||||||
|
Component.text(this.theme, NamedTextColor.YELLOW)
|
||||||
|
);
|
||||||
|
this.getPlayers().forEach(player -> {
|
||||||
|
player.showTitle(title);
|
||||||
|
player.sendMessage(Component.text("Euer Thema: ", NamedTextColor.GRAY)
|
||||||
|
.append(Component.text(this.theme, NamedTextColor.YELLOW)));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.getPlayers().forEach(player -> player.setGameMode(GameMode.CREATIVE));
|
||||||
|
|
||||||
|
MinecraftServer.getSchedulerManager()
|
||||||
|
.buildTask(() -> {
|
||||||
|
this.getPlayers().forEach(player -> player.sendMessage("Die Bauzeit ist beendet!"));
|
||||||
|
this.getPlayers().forEach(p -> {
|
||||||
|
p.setGameMode(GameMode.ADVENTURE);
|
||||||
|
p.setAllowFlying(true);
|
||||||
|
p.setFlying(true);
|
||||||
|
this.scores.put(p, 0);
|
||||||
|
});
|
||||||
|
MinecraftServer.getSchedulerManager()
|
||||||
|
.buildTask(() -> {
|
||||||
|
this.rating();
|
||||||
|
}).delay(TaskSchedule.seconds(3)).schedule();
|
||||||
|
}).delay(TaskSchedule.seconds(this.seconds)).schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onPlayerJoin(Player player) {
|
||||||
|
Pos spawnPos = new Pos(this.spawnPosx * this.spacing, height, this.spawnPosz * this.spacing);
|
||||||
|
this.spawnPositions.put(player, spawnPos.add(16, 0, 16));
|
||||||
|
|
||||||
|
if(this.spawnPosx >= this.rowCount) {
|
||||||
|
this.spawnPosx = 0;
|
||||||
|
this.spawnPosz++;
|
||||||
|
}
|
||||||
|
this.spawnPosx++;
|
||||||
|
player.setGameMode(GameMode.ADVENTURE);
|
||||||
|
MinecraftServer.getSchedulerManager().scheduleNextTick(() ->
|
||||||
|
player.teleport(spawnPos.add(16, 1.5, 16)));
|
||||||
|
return super.onPlayerJoin(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent event) {
|
||||||
|
var player = event.getPlayer();
|
||||||
|
Pos blockPos = event.getBlockPosition().asPos();
|
||||||
|
event.setCancelled(!this.isInArea(blockPos, player));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent event) {
|
||||||
|
var player = event.getPlayer();
|
||||||
|
Pos blockPos = event.getBlockPosition().asPos();
|
||||||
|
event.setCancelled(!this.isInArea(blockPos, player));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rating() {
|
||||||
|
List<Player> owners = new ArrayList<>(this.getPlayers());
|
||||||
|
this.registerRatingListener();
|
||||||
|
|
||||||
|
AtomicInteger index = new AtomicInteger(0);
|
||||||
|
MinecraftServer.getSchedulerManager().submitTask(() -> {
|
||||||
|
if (this.currentOwner != null) this.finishRound();
|
||||||
|
|
||||||
|
Player next = null;
|
||||||
|
while (index.get() < owners.size()) {
|
||||||
|
Player candidate = owners.get(index.getAndIncrement());
|
||||||
|
if (candidate.isOnline() && this.spawnPositions.containsKey(candidate)) {
|
||||||
|
next = candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next == null) {
|
||||||
|
return TaskSchedule.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.startRound(next);
|
||||||
|
return TaskSchedule.seconds(ratingSeconds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startRound(Player owner) {
|
||||||
|
this.currentOwner = owner;
|
||||||
|
this.currentVotes.clear();
|
||||||
|
|
||||||
|
Pos plot = this.spawnPositions.get(owner).add(0, 1.5, 0);
|
||||||
|
this.getPlayers().forEach(p -> {
|
||||||
|
p.teleport(plot);
|
||||||
|
p.sendMessage(Component.text("Bewerte das Grundstück von " + owner.getUsername() + "!"));
|
||||||
|
if (p != owner) this.giveRatingItems(p);
|
||||||
|
else p.getInventory().clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void giveRatingItems(Player player) {
|
||||||
|
Material[] materials = {
|
||||||
|
Material.RED_CONCRETE, Material.ORANGE_CONCRETE, Material.YELLOW_CONCRETE,
|
||||||
|
Material.LIME_CONCRETE, Material.GREEN_CONCRETE
|
||||||
|
};
|
||||||
|
player.getInventory().clear();
|
||||||
|
for (int i = 0; i < materials.length; i++) {
|
||||||
|
player.getInventory().setItemStack(i, ItemStack.builder(materials[i])
|
||||||
|
.customName(Component.text((i + 1) + " Punkte"))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerRatingListener() {
|
||||||
|
if (this.listenerRegistered) return;
|
||||||
|
this.listenerRegistered = true;
|
||||||
|
|
||||||
|
this.eventNode().addListener(PlayerUseItemEvent.class, event -> {
|
||||||
|
Player voter = event.getPlayer();
|
||||||
|
if (this.currentOwner == null || voter == this.currentOwner) return;
|
||||||
|
|
||||||
|
int slot = voter.getHeldSlot();
|
||||||
|
if (slot > 4) return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
this.currentVotes.put(voter, slot + 1);
|
||||||
|
voter.sendMessage(Component.text("Du hast " + (slot + 1) + " Punkte vergeben."));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finishRound() {
|
||||||
|
int sum = this.currentVotes.values().stream().mapToInt(Integer::intValue).sum();
|
||||||
|
this.getPlayers().forEach(p -> p.getInventory().clear());
|
||||||
|
|
||||||
|
Player owner = this.currentOwner;
|
||||||
|
this.currentOwner = null;
|
||||||
|
this.getScore().insertResult(owner, sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInArea(Pos blockToCheck, Player player) {
|
||||||
|
Pos pos1 = this.spawnPositions.get(player).add(15, 1, 15);
|
||||||
|
Pos pos2 = this.spawnPositions.get(player).add(-16, 300, -16);
|
||||||
|
return blockToCheck.x() >= Math.min(pos1.x(), pos2.x()) && blockToCheck.x() <= Math.max(pos1.x(), pos2.x())
|
||||||
|
&& blockToCheck.y() >= Math.min(pos1.y(), pos2.y()) && blockToCheck.y() <= Math.max(pos1.y(), pos2.y())
|
||||||
|
&& blockToCheck.z() >= Math.min(pos1.z(), pos2.z()) && blockToCheck.z() <= Math.max(pos1.z(), pos2.z());
|
||||||
|
}
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.util.GeneratorUtils;
|
||||||
|
import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
|
||||||
|
public class BuildBattleChunkgenerator extends BaseGenerator {
|
||||||
|
private static final int inner = 32;
|
||||||
|
private static final int ring = 3;
|
||||||
|
private static final int wall = 1;
|
||||||
|
private static final int wallHeight = 200;
|
||||||
|
|
||||||
|
|
||||||
|
private static final int period = wall + ring + inner + ring;
|
||||||
|
|
||||||
|
private static final int offset = wall + ring;
|
||||||
|
|
||||||
|
private static final Block middleBlocks = Block.QUARTZ_BLOCK;
|
||||||
|
private static final Block outerBlocks = Block.STONE_BRICKS;
|
||||||
|
private static final Block wallBlocks = Block.POLISHED_DEEPSLATE;
|
||||||
|
|
||||||
|
public BuildBattleChunkgenerator(int height) {
|
||||||
|
this.addMixIn(unit -> {
|
||||||
|
GeneratorUtils.foreachXZ(unit, point -> {
|
||||||
|
int lx = Math.floorMod(point.blockX() + offset, period);
|
||||||
|
int lz = Math.floorMod(point.blockZ() + offset, period);
|
||||||
|
|
||||||
|
boolean isWall = lx < wall || lz < wall;
|
||||||
|
if (isWall) {
|
||||||
|
for (int y = 0; y <= wallHeight; y++) {
|
||||||
|
unit.modifier().setBlock(point.withY(height + y), wallBlocks);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unit.modifier().setBlock(point.withY(height), floorBlock(lx, lz));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Block floorBlock(int lx, int lz) {
|
||||||
|
int innerStart = wall + ring;
|
||||||
|
int innerEnd = innerStart + inner;
|
||||||
|
|
||||||
|
boolean inInner = lx >= innerStart && lx < innerEnd
|
||||||
|
&& lz >= innerStart && lz < innerEnd;
|
||||||
|
|
||||||
|
return inInner ? middleBlocks : outerBlocks;
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.Game;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.room.Room;
|
||||||
|
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class BuildBattleFactory implements GameFactory {
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent name() {
|
||||||
|
return TranslatedComponent.byId("game_BuildBattle#name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigManager configuration() {
|
||||||
|
return new ConfigManager()
|
||||||
|
.addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("game_BuildBattle#seconds"), 60, 120, 300, 600));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
|
return new BuildBattle(configuration.get("seconds").getAsInt()).setParent(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material symbol() {
|
||||||
|
return Material.SANDSTONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent description() {
|
||||||
|
return TranslatedComponent.byId("game_BuildBattle#description");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -190,4 +190,9 @@ description;Jump on the right color!;Springe auf die richtige Farbe!
|
|||||||
;;
|
;;
|
||||||
ns:game_PlayerRace#;;
|
ns:game_PlayerRace#;;
|
||||||
name;Player Race;Wettrennen
|
name;Player Race;Wettrennen
|
||||||
description;Get to the other side as quickly as possible!;Komme so schnell wie möglich auf die andere Seite!
|
description;Get to the other side as quickly as possible!;Komme so schnell wie möglich auf die andere Seite!
|
||||||
|
;;
|
||||||
|
ns:game_BuildBattle#;;
|
||||||
|
name;Build Battle;Bauwettbewerb
|
||||||
|
description;Build the best creation for the given theme before time runs out and win through the other players’ ratings.;Baue in der Zeit das beste Bauwerk zum Thema und gewinne durch die Bewertung der anderen Spieler.
|
||||||
|
seconds;Build Time;Bauzeit
|
||||||
|
Reference in new issue
Block a user