added pillars and block battle #10

Merged
jannis merged 7 commits from develop-pillars into develop 2026-02-02 19:09:44 +00:00
6 changed files with 281 additions and 3 deletions
Showing only changes of commit d0031b4ea5 - Show all commits

View File

@@ -5,6 +5,7 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain.AcidRain
import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle.BlockBattleFactory;
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;
@@ -48,7 +49,8 @@ public enum GameList {
BLOCKBREAKRACE(new BlockBreakRaceFactory(), GameType.OTHER),
SPACESNAKE(new SpaceSnakeFactory(), GameType.PVP),
BOATRACE(new BoatRaceFactory(), GameType.OTHER),
PILLARS(new PillarsFactory(), GameType.PROTOTYPE);
PILLARS(new PillarsFactory(), GameType.PROTOTYPE),
BLOCKBATTLE(new BlockBattleFactory(), GameType.PROTOTYPE);
private final GameFactory factory;
private final GameType type;

View File

@@ -0,0 +1,211 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.NoScore;
import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.feature.CombatFeatures;
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.PlayerMoveEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
public class BlockBattle extends StatelessGame {
private final Team teamBlue = new Team(new Pos(0,101,20).add(0.5), Team.Color.BLUE);
private final Team teamRed = new Team(new Pos(0, 101, -20).add(0.5), Team.Color.RED);
private final Map<Player, Team> teams = new WeakHashMap<>();
public BlockBattle() {
super(Dimension.THE_END.key, "Block Battle", new NoScore());
this.eventNode().addChild(
CombatFeatures.empty()
.add(CombatFeatures.VANILLA_ATTACK)
.add(CombatFeatures.VANILLA_DAMAGE)
.add(CombatFeatures.VANILLA_KNOCKBACK)
.build().createNode()
);
this.eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
if(this.isBeforeBeginning) finalAttackEvent.setCancelled(true);
finalAttackEvent.setBaseDamage(0);
((Player) finalAttackEvent.getTarget()).setHealth(20);
});
}
@Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
this.generateWorld();
}
jannis marked this conversation as resolved
Review

generateWorld wird nur hier aufgerufen, der code von generateWorld kann also direkt hier in onLoad, ohne extra Methode.

generateWorld wird nur hier aufgerufen, der code von generateWorld kann also direkt hier in onLoad, ohne extra Methode.
@Override
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) {
Pos posGoldBlock = new Pos(playerBlockPlaceEvent.getBlockPosition()).sub(0, 1, 0);
Block goldBlock = playerBlockPlaceEvent.getInstance().getBlock(posGoldBlock);
if(goldBlock == Block.GOLD_BLOCK)
playerBlockPlaceEvent.setCancelled(false);
else
playerBlockPlaceEvent.setCancelled(true);
playerBlockPlaceEvent.getInstance().scheduler().scheduleNextTick(() -> {
Pos middle = new Pos(0, 101, 0);
boolean validBlue = true;
boolean validRed = true;
for(int x = middle.blockX()-1; x < middle.blockX()+2; x++) {
for(int z = middle.blockZ()-1; z < middle.blockZ()+2; z++) {
if(playerBlockPlaceEvent.getInstance().getBlock(x, 101, z) != Block.BLUE_WOOL) {
validBlue = false;
break;
}
}
if(!validBlue)
break;
}
for(int x = middle.blockX()-1; x < middle.blockX()+2; x++) {
for(int z = middle.blockZ()-1; z < middle.blockZ()+2; z++) {
if(playerBlockPlaceEvent.getInstance().getBlock(x, 101, z) != Block.RED_WOOL) {
validRed = false;
break;
}
}
if(!validRed)
break;
}
if(validBlue) {
super.stop();
System.out.println("blau");
}
if(validRed) {
super.stop();
System.out.println("rot");
}
});
}
@Override
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent playerBlockBreakEvent) {
final Block[] blockCantBreakList = new Block[] {
Block.YELLOW_CONCRETE_POWDER,
Block.GOLD_BLOCK,
Block.BLUE_CONCRETE_POWDER,
Block.BLUE_CONCRETE,
Block.BLUE_STAINED_GLASS,
Block.RED_CONCRETE_POWDER,
Block.RED_CONCRETE,
Block.RED_STAINED_GLASS
};
for(int i = 0; i < blockCantBreakList.length; i++) {
if(playerBlockBreakEvent.getBlock().equals(blockCantBreakList[i]))
playerBlockBreakEvent.setCancelled(true);
}
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(playerMoveEvent.getNewPosition().y() < 75) {
var player = playerMoveEvent.getPlayer();
if(this.isBeforeBeginning) {
player.teleport(this.getSpawn());
} else {
player.teleport(this.teams.get(player).getSpawnPosition());
}
player.getInventory().clear();
if(this.teams.get(player).getColor() == Team.Color.RED) {
ItemStack item = ItemStack.of(Material.RED_WOOL);
player.getInventory().addItemStack(item);
}
if(this.teams.get(player).getColor() == Team.Color.BLUE) {
ItemStack item = ItemStack.of(Material.BLUE_WOOL);
player.getInventory().addItemStack(item);
}
}
}
@Override
protected void onStart() {
this.setTeams();
this.getPlayers().forEach(player -> {
player.setGameMode(GameMode.SURVIVAL);
player.teleport(this.teams.get(player).getSpawnPosition());
if(this.teams.get(player).getColor() == Team.Color.RED) {
ItemStack item = ItemStack.of(Material.RED_WOOL);
jannis marked this conversation as resolved
Review

Kann direkt in onLoad rein.

Kann direkt in onLoad rein.
player.getInventory().addItemStack(item);
}
if(this.teams.get(player).getColor() == Team.Color.BLUE) {
ItemStack item = ItemStack.of(Material.BLUE_WOOL);
player.getInventory().addItemStack(item);
}
});
}
private void generatePlatform(Pos center, Block inner, Block outer) {
for(int x = center.blockX()-2; x < center.blockX()+3; x++) {
for(int z = center.blockZ()-2; z < center.blockZ()+3; z++) {
this.setBlock(x, center.blockY(), z, outer);
}
}
for(int x = center.blockX()-1; x < center.blockX()+2; x++) {
for(int z = center.blockZ()-1; z < center.blockZ()+2; z++) {
this.setBlock(x, center.blockY(), z, inner);
}
}
}
jannis marked this conversation as resolved
Review

