Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ef1d760ed | ||
|
|
70be6418e0 | ||
|
|
9d779a4879 | ||
|
|
f23495ecdd | ||
|
|
89b81a3288 | ||
|
|
8dc165952a | ||
|
|
4bd03c2603 | ||
|
|
75cd304bda | ||
|
|
53b13b6560 | ||
|
|
7e0c126a0d | ||
|
|
096b035503 | ||
|
|
103bd23bf4 | ||
|
|
b175433701 |
No files matched your search
@@ -1,5 +1,6 @@
|
||||
package eu.mhsl.minenet.minigames.handler.global;
|
||||
|
||||
import eu.mhsl.minenet.minigames.Main;
|
||||
import eu.mhsl.minenet.minigames.message.Icon;
|
||||
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@@ -9,6 +10,9 @@ import net.minestom.server.event.player.PlayerChatEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ChatFormatHandler implements EventListener<PlayerChatEvent> {
|
||||
// Verteilt der Proxy den Chat (chat-bridge bei CraftAttack), darf er hier nicht noch einmal erscheinen
|
||||
private final boolean chatViaProxy = Main.globalConfig.node("velocity", "chat-via-proxy").getBoolean(false);
|
||||
|
||||
@Override
|
||||
public @NotNull Class<PlayerChatEvent> eventType() {
|
||||
return PlayerChatEvent.class;
|
||||
@@ -16,6 +20,10 @@ public class ChatFormatHandler implements EventListener<PlayerChatEvent> {
|
||||
|
||||
@Override
|
||||
public @NotNull Result run(@NotNull PlayerChatEvent event) {
|
||||
if(this.chatViaProxy) {
|
||||
event.setCancelled(true);
|
||||
return Result.SUCCESS;
|
||||
}
|
||||
NamedTextColor color = event.getPlayer().getPermissionLevel() > 0 ? NamedTextColor.AQUA : NamedTextColor.GRAY;
|
||||
event.setFormattedMessage(
|
||||
new ChatMessage(Icon.CHAT)
|
||||
|
||||
@@ -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.boatRace.BoatRaceFactory;
|
||||
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.deathcube.DeathcubeFactory;
|
||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory;
|
||||
@@ -54,7 +55,8 @@ public enum GameList {
|
||||
PILLARS(new PillarsFactory(), GameType.PROTOTYPE),
|
||||
BLOCKBATTLE(new BlockBattleFactory(), GameType.PVP),
|
||||
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 GameType type;
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class BlockBattle extends StatelessGame {
|
||||
);
|
||||
|
||||
this.eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
|
||||
if(this.isBeforeBeginning) finalAttackEvent.setCancelled(true);
|
||||
if(!this.isRunning) finalAttackEvent.setCancelled(true);
|
||||
finalAttackEvent.setBaseDamage(0);
|
||||
((Player) finalAttackEvent.getTarget()).setHealth(20);
|
||||
});
|
||||
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
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.coordinate.Point;
|
||||
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.stream.IntStream;
|
||||
|
||||
|
||||
public class BuildBattle extends StatelessGame {
|
||||
private static final int height = 100;
|
||||
private static final int plotHalf = BuildBattleChunkgenerator.inner / 2;
|
||||
private static final int rowCount = 5;
|
||||
private static final int ratingSeconds = 15;
|
||||
private static final List<Material> ratingMaterials = List.of(
|
||||
Material.RED_CONCRETE, Material.ORANGE_CONCRETE, Material.YELLOW_CONCRETE,
|
||||
Material.LIME_CONCRETE, Material.GREEN_CONCRETE
|
||||
);
|
||||
private static final List<ItemStack> ratingItems = IntStream.range(0, ratingMaterials.size())
|
||||
.mapToObj(i -> ItemStack.builder(ratingMaterials.get(i))
|
||||
.customName(Component.text((i + 1) + " Punkte"))
|
||||
.build())
|
||||
.toList();
|
||||
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 int spawnPosx = 0;
|
||||
private int spawnPosz = 0;
|
||||
private final Map<Player, Pos> spawnPositions = new WeakHashMap<>();
|
||||
private final int seconds;
|
||||
private final Map<Player, Integer> currentVotes = new HashMap<>();
|
||||
private Player currentOwner = null;
|
||||
|
||||
public BuildBattle(int seconds) {
|
||||
super(Dimension.THE_END.key, "BuildBattle", new PointsWinScore());
|
||||
this.seconds = seconds;
|
||||
this.setGenerator(new BuildBattleChunkgenerator(height));
|
||||
this.eventNode().addListener(PlayerUseItemEvent.class, this::onRatingItemUse);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
String theme = themes.get(this.rnd.nextInt(themes.size()));
|
||||
|
||||
this.showTitle(Title.title(
|
||||
Component.text("Thema", NamedTextColor.GOLD),
|
||||
Component.text(theme, NamedTextColor.YELLOW)
|
||||
));
|
||||
this.sendMessage(Component.text("Euer Thema: ", NamedTextColor.GRAY)
|
||||
.append(Component.text(theme, NamedTextColor.YELLOW)));
|
||||
this.getPlayers().forEach(player -> player.setGameMode(GameMode.CREATIVE));
|
||||
|
||||
this.scheduler().scheduleTask(this::endBuildPhase, TaskSchedule.seconds(this.seconds), TaskSchedule.stop());
|
||||
}
|
||||
|
||||
private void endBuildPhase() {
|
||||
this.sendMessage(Component.text("Die Bauzeit ist beendet!"));
|
||||
this.getPlayers().forEach(p -> {
|
||||
p.setGameMode(GameMode.ADVENTURE);
|
||||
p.setAllowFlying(true);
|
||||
p.setFlying(true);
|
||||
});
|
||||
this.scheduler().scheduleTask(this::rating, TaskSchedule.seconds(3), TaskSchedule.stop());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onPlayerJoin(Player player) {
|
||||
Pos plotCenter = new Pos(
|
||||
this.spawnPosx * BuildBattleChunkgenerator.period + plotHalf,
|
||||
height,
|
||||
this.spawnPosz * BuildBattleChunkgenerator.period + plotHalf
|
||||
);
|
||||
this.spawnPositions.put(player, plotCenter);
|
||||
|
||||
if(this.spawnPosx >= rowCount - 1) {
|
||||
this.spawnPosx = 0;
|
||||
this.spawnPosz++;
|
||||
} else this.spawnPosx ++;
|
||||
|
||||
player.setGameMode(GameMode.ADVENTURE);
|
||||
this.scheduler().scheduleNextTick(() -> player.teleport(plotCenter.add(0, 1.5, 0)));
|
||||
return super.onPlayerJoin(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent event) {
|
||||
event.setCancelled(!this.isInArea(event.getBlockPosition(), event.getPlayer()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent event) {
|
||||
event.setCancelled(!this.isInArea(event.getBlockPosition(), event.getPlayer()));
|
||||
}
|
||||
|
||||
private void rating() {
|
||||
Queue<Player> owners = new ArrayDeque<>(this.getPlayers());
|
||||
|
||||
this.scheduler().submitTask(() -> {
|
||||
if (this.currentOwner != null) this.finishRound();
|
||||
|
||||
Player next = owners.poll();
|
||||
while (next != null && !(next.isOnline() && this.spawnPositions.containsKey(next))) next = owners.poll();
|
||||
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.sendMessage(Component.text("Bewerte das Grundstück von " + owner.getUsername() + "!"));
|
||||
this.getPlayers().forEach(p -> {
|
||||
p.teleport(plot);
|
||||
p.getInventory().clear();
|
||||
if (p != owner) this.giveRatingItems(p);
|
||||
});
|
||||
}
|
||||
|
||||
private void giveRatingItems(Player player) {
|
||||
for (int i = 0; i < ratingItems.size(); i++) {
|
||||
player.getInventory().setItemStack(i, ratingItems.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
private void onRatingItemUse(PlayerUseItemEvent event) {
|
||||
Player voter = event.getPlayer();
|
||||
if (this.currentOwner == null || voter == this.currentOwner) return;
|
||||
|
||||
int slot = voter.getHeldSlot();
|
||||
if (slot >= ratingItems.size()) return;
|
||||
|
||||
event.setCancelled(true);
|
||||
this.currentVotes.put(voter, slot + 1);
|
||||
voter.sendMessage(Component.text("Du hast " + (slot + 1) + " Punkte vergeben."));
|
||||
}
|
||||
|
||||
private void finishRound() {
|
||||
int voteSum = this.currentVotes.values().stream()
|
||||
.mapToInt(Integer::intValue)
|
||||
.sum();
|
||||
int score = (int) Math.round((double) voteSum / this.getPlayers().size());
|
||||
|
||||
this.getPlayers().forEach(p -> p.getInventory().clear());
|
||||
this.getScore().insertResult(this.currentOwner, score);
|
||||
this.currentOwner = null;
|
||||
}
|
||||
|
||||
private boolean isInArea(Point block, Player player) {
|
||||
Pos center = this.spawnPositions.get(player);
|
||||
double dx = block.x() - center.x();
|
||||
double dy = block.y() - center.y();
|
||||
double dz = block.z() - center.z();
|
||||
return dx >= -plotHalf && dx < plotHalf
|
||||
&& dy >= 1 && dy <= 300
|
||||
&& dz >= -plotHalf && dz < plotHalf;
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
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 {
|
||||
static final int inner = 32;
|
||||
private static final int ring = 3;
|
||||
private static final int wall = 1;
|
||||
private static final int wallHeight = 200;
|
||||
|
||||
static final int period = wall + ring + inner + ring;
|
||||
|
||||
private static final int innerStart = wall + ring;
|
||||
private static final int innerEnd = innerStart + inner;
|
||||
|
||||
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() + innerStart, period);
|
||||
int lz = Math.floorMod(point.blockZ() + innerStart, period);
|
||||
|
||||
if (lx < wall || lz < wall) {
|
||||
unit.modifier().fill(point.withY(height), point.add(1, 0, 1).withY(height + wallHeight + 1), wallBlocks);
|
||||
} else {
|
||||
unit.modifier().setBlock(point.withY(height), floorBlock(lx, lz));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private static Block floorBlock(int lx, int lz) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
+4
@@ -172,5 +172,9 @@ public class ColorJump extends StatelessGame {
|
||||
this.getScore().insertResult(player);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
}
|
||||
if(!this.isBeforeBeginning && !this.isRunning) {
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
player.teleport(this.getSpawn());
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-9
@@ -9,6 +9,7 @@ import io.github.togar2.pvp.events.FinalAttackEvent;
|
||||
import io.github.togar2.pvp.events.PrepareAttackEvent;
|
||||
import io.github.togar2.pvp.feature.CombatFeatures;
|
||||
import io.github.togar2.pvp.feature.knockback.KnockbackSettings;
|
||||
import net.minestom.server.ServerFlag;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.instance.InstanceTickEvent;
|
||||
@@ -51,15 +52,18 @@ class HighGround extends StatelessGame {
|
||||
|
||||
this.eventNode().addListener(
|
||||
EntityKnockbackEvent.class,
|
||||
entityKnockbackEvent -> entityKnockbackEvent.setSettings(
|
||||
KnockbackSettings.builder()
|
||||
.horizontal(1.1)
|
||||
.vertical(KnockbackSettings.DEFAULT.vertical())
|
||||
.verticalLimit(KnockbackSettings.DEFAULT.verticalLimit())
|
||||
.extraHorizontal(KnockbackSettings.DEFAULT.extraHorizontal())
|
||||
.extraVertical(KnockbackSettings.DEFAULT.extraVertical())
|
||||
.build()
|
||||
)
|
||||
entityKnockbackEvent -> {
|
||||
double tps = ServerFlag.SERVER_TICKS_PER_SECOND;
|
||||
entityKnockbackEvent.setSettings(
|
||||
KnockbackSettings.builder()
|
||||
.horizontal(1.1)
|
||||
.vertical(KnockbackSettings.DEFAULT.vertical() / tps)
|
||||
.verticalLimit(KnockbackSettings.DEFAULT.verticalLimit() / tps)
|
||||
.extraHorizontal(KnockbackSettings.DEFAULT.extraHorizontal() / tps)
|
||||
.extraVertical(KnockbackSettings.DEFAULT.extraVertical() / tps)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
this.eventNode().addListener(InstanceTickEvent.class, instanceTickEvent -> {
|
||||
|
||||
+1
-2
@@ -147,10 +147,10 @@ class Tetris extends StatelessGame {
|
||||
|
||||
TetrisGame tetrisGame = this.tetrisGames.get(p);
|
||||
|
||||
p.teleport(tetrisGame.getPlayerSpawnPosition());
|
||||
tetrisGame.sidebar.addViewer(p);
|
||||
|
||||
MinecraftServer.getSchedulerManager().scheduleTask(() -> {
|
||||
p.teleport(tetrisGame.getPlayerSpawnPosition());
|
||||
Entity ghostBlock = new Entity(EntityType.BLOCK_DISPLAY);
|
||||
((BlockDisplayMeta) ghostBlock.getEntityMeta()).setBlockState(Block.AIR);
|
||||
ghostBlock.setNoGravity(true);
|
||||
@@ -159,7 +159,6 @@ class Tetris extends StatelessGame {
|
||||
return TaskSchedule.stop();
|
||||
}, TaskSchedule.nextTick());
|
||||
|
||||
|
||||
return super.onPlayerJoin(p);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ public class TetrisGame {
|
||||
int standardTickDelay = 40;
|
||||
if(this.isFast) standardTickDelay = 20;
|
||||
|
||||
TaskSchedule nextTick = TaskSchedule.tick(Math.round((float) standardTickDelay / this.level));
|
||||
TaskSchedule nextTick = TaskSchedule.tick(Math.max(Math.round((float) standardTickDelay / this.level), 1));
|
||||
if(this.paused) return nextTick;
|
||||
this.tick();
|
||||
return nextTick;
|
||||
|
||||
@@ -9,6 +9,8 @@ bungeecord:
|
||||
|
||||
velocity:
|
||||
enabled: false
|
||||
# Chat nur über den Proxy verteilen, hier verwerfen (chat-bridge)
|
||||
chat-via-proxy: false
|
||||
secret: ''
|
||||
|
||||
api:
|
||||
|
||||
@@ -191,3 +191,8 @@ description;Jump on the right color!;Springe auf die richtige Farbe!
|
||||
ns:game_PlayerRace#;;
|
||||
name;Player Race;Wettrennen
|
||||
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