From 36c6c93edb02233be345cdd9ef34e1bc04e3def7 Mon Sep 17 00:00:00 2001 From: lars Date: Fri, 11 Apr 2025 00:51:43 +0200 Subject: [PATCH] started towerdefense path mechanic --- .../handler/global/PlayerLoginHandler.java | 11 +++- .../types/towerdefense/Towerdefense.java | 65 +++++++++++++++++-- .../types/towerdefense/TowerdefenseRoom.java | 58 +++++++++++++++++ 3 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/towerdefense/TowerdefenseRoom.java diff --git a/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLoginHandler.java b/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLoginHandler.java index b694668..c46ce63 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLoginHandler.java +++ b/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLoginHandler.java @@ -2,6 +2,7 @@ package eu.mhsl.minenet.minigames.handler.global; import eu.mhsl.minenet.minigames.Main; import eu.mhsl.minenet.minigames.api.QueuedPlayerRooms; +import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.TowerdefenseFactory; import eu.mhsl.minenet.minigames.instance.room.Room; import eu.mhsl.minenet.minigames.instance.transfer.Transfer; import eu.mhsl.minenet.minigames.skin.SkinCache; @@ -48,7 +49,15 @@ public class PlayerLoginHandler implements EventListener mazePath = new ArrayList<>(); + private List instances = new ArrayList<>(); + public Towerdefense() { - super(Dimension.NETHER.key, "Towerdefense", new NoScore()); + super(Dimension.NETHER.key, "Towerdefense", new LastWinsScore()); setGenerator(new MazeGenerator()); + this.generateMaze(); + } + + private void generateMaze() { + Pos position = new Pos(0, 0, 0); + this.addMazePosition(position, Block.GREEN_WOOL); + + List previousDirections = new ArrayList<>(); + int direction = 1; // 0 -> right; 1 -> straight; 2 -> left + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 3; j++) { + position = position.add(direction-1,0,direction%2); + this.addMazePosition(position, Block.WHITE_WOOL); + } + + int origin = 0; + int bound = 3; + long rightLeftDifference = previousDirections.stream().filter(integer -> integer == 0).count() - previousDirections.stream().filter(integer -> integer == 2).count(); + if(rightLeftDifference >= 2 || direction == 2) origin = 1; + if(rightLeftDifference <= -2 || direction == 0) bound = 2; + direction = random.nextInt(origin, bound); + previousDirections.add(direction); + } + this.addMazePosition(position, Block.WHITE_WOOL); + this.addMazePosition(position.add(0,0,1), Block.WHITE_WOOL); + this.addMazePosition(position.add(0,0,2), Block.RED_WOOL); + } + + private void addMazePosition(Pos position, Block pathBlock) { + this.mazeBatch.setBlock(position, pathBlock); + this.mazePath.add(position.add(0.5,1,0.5)); + } + + public AbsoluteBlockBatch getMazeBatch() { + return this.mazeBatch; + } + + public List getMazePath() { + return this.mazePath; } @Override protected boolean onPlayerJoin(Player p) { - p.getInventory().setItemStack(1, ItemStack.of(Material.ARMOR_STAND)); + TowerdefenseRoom newRoom = new TowerdefenseRoom(p, this); + this.instances.add(newRoom); + p.setInstance(newRoom); + newRoom.startWave(List.of(EntityType.ENDERMAN, EntityType.BLAZE, EntityType.PLAYER, EntityType.HORSE, EntityType.ARMOR_STAND, EntityType.SKELETON)); return false; } - - } diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/towerdefense/TowerdefenseRoom.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/towerdefense/TowerdefenseRoom.java new file mode 100644 index 0000000..9b02e0f --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/towerdefense/TowerdefenseRoom.java @@ -0,0 +1,58 @@ +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.types.towerdefense.generator.MazeGenerator; +import eu.mhsl.minenet.minigames.util.BatchUtil; +import net.minestom.server.MinecraftServer; +import net.minestom.server.entity.*; +import net.minestom.server.entity.attribute.Attribute; +import net.minestom.server.instance.InstanceContainer; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.minestom.server.timer.TaskSchedule; + +import java.util.List; +import java.util.UUID; + +public class TowerdefenseRoom extends InstanceContainer { + private final Player player; + private final Towerdefense game; + + public TowerdefenseRoom(Player player, Towerdefense game) { + super(UUID.randomUUID(), Dimension.OVERWORLD.key); + MinecraftServer.getInstanceManager().registerInstance(this); + this.player = player; + this.game = game; + this.player.setGameMode(GameMode.ADVENTURE); + this.player.setAllowFlying(true); + this.player.getInventory().setItemStack(0, ItemStack.of(Material.ARMOR_STAND)); + + setGenerator(new MazeGenerator()); + BatchUtil.loadAndApplyBatch(this.game.getMazeBatch(), this, () -> {}); + } + + public void startWave(List entities) { + int counter = 0; + for(EntityType entityType : entities) { + MinecraftServer.getSchedulerManager().scheduleTask(() -> { + this.addEntity(new EntityCreature(entityType)); + return TaskSchedule.stop(); + }, TaskSchedule.millis(800L*counter)); + counter++; + } + } + + private void addEntity(EntityCreature entity) { + entity.setInstance(this, this.game.getMazePath().getFirst()); + entity.getAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.15); + entity.getNavigator().setPathTo(this.game.getMazePath().get(1), 0.7, () -> changeEntityGoal(entity, 1)); + } + + private void changeEntityGoal(EntityCreature entity, int positionIndex) { + if(positionIndex == this.game.getMazePath().size()-1) { + return; + } + entity.getNavigator().setPathTo(this.game.getMazePath().get(positionIndex+1), 0.7, () -> changeEntityGoal(entity, positionIndex+1)); + } + +}