diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java index 97b5678..0d846b6 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java @@ -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; diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/BlockBattle.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/BlockBattle.java new file mode 100644 index 0000000..2e0efe1 --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/BlockBattle.java @@ -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 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 callback) { + this.generateWorld(); + } + + @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); + 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); + } + } + } + + 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 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); + } +} diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/BlockBattleFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/BlockBattleFactory.java new file mode 100644 index 0000000..d4b895f --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/BlockBattleFactory.java @@ -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> configuration) throws Exception { + return new BlockBattle().setParent(parent); + } +} diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/Team.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/Team.java new file mode 100644 index 0000000..5dc8f81 --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/Team.java @@ -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; + } +} diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/pillars/PillarsFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/pillars/PillarsFactory.java index c2afac6..22e03a2 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/pillars/PillarsFactory.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/pillars/PillarsFactory.java @@ -15,9 +15,14 @@ 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; + return Material.BEDROCK; } @Override diff --git a/src/main/resources/lang/locales.map.csv b/src/main/resources/lang/locales.map.csv index 46c7d6b..3c82743 100644 --- a/src/main/resources/lang/locales.map.csv +++ b/src/main/resources/lang/locales.map.csv @@ -176,4 +176,7 @@ name;Boatrace;Bootrennen description;; ;; ns:game_Pillars#;; -name;Pillars;Pillars \ No newline at end of file +name;Pillars;Pillars +;; +ns:game_BlockBattle#;; +name;Block Battle;Block Battle \ No newline at end of file