diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..a2287ef --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,54 @@ + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 43c2c0c..78e813e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,6 +9,10 @@ java { subprojects { + if(project.name == "games") { + return@subprojects + } + apply(plugin = "maven-publish") apply(plugin = "java") diff --git a/core/src/main/java/fr/efreicraft/ludos/core/games/annotations/GameMetadata.java b/core/src/main/java/fr/efreicraft/ludos/core/games/annotations/GameMetadata.java index feef3c8..543cecf 100644 --- a/core/src/main/java/fr/efreicraft/ludos/core/games/annotations/GameMetadata.java +++ b/core/src/main/java/fr/efreicraft/ludos/core/games/annotations/GameMetadata.java @@ -18,6 +18,12 @@ */ String name(); + /** + * Nom du dossier de la map. + * @return Nom du dossier de la map. + */ + String mapFolder() default ""; + /** * Couleur du jeu. * @return Couleur du jeu. diff --git a/core/src/main/java/fr/efreicraft/ludos/core/maps/MapManager.java b/core/src/main/java/fr/efreicraft/ludos/core/maps/MapManager.java index 5b4a376..4116522 100644 --- a/core/src/main/java/fr/efreicraft/ludos/core/maps/MapManager.java +++ b/core/src/main/java/fr/efreicraft/ludos/core/maps/MapManager.java @@ -74,6 +74,14 @@ public void runManager() { setupLobbyWorld(); } + private String getMapFolder(Game game) { + if (game.getMetadata().mapFolder().isEmpty()) { + return game.getMetadata().name(); + } else { + return game.getMetadata().mapFolder(); + } + } + /** * Répertorie les cartes disponibles d'un jeu, accompagnées de leur type. * Cette fonction est appelée à chaque changement de jeu. @@ -82,7 +90,7 @@ public void runManager() { public void setupCurrentGameMaps(Game game) { if (!this.currentGameMaps.isEmpty()) clearGameMaps(); - File dataFolder = new File(Core.get().getPlugin().getDataFolder(), "game_maps/" + game.getMetadata().name()); + File dataFolder = new File(Core.get().getPlugin().getDataFolder(), "game_maps/" + getMapFolder(game)); if(dataFolder.exists()) { for (File file : Objects.requireNonNull(dataFolder.listFiles())) { if (file.isFile() && file.getName().endsWith(".schem")) { @@ -210,7 +218,7 @@ private ParseMapArgs loadSchematicMap(String mapName) throws MapLoadingException try { schematic = SchematicUtils.loadSchematic( - Core.get().getGameManager().getCurrentGame().getMetadata().name() + "/" + mapName + getMapFolder(Core.get().getGameManager().getCurrentGame()) + "/" + mapName ); } catch (IOException e) { WorldUtils.deleteWorld(world); @@ -272,12 +280,19 @@ private ParseMapArgs loadSchematicMap(String mapName) throws MapLoadingException private ParseMapArgs loadFolderMap(String mapName) throws MapLoadingException { Core.get().getLogger().log(Level.INFO, "Copying world folder {0}...", mapName); - File sourceFolder = new File(Core.get().getPlugin().getDataFolder(), - "game_maps/" + Core.get().getGameManager().getCurrentGame().getMetadata().name() + "/" + mapName); - if (!sourceFolder.isDirectory()) throw new MapLoadingException(mapName + " n'est pas un dossier ou n'existe pas."); - - Core.get().getLogger().log(Level.INFO, "Path is {0}", Bukkit.getPluginsFolder().getAbsolutePath().substring(0, Bukkit.getPluginsFolder().getAbsolutePath().lastIndexOf(File.separatorChar))); - File destination = new File(Bukkit.getPluginsFolder().getAbsolutePath().substring(0, Bukkit.getPluginsFolder().getAbsolutePath().lastIndexOf(File.separatorChar))); + File sourceFolder = new File( + Core.get().getPlugin().getDataFolder(), + "game_maps/" + getMapFolder(Core.get().getGameManager().getCurrentGame()) + "/" + mapName + ); + if (!sourceFolder.isDirectory()) + throw new MapLoadingException(mapName + " n'est pas un dossier ou n'existe pas."); + + File destination = new File( + Bukkit.getPluginsFolder().getAbsolutePath().substring( + 0, + Bukkit.getPluginsFolder().getAbsolutePath().lastIndexOf(File.separatorChar) + ) + ); try { FileUtils.copyDirectory(sourceFolder, new File(destination, WorldUtils.getNormalizedWorldName(mapName))); @@ -288,14 +303,19 @@ private ParseMapArgs loadFolderMap(String mapName) throws MapLoadingException { org.bukkit.World world = WorldUtils.createWorld(mapName); if (Core.get().getGameManager().getCurrentGame() != null) { Block spongeBlock = world.getSpawnLocation().getBlock(); - if (spongeBlock.getType() != Material.SPONGE) throw new MapLoadingException("World spawn is not The Sponge Block"); + if (spongeBlock.getType() != Material.SPONGE) + throw new MapLoadingException("World spawn is not The Sponge Block"); Sign sign = (Sign) world.getBlockAt(spongeBlock.getLocation().add(0, 1, 0)).getState(); int[] coord1; int[] coord2; try { - coord1 = Arrays.stream(((TextComponent) sign.line(2)).content().split(" ")).mapToInt(Integer::parseInt).toArray(); - coord2 = Arrays.stream(((TextComponent) sign.line(3)).content().split(" ")).mapToInt(Integer::parseInt).toArray(); + coord1 = Arrays.stream(((TextComponent) sign.line(2)).content().split(" ")) + .mapToInt(Integer::parseInt) + .toArray(); + coord2 = Arrays.stream(((TextComponent) sign.line(3)).content().split(" ")) + .mapToInt(Integer::parseInt) + .toArray(); } catch (NumberFormatException e) { throw new MapLoadingException("Bad coords given on the map description Map"); } diff --git a/dev/Run Server.run.xml b/dev/Run Server.run.xml deleted file mode 100644 index 15682ec..0000000 --- a/dev/Run Server.run.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/games/dac/build.gradle.kts b/games/dac/build.gradle.kts new file mode 100644 index 0000000..0c2e701 --- /dev/null +++ b/games/dac/build.gradle.kts @@ -0,0 +1,23 @@ +import net.minecrell.pluginyml.bukkit.BukkitPluginDescription + +plugins { + `java-library` + id("net.minecrell.plugin-yml.bukkit") version "0.5.2" // Generates plugin.yml +} + +dependencies { + implementation(project(":core")) + + compileOnly("io.papermc.paper:paper-api:1.19.2-R0.1-SNAPSHOT") + + compileOnly("fr.efreicraft:ECATUP:latest.integration") +} + +bukkit { + load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD + name = "LudosDAC" + main = "fr.efreicraft.ludos.games.dac.Main" + apiVersion = "1.19" + authors = listOf("Nat.io") + prefix = "DAC" +} \ No newline at end of file diff --git a/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/EventListener.java b/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/EventListener.java new file mode 100644 index 0000000..22ae761 --- /dev/null +++ b/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/EventListener.java @@ -0,0 +1,39 @@ +package fr.efreicraft.ludos.games.dac; + +import fr.efreicraft.ludos.core.Core; +import fr.efreicraft.ludos.core.players.LudosPlayer; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerMoveEvent; + +public record EventListener(GameLogic dac) implements Listener { + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + if (!event.hasChangedBlock()) { + return; + } + LudosPlayer player = Core.get().getPlayerManager().getPlayer(event.getPlayer()); + if (!player.getTeam().isPlayingTeam()) { + return; + } + if (this.dac.isInBassin(event.getTo())) { + dac.onPlayerInBassin(player); + } else if (this.dac.isOnGround(event.getTo().getY())) { + dac.onPlayerTouchingGround(player); + } + } + + + @EventHandler + public void onDamage(EntityDamageEvent event) { + if (event.getEntity() instanceof org.bukkit.entity.Player bukkitPlayer) { + LudosPlayer player = Core.get().getPlayerManager().getPlayer(bukkitPlayer); + if (!player.getTeam().isPlayingTeam()) { + return; + } + event.setDamage(0); + } + } +} diff --git a/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/GameLogic.java b/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/GameLogic.java new file mode 100644 index 0000000..20cdab3 --- /dev/null +++ b/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/GameLogic.java @@ -0,0 +1,154 @@ +package fr.efreicraft.ludos.games.dac; + +import fr.efreicraft.ludos.core.Core; +import fr.efreicraft.ludos.core.players.LudosPlayer; +import fr.efreicraft.ludos.core.utils.MessageUtils; +import fr.efreicraft.ludos.core.utils.TitleUtils; +import org.bukkit.Location; +import org.bukkit.Material; + +import java.util.ArrayList; +import java.util.List; + +public class GameLogic { + + private final List players = new ArrayList<>(); + private Location bassinPosition; + private Location plateformePosition; + private Location spawnPosition; + private Location boundary1Position; + private Location boundary2Position; + private int round = 1; + private int numberOfPlayers; + private double limitOfPlayers; + + public void setBassinLocation(Location bassinLocation) { + this.bassinPosition = bassinLocation; + } + + public void setPlateformeLocation(Location plateformeLocation) { + this.plateformePosition = plateformeLocation.getBlock().getLocation(); + this.plateformePosition.setPitch(0); + this.plateformePosition.setYaw(180); + } + + public void setNumberOfPlayers(int numberOfPlayers) { + this.numberOfPlayers = numberOfPlayers; + } + + public void setLimitOfPlayers(int numberOfPlayers) { + this.limitOfPlayers = Math.ceil((double) numberOfPlayers / 2); + } + + public void setPlateformeBoundaries(Location boundary1Location, Location boundary2Location) { + this.boundary1Position = boundary1Location; + this.boundary2Position = boundary2Location; + } + + public void setSpawnPosition(Location spawnLocation) { + this.spawnPosition = spawnLocation; + } + + public boolean isInBassin(Location position) { + return bassinPosition.getBlockY() > position.getY() & bassinPosition.getBlockY() - 2 < position.getY() & + bassinPosition.getBlockX() + 4 > position.getX() & bassinPosition.getBlockX() - 4 < position.getX() & + bassinPosition.getBlockZ() + 4 > position.getZ() & bassinPosition.getBlockZ() - 4 < position.getZ(); + } + + public boolean isOnGround(double positionY) { + return bassinPosition.getBlockY() == positionY; + } + + public void onPlayerInBassin(LudosPlayer player) { + player.sendMessage(MessageUtils.ChatPrefix.GAME, "Tombé dans l'eau"); + Core.get().getMapManager().getCurrentMap().getWorld().setBlockData(new Location( + Core.get() + .getMapManager() + .getCurrentMap() + .getWorld(), + player.entity() + .getLocation() + .getBlockX(), + bassinPosition.getY() - 1, + player.entity() + .getLocation() + .getBlockZ() + ), Material.BLACK_CONCRETE.createBlockData()); + player.entity().teleport(this.spawnPosition); + nextPlayer(player); + } + + public void movePlateforme(int round) { + if (round != 1) { + int decalagePlateforme = 30 * (round - 1); + for (int y = this.boundary2Position.getBlockY(); y >= this.boundary1Position.getBlockY(); y--) { + for (int z = this.boundary2Position.getBlockZ(); z <= this.boundary1Position.getBlockZ(); z++) { + for (int x = this.boundary2Position.getBlockX(); x <= this.boundary1Position.getBlockX(); x++) { + Core.get() + .getMapManager() + .getCurrentMap() + .getWorld() + .getBlockAt(x, y + decalagePlateforme, z) + .setType(Core.get() + .getMapManager() + .getCurrentMap() + .getWorld() + .getBlockAt(x, y, z) + .getType()); + Core.get().getMapManager().getCurrentMap().getWorld().getBlockAt(x, y, z).setType(Material.AIR); + } + } + } + this.plateformePosition.setY(this.plateformePosition.getY() + decalagePlateforme); + } + } + + public void onPlayerTouchingGround(LudosPlayer player) { + player.sendMessage(MessageUtils.ChatPrefix.GAME, "Vous êtes tombé sur une bloc ! Vous êtes éliminé !"); + player.setTeam(Core.get().getTeamManager().getTeam("SPECTATORS")); + player.entity().setGameMode(org.bukkit.GameMode.SPECTATOR); + players.remove(player); + nextPlayer(player); + } + + public void nextPlayer(LudosPlayer player) { + player.sendMessage(MessageUtils.ChatPrefix.GAME, "Il reste " + players.size() + " joueurs"); + if (players.size() == 1) { + TitleUtils.broadcastTitle("&9" + "Victoire de " + players.get(0).entity().getName(), "", 0, 2, 0.5f); + } else if (players.size() < limitOfPlayers + Math.abs(round % 2 - 1)) { + this.round++; + playRound(this.round); + } else { + for (LudosPlayer currentPlayer : players) { + if (currentPlayer == player && players.lastIndexOf(player) < players.size()) { + players.iterator().next().entity().teleport(this.plateformePosition); + } else { + players.get(0).entity().teleport(this.plateformePosition); + } + } + } + } + + public void setPlayingPlayers() { + this.players.addAll(Core.get().getTeamManager().getTeam("PLAYERS").getPlayers()); + } + + public void playRound(int round) { + TitleUtils.broadcastTitle( + Core.get().getGameManager().getCurrentGame().getMetadata().color() + "Round " + round, + "", + 0, + 2, + 0.5f + ); + movePlateforme(round); + players.get(0).entity().teleport(this.plateformePosition); + } + + public void onGameStart() { + setNumberOfPlayers(Core.get().getTeamManager().getTeam("PLAYERS").getPlayers().size()); + setLimitOfPlayers(numberOfPlayers); + setPlayingPlayers(); + playRound(1); + } +} diff --git a/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/LudosGame.java b/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/LudosGame.java new file mode 100644 index 0000000..12d53fb --- /dev/null +++ b/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/LudosGame.java @@ -0,0 +1,105 @@ +package fr.efreicraft.ludos.games.dac; + +import com.google.common.collect.ImmutableMap; +import fr.efreicraft.ludos.core.Core; +import fr.efreicraft.ludos.core.games.annotations.GameMetadata; +import fr.efreicraft.ludos.core.games.annotations.GameRules; +import fr.efreicraft.ludos.core.games.interfaces.Game; +import fr.efreicraft.ludos.core.players.LudosPlayer; +import fr.efreicraft.ludos.core.teams.TeamRecord; +import fr.efreicraft.ludos.core.utils.ColorUtils; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.*; + +import java.util.EnumMap; +import java.util.Map; + +import static fr.efreicraft.ludos.core.teams.DefaultTeamRecordBuilder.DefaultTeamRecords.ONLY_SPECTATOR; + +@GameMetadata( + name = "Dé à coudre", + description = "Essayer de tomber dans l'eau et passez les trois rounds pour gagner !", + authors = {"Nat.io"}, + color = "&9", + mapFolder = "DAC", + rules = @GameRules( + maxPlayers = 8 + ) +) +public class LudosGame extends Game { + private final GameLogic gameLogic; + + public LudosGame() { + super(); + this.gameLogic = new GameLogic(); + this.setEventListener(new EventListener(this.gameLogic)); + } + + @Override + public void preMapParse(World world) { + // Nothing to do here + } + + @Override + public void beginGame() { + super.beginGame(); + Core.get().getTeamManager().getTeam("PLAYERS").setFriendlyFire(false); + gameLogic.onGameStart(); + } + + @Override + public void postMapParse() { + this.gameLogic.setBassinLocation( + Core.get().getMapManager().getCurrentMap().getGamePoints().get("BASSIN").get(0).getLocation() + ); + this.gameLogic.setPlateformeLocation( + Core.get().getMapManager().getCurrentMap().getGamePoints().get("SPAWN_PLATEFORME").get(0).getLocation() + ); + this.gameLogic.setPlateformeBoundaries( + Core.get().getMapManager().getCurrentMap().getGamePoints().get("BORDER_PLATEFORME").get(0).getLocation(), + Core.get().getMapManager().getCurrentMap().getGamePoints().get("BORDER_PLATEFORME").get(1).getLocation() + ); + this.gameLogic.setSpawnPosition( + Core.get().getMapManager().getCurrentMap().getSpawnPoints().get(Core.get().getTeamManager().getTeam("PLAYERS")).get(5).getLocation() + ); + } + + @Override + public void setupScoreboard(LudosPlayer player) { + // No scoreboard for now + } + + @Override + public EnumMap getGamePointsMaterials() { + EnumMap gamePointsMaterials = new EnumMap<>(Material.class); + gamePointsMaterials.put(Material.PRISMARINE_BRICKS, "BASSIN"); + gamePointsMaterials.put(Material.END_STONE_BRICKS, "BORDER_PLATEFORME"); + gamePointsMaterials.put(Material.CHISELED_STONE_BRICKS, "SPAWN_PLATEFORME"); + return gamePointsMaterials; + } + + @Override + public Map getTeamRecords() { + return ImmutableMap.builder() + .put("PLAYERS", new TeamRecord( + "Joueurs", + 1, + true, + true, + new ColorUtils.TeamColorSet(NamedTextColor.GRAY, DyeColor.WHITE, Color.GRAY), + null, + p -> { + p.entity().setHealth(20); + p.entity().setFoodLevel(20); + p.entity().setSaturation(20); + p.entity().setExp(0); + p.entity().setLevel(0); + p.entity().getInventory().clear(); + p.entity().getInventory().setArmorContents(null); + p.entity().setGameMode(GameMode.ADVENTURE); + } + )) + .putAll(ONLY_SPECTATOR.getTeamRecords()) + .build(); + } +} diff --git a/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/Main.java b/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/Main.java new file mode 100644 index 0000000..88bd358 --- /dev/null +++ b/games/dac/src/main/java/fr/efreicraft/ludos/games/dac/Main.java @@ -0,0 +1,16 @@ +package fr.efreicraft.ludos.games.dac; + +import fr.efreicraft.ludos.core.games.interfaces.Game; +import fr.efreicraft.ludos.core.games.interfaces.GamePlugin; + +public class Main extends GamePlugin { + + public Main() { + super(); + } + + @Override + public Class getGameClass() { + return LudosGame.class; + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 0ec0d11..41378fc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -13,7 +13,8 @@ include ( "games:arena", "games:spleef", "games:rush", - "games:sumo" + "games:sumo", + "games:dac" ) if (System.getenv("NEXUS_REPOSITORY") == null) {