diff --git a/PALAMOD_CDC.md b/PALAMOD_CDC.md index a593afe..07ea69f 100644 --- a/PALAMOD_CDC.md +++ b/PALAMOD_CDC.md @@ -740,6 +740,10 @@ avant M4 (TODO:crafts-machines). miningZone/farmlandZone persistee VERIFIEES, message si non configure). ECART : positions = config admin (UNVERIFIED), bonus grades payants SKIP (boutique externe). VERIFIE : build SUCCESSFUL, boot Done, 0 erreur. UNVERIFIED en jeu. +- M-homes-1 LIVRE 2026-10-19 ~07:50 : homes personnels /sethome /home /delhome /homes + (persistes pala-players.json, limite maxHomesBase=3 ECART base non publiee, grades + payants SKIP). Lecon : markDirty() existait deja (doublon retire). VERIFIE : build + SUCCESSFUL, boot Done, 0 erreur, maxHomesBase persiste. UNVERIFIED en jeu. - M-palaforge LIVRE 2026-10-19 ~03:55 : bloc + BE partagee (3e mode) + gate mineur 14 + table fonte wiki §3.2 (31 items, ratio floor usure) + fuels bois (+buche/planches/baton, lave exclue : seau non rendu) + craft (1 findium + 4 furnaces + 4 briques, positions diff --git a/mods/pala/src/main/java/fr/surviepote/pala/PalaCommands.java b/mods/pala/src/main/java/fr/surviepote/pala/PalaCommands.java index 5ae4dfc..7813c50 100644 --- a/mods/pala/src/main/java/fr/surviepote/pala/PalaCommands.java +++ b/mods/pala/src/main/java/fr/surviepote/pala/PalaCommands.java @@ -96,6 +96,17 @@ public final class PalaCommands { .executes(command -> minage(command.getSource()))); dispatcher.register(Commands.literal("farmland") .executes(command -> farmland(command.getSource()))); + dispatcher.register(Commands.literal("sethome") + .then(Commands.argument("nom", com.mojang.brigadier.arguments.StringArgumentType.word()) + .executes(command -> setHome(command.getSource(), command)))); + dispatcher.register(Commands.literal("home") + .then(Commands.argument("nom", com.mojang.brigadier.arguments.StringArgumentType.word()) + .executes(command -> goHome(command.getSource(), command)))); + dispatcher.register(Commands.literal("delhome") + .then(Commands.argument("nom", com.mojang.brigadier.arguments.StringArgumentType.word()) + .executes(command -> delHome(command.getSource(), command)))); + dispatcher.register(Commands.literal("homes") + .executes(command -> listHomes(command.getSource()))); dispatcher.register(Commands.literal("tpa") .then(Commands.argument("cible", EntityArgument.player()) .executes(command -> tpa(command.getSource(), @@ -1139,6 +1150,91 @@ public final class PalaCommands { } } + // M-homes-1 (wiki grades) : homes personnels /sethome /home /delhome /homes. + private static int setHome(CommandSourceStack source, + com.mojang.brigadier.context.CommandContext ctx) { + try { + ServerPlayer player = source.getPlayerOrException(); + String name = com.mojang.brigadier.arguments.StringArgumentType + .getString(ctx, "nom").toLowerCase(java.util.Locale.ROOT); + fr.surviepote.pala.core.PalaStorage store = + fr.surviepote.pala.core.PalaStorage.get(); + fr.surviepote.pala.core.PalaStorage.PlayerData data = + store.data(player.getUUID()); + int max = fr.surviepote.pala.core.PalaConfig.get().maxHomesBase; + if (!data.homes.containsKey(name) && data.homes.size() >= max) { + source.sendFailure(Component.literal( + "§cLimite de homes atteinte (" + max + ").")); + return 0; + } + data.homes.put(name, player.level().dimension().identifier() + + ":" + player.blockPosition().getX() + + ":" + player.blockPosition().getY() + + ":" + player.blockPosition().getZ()); + store.markDirty(); + source.sendSuccess(() -> Component.literal("§aHome '" + name + "' defini."), false); + return Command.SINGLE_SUCCESS; + } catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) { + return 0; + } + } + + private static int goHome(CommandSourceStack source, + com.mojang.brigadier.context.CommandContext ctx) { + try { + ServerPlayer player = source.getPlayerOrException(); + String name = com.mojang.brigadier.arguments.StringArgumentType + .getString(ctx, "nom").toLowerCase(java.util.Locale.ROOT); + String zone = fr.surviepote.pala.core.PalaStorage.get() + .data(player.getUUID()).homes.get(name); + if (zone == null) { + source.sendFailure(Component.literal( + "§cHome inconnu (liste : /homes).")); + return 0; + } + return zoneTeleport(source, zone, "Home"); + } catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) { + return 0; + } + } + + private static int delHome(CommandSourceStack source, + com.mojang.brigadier.context.CommandContext ctx) { + try { + ServerPlayer player = source.getPlayerOrException(); + String name = com.mojang.brigadier.arguments.StringArgumentType + .getString(ctx, "nom").toLowerCase(java.util.Locale.ROOT); + fr.surviepote.pala.core.PalaStorage store = + fr.surviepote.pala.core.PalaStorage.get(); + if (store.data(player.getUUID()).homes.remove(name) == null) { + source.sendFailure(Component.literal("§cHome inconnu.")); + return 0; + } + store.markDirty(); + source.sendSuccess(() -> Component.literal("§aHome '" + name + "' supprime."), false); + return Command.SINGLE_SUCCESS; + } catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) { + return 0; + } + } + + private static int listHomes(CommandSourceStack source) { + try { + ServerPlayer player = source.getPlayerOrException(); + java.util.Map homes = fr.surviepote.pala.core.PalaStorage.get() + .data(player.getUUID()).homes; + if (homes.isEmpty()) { + source.sendSuccess(() -> Component.literal("§7Aucun home (/sethome )."), false); + } else { + source.sendSuccess(() -> Component.literal( + "§6[Homes] §7" + String.join(", ", homes.keySet())), false); + } + return Command.SINGLE_SUCCESS; + } catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) { + return 0; + } + } + private static int fDisband(CommandSourceStack source) { try { ServerPlayer player = source.getPlayerOrException(); diff --git a/mods/pala/src/main/java/fr/surviepote/pala/core/PalaConfig.java b/mods/pala/src/main/java/fr/surviepote/pala/core/PalaConfig.java index b6eb895..a53ecff 100644 --- a/mods/pala/src/main/java/fr/surviepote/pala/core/PalaConfig.java +++ b/mods/pala/src/main/java/fr/surviepote/pala/core/PalaConfig.java @@ -96,6 +96,10 @@ public final class PalaConfig { public String miningZone = ""; public String farmlandZone = ""; + // M-homes-1 (wiki grades : homes multiples) : homes personnels max (base, ECART : + // base non publiee, configurable ; grades payants boutique externe SKIP). + public int maxHomesBase = 3; + // M-rtp (wiki commandes) : cooldown minutes entre deux /rtp (wiki : 15). public int rtpCooldownMinutes = 15; // Rayon max du /rtp autour du spawn (blocs). UNVERIFIED (wiki : "aleatoire", sans borne). @@ -252,7 +256,7 @@ public final class PalaConfig { "serverName", "wikiUrl", "discordUrl", "shopUrl", "afkKickMinutes", "rtpCooldownMinutes", "rtpRadius", "factionMaxClaims", "marketExpiryDays", - "miningZone", "farmlandZone"); + "miningZone", "farmlandZone", "maxHomesBase"); boolean complete = true; try (Reader keysReader = Files.newBufferedReader(path)) { com.google.gson.JsonObject obj = diff --git a/mods/pala/src/main/java/fr/surviepote/pala/core/PalaStorage.java b/mods/pala/src/main/java/fr/surviepote/pala/core/PalaStorage.java index b406eb4..55bfc5c 100644 --- a/mods/pala/src/main/java/fr/surviepote/pala/core/PalaStorage.java +++ b/mods/pala/src/main/java/fr/surviepote/pala/core/PalaStorage.java @@ -37,8 +37,11 @@ public final class PalaStorage { public Map jobs = new HashMap<>(); public String rank = "default"; public double money = 0.0; + // M-homes-1 : homes personnels (nom -> "dimension:x:y:z"). + public Map homes = new HashMap<>(); } + private final Map players = new HashMap<>(); private boolean dirty = false; diff --git a/server/mods/pala-0.2.1.jar b/server/mods/pala-0.2.1.jar index 4f4e79a..75aa6cd 100644 Binary files a/server/mods/pala-0.2.1.jar and b/server/mods/pala-0.2.1.jar differ