Anstatt immer this.setBlock aufzurufen kann man auch AbsoluteBlockBatch benutzen (siehe Tetris Playfield).
Ist aber nicht unbedingt notwendig.

Anstatt immer this.setBlock aufzurufen kann man auch AbsoluteBlockBatch benutzen (siehe Tetris Playfield). Ist aber nicht unbedingt notwendig.
private void generateWorld() {
this.generatePlatform(new Pos(0, 100, 0), Block.GOLD_BLOCK, Block.YELLOW_CONCRETE_POWDER);
this.generatePlatform(new Pos(0, 101, 0), Block.AIR, Block.YELLOW_CONCRETE_POWDER);
this.generatePlatform(new Pos(0, 100, 20), Block.BLUE_CONCRETE, Block.BLUE_CONCRETE_POWDER);
this.generatePlatform(new Pos(0, 100, -20), Block.RED_CONCRETE, Block.RED_CONCRETE_POWDER);
this.generatePlatform(new Pos(-5, 101, -14), Block.RED_STAINED_GLASS, Block.AIR);
this.generatePlatform(new Pos(5, 101, 14), Block.BLUE_STAINED_GLASS, Block.AIR);
this.setBlock(new Pos(2, 102, -9), Block.RED_STAINED_GLASS);
this.setBlock(new Pos(-1, 103, -9), Block.RED_STAINED_GLASS);
this.setBlock(new Pos(-2, 104, -6), Block.RED_STAINED_GLASS);
this.setBlock(new Pos(-5, 103, -7), Block.RED_STAINED_GLASS);
this.setBlock(new Pos(-7, 102, -10), Block.RED_STAINED_GLASS);
this.setBlock(new Pos(3, 102, -12), Block.RED_STAINED_GLASS);
this.setBlock(new Pos(5, 101, -15), Block.RED_STAINED_GLASS);
this.setBlock(new Pos(-5, 101, 15), Block.BLUE_STAINED_GLASS);
this.setBlock(new Pos(-3, 102, 12), Block.BLUE_STAINED_GLASS);
this.setBlock(new Pos(-2, 102, 9), Block.BLUE_STAINED_GLASS);
this.setBlock(new Pos(1, 103, 9), Block.BLUE_STAINED_GLASS);
this.setBlock(new Pos(2, 104, 6), Block.BLUE_STAINED_GLASS);
this.setBlock(new Pos(5, 103, 7), Block.BLUE_STAINED_GLASS);
this.setBlock(new Pos(7, 102, 10), Block.BLUE_STAINED_GLASS);
}
private void setTeams() {
List<Player> players = this.getPlayers().stream().toList();
int halfPlayers = players.size()/2;
players.subList(0, halfPlayers).forEach(player -> this.teams.put(player, this.teamBlue));
players.subList(halfPlayers, players.size()).forEach(player -> this.teams.put(player, this.teamRed));
}
@Override
public Pos getSpawn() {
return new Pos(0, 101, 0).add(0.5);
}
}

View File

@@ -0,0 +1,32 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle;
import eu.mhsl.minenet.minigames.instance.game.Game;
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.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import net.minestom.server.item.Material;
import java.util.Map;
public class BlockBattleFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_BlockBattle#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_BlockBattle#description");
}
@Override
public Material symbol() {
return Material.GREEN_CONCRETE;
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new BlockBattle().setParent(parent);
}
}

View File

@@ -0,0 +1,25 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle;
import net.minestom.server.coordinate.Pos;
public class Team {
public enum Color {
RED,
BLUE
}
private final Pos spawnPosition;
private final Color color;
public Team(Pos spawnPosition, Color color) {
this.spawnPosition = spawnPosition;
this.color = color;
}
public Pos getSpawnPosition() {
return this.spawnPosition;
}
public Color getColor() {
return this.color;
}
}

View File

@@ -15,6 +15,11 @@ public class PillarsFactory implements GameFactory {
return TranslatedComponent.byId("game_Pillars#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_Pillars#description");
}
@Override
public Material symbol() {
return Material.BEDROCK;

View File

@@ -177,3 +177,6 @@ description;;
;;
ns:game_Pillars#;;
name;Pillars;Pillars
;;
ns:game_BlockBattle#;;
name;Block Battle;Block Battle
1 map en_us de_de
177
178 ns:game_Pillars#
179 name Pillars Pillars
180
181 ns:game_BlockBattle#
182 name Block Battle Block Battle