From c898e2640667f8a7522d1b5132b537b29b014745 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Tue, 9 Jan 2024 20:56:21 +0100 Subject: [PATCH 01/32] :bug: Allow "none" as message in bring back stage --- .../java/fr/skytasul/quests/stages/StageBringBack.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java b/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java index 0baa055e..b83653c4 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java @@ -65,9 +65,12 @@ public boolean checkItems(Player p, boolean msg){ } public void sendNeedMessage(Player p) { - new Message(MessageUtils.format(getMessage(), getPlaceholdersRegistry(), StageDescriptionPlaceholdersContext.of(true, - PlayersManager.getPlayerAccount(p), DescriptionSource.FORCELINE, null)), Sender.NPC).sendMessage(p, getNPC(), - getNpcName(), 1, 1); + String text = getMessage(); + if ("none".equals(text)) + return; + Message msg = new Message(MessageUtils.format(text, getPlaceholdersRegistry(), StageDescriptionPlaceholdersContext + .of(true, PlayersManager.getPlayerAccount(p), DescriptionSource.FORCELINE, null)), Sender.NPC); + msg.sendMessage(p, getNPC(), getNpcName(), 1, 1); } public void removeItems(Player p){ From 62201159baa69aa0061466aebffe3a5ce57dfe1e Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Wed, 10 Jan 2024 09:18:21 +0100 Subject: [PATCH 02/32] :loud_sound: Added logs for missing translation --- .../skytasul/quests/api/localization/Locale.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/localization/Locale.java b/api/src/main/java/fr/skytasul/quests/api/localization/Locale.java index 6643df08..90810d9d 100644 --- a/api/src/main/java/fr/skytasul/quests/api/localization/Locale.java +++ b/api/src/main/java/fr/skytasul/quests/api/localization/Locale.java @@ -7,6 +7,8 @@ import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -71,13 +73,24 @@ default void quickSend(@NotNull CommandSender sender, @NotNull String key1, @Nul public static void loadStrings(@NotNull Locale @NotNull [] locales, @NotNull YamlConfiguration defaultConfig, @NotNull YamlConfiguration config) { + List missing = new ArrayList<>(); for (Locale l : locales) { String value = config.getString(l.getPath(), null); - if (value == null) value = defaultConfig.getString(l.getPath(), null); + if (value == null) { + value = defaultConfig.getString(l.getPath(), null); + missing.add(l.getPath()); + } if (value == null) QuestsPlugin.getPlugin().getLoggerExpanded().debug("Unavailable string in config for key " + l.getPath()); l.setValue(ChatColorUtils.translateHexColorCodes(ChatColor.translateAlternateColorCodes('&', value == null ? "§cunknown string" : value))); } + + if (!missing.isEmpty()) { + QuestsPlugin.getPlugin().getLoggerExpanded() + .warning("The file is not fully translated! " + missing.size() + " missing translations."); + QuestsPlugin.getPlugin().getLoggerExpanded() + .debug("Missing translations: " + String.join(", ", missing)); + } } public static YamlConfiguration loadLang(@NotNull Plugin plugin, @NotNull Locale @NotNull [] locales, From 47f747f3f56d5e7f50bd8b3acf5ef19d3b047b3e Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Wed, 10 Jan 2024 21:51:48 +0100 Subject: [PATCH 03/32] :bug: Fixed wrong string and weird NPC code --- core/src/main/resources/locales/en_US.yml | 2 +- .../quests/integrations/mobs/CitizensFactory.java | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/core/src/main/resources/locales/en_US.yml b/core/src/main/resources/locales/en_US.yml index 0de2c421..71a1d97b 100644 --- a/core/src/main/resources/locales/en_US.yml +++ b/core/src/main/resources/locales/en_US.yml @@ -127,7 +127,7 @@ msg: leaveAll: '§aYou have forced the end of {success} quest(s). Errors: {errors}' resetPlayer: player: §6All informations of your {quest_amount} quest(s) has/have been deleted by {deleter_name}. - remover: §6{quest_amount} quest information(s) (and {quest_pool} pools) of {player} has/have been deleted. + remover: §6{quest_amount} quest information(s) (and {quest_pool} pools) of {player_name} has/have been deleted. resetPlayerQuest: player: §6All informations about the quest {quest} have been deleted by {deleter_name}. remover: §6{player} informations of quest {quest} has/have been deleted. diff --git a/integrations/src/main/java/fr/skytasul/quests/integrations/mobs/CitizensFactory.java b/integrations/src/main/java/fr/skytasul/quests/integrations/mobs/CitizensFactory.java index 9bc09a8d..d9499873 100644 --- a/integrations/src/main/java/fr/skytasul/quests/integrations/mobs/CitizensFactory.java +++ b/integrations/src/main/java/fr/skytasul/quests/integrations/mobs/CitizensFactory.java @@ -41,7 +41,7 @@ public void itemClick(Player p, Consumer run) { Lang.SELECT_KILL_NPC.send(p); // we cannot use the SelectNPC editor as it uses the BQNPCManager // and if it is registered to another NPC plugin it wouldn't work - new CitizensNpcClickEditor(p, () -> run.accept(null), p, run).start(); + new CitizensNpcClickEditor(p, () -> run.accept(null), run).start(); } @Override @@ -82,17 +82,15 @@ public void onNPCKilled(NPCDeathEvent e) { } private class CitizensNpcClickEditor extends InventoryClear implements Listener { - private final Player p; private final Consumer run; - private CitizensNpcClickEditor(Player p, Runnable cancel, Player p2, Consumer run) { + private CitizensNpcClickEditor(Player p, Runnable cancel, Consumer run) { super(p, cancel); - this.p = p2; this.run = run; } @EventHandler(priority = EventPriority.LOW) - private void onNPCClick(NPCRightClickEvent e) { + public void onNPCClick(NPCRightClickEvent e) { if (e.getClicker() != player) return; e.setCancelled(true); @@ -103,7 +101,7 @@ private void onNPCClick(NPCRightClickEvent e) { @Override public void begin() { super.begin(); - Lang.NPC_EDITOR_ENTER.send(p); + Lang.NPC_EDITOR_ENTER.send(player); } } From 43492895ac69ca455c501275ac1fbf6e30fbdf13 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sat, 20 Jan 2024 22:38:06 +0100 Subject: [PATCH 04/32] :bug: Fixed NPE in particle effect GUI --- .../quests/gui/particles/ParticleEffectGUI.java | 17 +++++++++-------- .../skytasul/quests/utils/ParticleEffect.java | 16 +++++++++------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/fr/skytasul/quests/gui/particles/ParticleEffectGUI.java b/core/src/main/java/fr/skytasul/quests/gui/particles/ParticleEffectGUI.java index c26e209a..291483ac 100644 --- a/core/src/main/java/fr/skytasul/quests/gui/particles/ParticleEffectGUI.java +++ b/core/src/main/java/fr/skytasul/quests/gui/particles/ParticleEffectGUI.java @@ -34,26 +34,27 @@ public class ParticleEffectGUI extends LayoutedGUI.LayoutedRowsGUI { return false; }).collect(Collectors.toList()); - private final Consumer end; + private final @NotNull Consumer end; - private Particle particle; - private ParticleShape shape; - private Color color; + private @NotNull Particle particle; + private @NotNull ParticleShape shape; + private @NotNull Color color; - public ParticleEffectGUI(Consumer end) { + public ParticleEffectGUI(@NotNull Consumer end) { this(end, Particle.FLAME, ParticleShape.POINT, Color.AQUA); } - public ParticleEffectGUI(Consumer end, ParticleEffect effect) { + public ParticleEffectGUI(@NotNull Consumer end, @NotNull ParticleEffect effect) { this(end, effect.getParticle(), effect.getShape(), effect.getColor()); } - public ParticleEffectGUI(Consumer end, Particle particle, ParticleShape shape, Color color) { + public ParticleEffectGUI(@NotNull Consumer end, @NotNull Particle particle, @NotNull ParticleShape shape, + @Nullable Color color) { super(Lang.INVENTORY_PARTICLE_EFFECT.toString(), new HashMap<>(), new DelayCloseBehavior(() -> end.accept(null)), 1); this.end = end; this.particle = particle; this.shape = shape; - this.color = color; + this.color = color == null ? Color.AQUA : color; initButtons(); } diff --git a/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java b/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java index 8021300c..031a2daf 100644 --- a/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java +++ b/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java @@ -9,6 +9,8 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import fr.skytasul.quests.api.utils.MinecraftVersion; import fr.skytasul.quests.utils.compatibility.Post1_13; import fr.skytasul.quests.utils.nms.NMS; @@ -17,14 +19,14 @@ public class ParticleEffect { private static Random random = new Random(); - private final ParticleType type; - private final ParticleShape shape; - private final Color color; + private final @NotNull ParticleType type; + private final @NotNull ParticleShape shape; + private final @Nullable Color color; private final double[] colors; private final Object dustColor; - public ParticleEffect(Particle bukkitType, ParticleShape shape, Color color) { + public ParticleEffect(@NotNull Particle bukkitType, @NotNull ParticleShape shape, @Nullable Color color) { Validate.notNull(bukkitType); this.type = new ParticleType(bukkitType); this.shape = shape; @@ -46,15 +48,15 @@ public ParticleEffect(Particle bukkitType, ParticleShape shape, Color color) { } } - public Particle getParticle() { + public @NotNull Particle getParticle() { return type.particle; } - public ParticleShape getShape() { + public @NotNull ParticleShape getShape() { return shape; } - public Color getColor() { + public @Nullable Color getColor() { return color; } From f84f58e19e9b71b0093d8e03bb0e5c85e85fb3d1 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sat, 20 Jan 2024 22:40:04 +0100 Subject: [PATCH 05/32] :arrow_up: Updated Paper API version --- api/dependency-reduced-pom.xml | 239 --------------------------------- api/pom.xml | 3 +- core/pom.xml | 2 +- pom.xml | 1 + 4 files changed, 4 insertions(+), 241 deletions(-) delete mode 100755 api/dependency-reduced-pom.xml diff --git a/api/dependency-reduced-pom.xml b/api/dependency-reduced-pom.xml deleted file mode 100755 index 76bda9fc..00000000 --- a/api/dependency-reduced-pom.xml +++ /dev/null @@ -1,239 +0,0 @@ - - - - beautyquests-parent - fr.skytasul - 1.0.2-SNAPSHOT - - 4.0.0 - beautyquests-api - - - - maven-shade-plugin - 3.2.1 - - - package - - shade - - - - - - - revxrsal.commands - fr.skytasul.quests.api.commands.revxrsal - - - com.cryptomorin.xseries - fr.skytasul.quests.api.utils - - - - - com.github.cryptomorin:XSeries - - com/cryptomorin/xseries/XMaterial* - com/cryptomorin/xseries/XBlock* - com/cryptomorin/xseries/XPotion* - - - - true - - - - maven-compiler-plugin - 3.8.0 - - true - - - - maven-javadoc-plugin - 3.4.1 - - - attach-javadocs - verify - - jar - - - - - false - none - - - - maven-source-plugin - 3.2.1 - - - attach-sources - verify - - jar-no-fork - - - - - false - - - - maven-surefire-plugin - 3.2.2 - - true - - - - - - - papermc - https://repo.papermc.io/repository/maven-public/ - - - jitpack.io - https://jitpack.io - - - - - org.jetbrains - annotations - 24.0.0 - provided - - - commons-lang - commons-lang - 2.6 - provided - - - io.papermc.paper - paper-api - 1.20.1-R0.1-SNAPSHOT - provided - - - guava - com.google.guava - - - gson - com.google.code.gson - - - bungeecord-chat - net.md-5 - - - snakeyaml - org.yaml - - - joml - org.joml - - - json-simple - com.googlecode.json-simple - - - fastutil - it.unimi.dsi - - - log4j-api - org.apache.logging.log4j - - - slf4j-api - org.slf4j - - - maven-resolver-provider - org.apache.maven - - - adventure-api - net.kyori - - - adventure-text-minimessage - net.kyori - - - adventure-text-serializer-gson - net.kyori - - - adventure-text-serializer-legacy - net.kyori - - - adventure-text-serializer-plain - net.kyori - - - adventure-text-logger-slf4j - net.kyori - - - checker-qual - org.checkerframework - - - asm - org.ow2.asm - - - asm-commons - org.ow2.asm - - - - - org.junit.jupiter - junit-jupiter-api - 5.10.1 - test - - - opentest4j - org.opentest4j - - - junit-platform-commons - org.junit.platform - - - apiguardian-api - org.apiguardian - - - - - org.junit.jupiter - junit-jupiter-params - 5.10.1 - test - - - apiguardian-api - org.apiguardian - - - - - - 5.10.1 - - diff --git a/api/pom.xml b/api/pom.xml index 77bd1031..2c20a8ad 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -22,6 +22,7 @@ maven-shade-plugin 3.2.1 + false revxrsal.commands @@ -134,7 +135,7 @@ io.papermc.paper paper-api - 1.20.1-R0.1-SNAPSHOT + ${minecraft.version} provided diff --git a/core/pom.xml b/core/pom.xml index 66bfb184..c2e0348c 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -117,7 +117,7 @@ io.papermc.paper paper-api - 1.20.1-R0.1-SNAPSHOT + ${minecraft.version} provided diff --git a/pom.xml b/pom.xml index 7131c1b5..4354df4c 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,7 @@ true unknown 1.0.2 + 1.20.4-R0.1-SNAPSHOT From e17fa537a3fc5fdb8ab46ac74aaaaf20b0117c5e Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Mon, 22 Jan 2024 09:43:45 +0100 Subject: [PATCH 06/32] :construction_worker: Changed maven poms to have version at only 1 place --- .gitignore | 1 + api/pom.xml | 2 +- core/pom.xml | 5 ++-- core/src/main/resources/plugin.yml | 4 +-- dist/pom.xml | 42 +++++++++++++++--------------- integrations/pom.xml | 9 +++---- pom.xml | 30 +++++++++++++++++++-- v1_12_R1/pom.xml | 4 +-- v1_15_R1/pom.xml | 4 +-- v1_16_R1/pom.xml | 4 +-- v1_16_R2/pom.xml | 4 +-- v1_16_R3/pom.xml | 4 +-- v1_17_R1/pom.xml | 6 ++--- v1_18_R1/pom.xml | 6 ++--- v1_18_R2/pom.xml | 6 ++--- v1_19_R1/pom.xml | 6 ++--- v1_19_R2/pom.xml | 6 ++--- v1_19_R3/pom.xml | 6 ++--- v1_20_R1/pom.xml | 6 ++--- v1_20_R2/pom.xml | 6 ++--- v1_20_R3/pom.xml | 6 ++--- v1_9_R1/pom.xml | 4 +-- v1_9_R2/pom.xml | 4 +-- 23 files changed, 101 insertions(+), 74 deletions(-) diff --git a/.gitignore b/.gitignore index aa3fcc8d..02ce5ac0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ target/ .settings/ /integrations/jars/ +.flattened-pom.xml \ No newline at end of file diff --git a/api/pom.xml b/api/pom.xml index 2c20a8ad..13722b3d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} diff --git a/core/pom.xml b/core/pom.xml index c2e0348c..645e9802 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} @@ -30,6 +30,7 @@ maven-shade-plugin 3.2.1 + false org.bstats @@ -97,7 +98,7 @@ fr.skytasul beautyquests-api - ${project.version} + ${revision} provided diff --git a/core/src/main/resources/plugin.yml b/core/src/main/resources/plugin.yml index 3ef14df2..1e5f7f73 100644 --- a/core/src/main/resources/plugin.yml +++ b/core/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: BeautyQuests author: SkytAsul -#version: "${human.version}_BUILD${build.number}" -version: "${human.version}" +version: "${human.version}_BUILD${build.number}" +#version: "${human.version}" description: Quests system with a simple graphical interface. website: https://www.spigotmc.org/resources/beautyquests.39255/ api-version: 1.13 diff --git a/dist/pom.xml b/dist/pom.xml index 592518f4..bba5f7ff 100644 --- a/dist/pom.xml +++ b/dist/pom.xml @@ -7,12 +7,12 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} ../target - beautyquests-${project.version} + beautyquests-${revision} org.apache.maven.plugins @@ -40,133 +40,133 @@ ${project.groupId} beautyquests-api - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-core - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-integrations - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_9_R1 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_9_R2 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_12_R1 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_15_R1 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_16_R1 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_16_R2 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_16_R3 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_17_R1 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_18_R1 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_18_R2 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_19_R1 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_19_R2 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_19_R3 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_20_R1 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_20_R2 - ${project.version} + ${revision} jar compile ${project.groupId} beautyquests-v1_20_R3 - ${project.version} + ${revision} jar compile diff --git a/integrations/pom.xml b/integrations/pom.xml index 6f7d1771..656a1573 100644 --- a/integrations/pom.xml +++ b/integrations/pom.xml @@ -8,14 +8,13 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} placeholderapi - - https://repo.extendedclip.com/content/repositories/placeholderapi/ + https://repo.extendedclip.com/content/repositories/placeholderapi/ dynmap @@ -78,9 +77,9 @@ - fr.skytasul + fr.skytasul beautyquests-api - ${project.version} + ${revision} provided diff --git a/pom.xml b/pom.xml index 4354df4c..5f01eb51 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} pom BeautyQuests @@ -42,7 +42,8 @@ 8 true unknown - 1.0.2 + 1.0.3-SNAPSHOT + 1.0.3 1.20.4-R0.1-SNAPSHOT @@ -94,6 +95,31 @@ maven-javadoc-plugin 3.4.1 + + org.codehaus.mojo + flatten-maven-plugin + 1.6.0 + + true + resolveCiFriendliesOnly + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + diff --git a/v1_12_R1/pom.xml b/v1_12_R1/pom.xml index 9db4a180..3d0b34ce 100644 --- a/v1_12_R1/pom.xml +++ b/v1_12_R1/pom.xml @@ -7,7 +7,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} true @@ -22,7 +22,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} diff --git a/v1_15_R1/pom.xml b/v1_15_R1/pom.xml index 4db4a58f..d774011d 100644 --- a/v1_15_R1/pom.xml +++ b/v1_15_R1/pom.xml @@ -7,7 +7,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} true @@ -22,7 +22,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} diff --git a/v1_16_R1/pom.xml b/v1_16_R1/pom.xml index 8f5960df..2eb81f89 100644 --- a/v1_16_R1/pom.xml +++ b/v1_16_R1/pom.xml @@ -7,7 +7,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} true @@ -22,7 +22,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} diff --git a/v1_16_R2/pom.xml b/v1_16_R2/pom.xml index db6fc64c..4f4a2924 100644 --- a/v1_16_R2/pom.xml +++ b/v1_16_R2/pom.xml @@ -7,7 +7,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} true @@ -22,7 +22,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} diff --git a/v1_16_R3/pom.xml b/v1_16_R3/pom.xml index 4e9d3d7e..84c4df05 100644 --- a/v1_16_R3/pom.xml +++ b/v1_16_R3/pom.xml @@ -7,7 +7,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} true @@ -22,7 +22,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} diff --git a/v1_17_R1/pom.xml b/v1_17_R1/pom.xml index 5e8113ba..1bb36aca 100644 --- a/v1_17_R1/pom.xml +++ b/v1_17_R1/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} @@ -22,7 +22,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} org.spigotmc @@ -61,7 +61,7 @@ remap-spigot - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + ${project.build.directory}/${project.artifactId}-${revision}-remapped-obf.jar org.spigotmc:minecraft-server:1.17.1-R0.1-SNAPSHOT:csrg:maps-spigot org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT:jar:remapped-obf diff --git a/v1_18_R1/pom.xml b/v1_18_R1/pom.xml index c2691eb1..2299ac2e 100644 --- a/v1_18_R1/pom.xml +++ b/v1_18_R1/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} @@ -22,7 +22,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} org.spigotmc @@ -61,7 +61,7 @@ remap-spigot - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + ${project.build.directory}/${project.artifactId}-${revision}-remapped-obf.jar org.spigotmc:minecraft-server:1.18.1-R0.1-SNAPSHOT:csrg:maps-spigot org.spigotmc:spigot:1.18.1-R0.1-SNAPSHOT:jar:remapped-obf diff --git a/v1_18_R2/pom.xml b/v1_18_R2/pom.xml index ad3d934c..d9a95bb0 100644 --- a/v1_18_R2/pom.xml +++ b/v1_18_R2/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} @@ -22,7 +22,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} org.spigotmc @@ -61,7 +61,7 @@ remap-spigot - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + ${project.build.directory}/${project.artifactId}-${revision}-remapped-obf.jar org.spigotmc:minecraft-server:1.18.2-R0.1-SNAPSHOT:csrg:maps-spigot org.spigotmc:spigot:1.18.2-R0.1-SNAPSHOT:jar:remapped-obf diff --git a/v1_19_R1/pom.xml b/v1_19_R1/pom.xml index b6f1c353..d859ee60 100644 --- a/v1_19_R1/pom.xml +++ b/v1_19_R1/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} @@ -29,7 +29,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} provided @@ -69,7 +69,7 @@ remap-spigot - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + ${project.build.directory}/${project.artifactId}-${revision}-remapped-obf.jar org.spigotmc:minecraft-server:1.19.2-R0.1-SNAPSHOT:csrg:maps-spigot org.spigotmc:spigot:1.19.2-R0.1-SNAPSHOT:jar:remapped-obf diff --git a/v1_19_R2/pom.xml b/v1_19_R2/pom.xml index 743e13ae..1b205fd2 100644 --- a/v1_19_R2/pom.xml +++ b/v1_19_R2/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} @@ -29,7 +29,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} provided @@ -69,7 +69,7 @@ remap-spigot - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + ${project.build.directory}/${project.artifactId}-${revision}-remapped-obf.jar org.spigotmc:minecraft-server:1.19.3-R0.1-SNAPSHOT:csrg:maps-spigot org.spigotmc:spigot:1.19.3-R0.1-SNAPSHOT:jar:remapped-obf diff --git a/v1_19_R3/pom.xml b/v1_19_R3/pom.xml index cc506950..c7c96acc 100644 --- a/v1_19_R3/pom.xml +++ b/v1_19_R3/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} @@ -29,7 +29,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} provided @@ -69,7 +69,7 @@ remap-spigot - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + ${project.build.directory}/${project.artifactId}-${revision}-remapped-obf.jar org.spigotmc:minecraft-server:1.19.4-R0.1-SNAPSHOT:csrg:maps-spigot org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT:jar:remapped-obf diff --git a/v1_20_R1/pom.xml b/v1_20_R1/pom.xml index 86355ceb..b34d453b 100644 --- a/v1_20_R1/pom.xml +++ b/v1_20_R1/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} @@ -29,7 +29,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} provided @@ -69,7 +69,7 @@ remap-spigot - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + ${project.build.directory}/${project.artifactId}-${revision}-remapped-obf.jar org.spigotmc:minecraft-server:1.20.1-R0.1-SNAPSHOT:csrg:maps-spigot org.spigotmc:spigot:1.20.1-R0.1-SNAPSHOT:jar:remapped-obf diff --git a/v1_20_R2/pom.xml b/v1_20_R2/pom.xml index d22ceab5..cee78aaf 100755 --- a/v1_20_R2/pom.xml +++ b/v1_20_R2/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} @@ -31,7 +31,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} provided @@ -71,7 +71,7 @@ remap-spigot - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + ${project.build.directory}/${project.artifactId}-${revision}-remapped-obf.jar org.spigotmc:minecraft-server:${spigot.version}:csrg:maps-spigot org.spigotmc:spigot:${spigot.version}:jar:remapped-obf diff --git a/v1_20_R3/pom.xml b/v1_20_R3/pom.xml index 8fe95997..29dba410 100755 --- a/v1_20_R3/pom.xml +++ b/v1_20_R3/pom.xml @@ -8,7 +8,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} @@ -31,7 +31,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} provided @@ -71,7 +71,7 @@ remap-spigot - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + ${project.build.directory}/${project.artifactId}-${revision}-remapped-obf.jar org.spigotmc:minecraft-server:${spigot.version}:csrg:maps-spigot org.spigotmc:spigot:${spigot.version}:jar:remapped-obf diff --git a/v1_9_R1/pom.xml b/v1_9_R1/pom.xml index b05f93b8..55877766 100644 --- a/v1_9_R1/pom.xml +++ b/v1_9_R1/pom.xml @@ -7,7 +7,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} true @@ -22,7 +22,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} diff --git a/v1_9_R2/pom.xml b/v1_9_R2/pom.xml index 23b7b7d8..9f3687ab 100644 --- a/v1_9_R2/pom.xml +++ b/v1_9_R2/pom.xml @@ -7,7 +7,7 @@ fr.skytasul beautyquests-parent - 1.0.2 + ${revision} true @@ -22,7 +22,7 @@ fr.skytasul beautyquests-core - ${project.version} + ${revision} From ad797a114de873ff0247613f91ef7e215e513098 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Mon, 22 Jan 2024 09:47:44 +0100 Subject: [PATCH 07/32] :bug: Fixed issues with Eat/Drink stages * closes #309 --- .../quests/api/stages/types/AbstractCountableStage.java | 3 ++- .../main/java/fr/skytasul/quests/stages/StageEnchant.java | 3 --- .../main/java/fr/skytasul/quests/stages/StageFish.java | 2 +- .../main/java/fr/skytasul/quests/stages/StageMobs.java | 3 +-- .../java/fr/skytasul/quests/stages/StagePlaceBlocks.java | 8 +++----- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractCountableStage.java b/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractCountableStage.java index 46cd296a..1c8c1c2b 100644 --- a/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractCountableStage.java +++ b/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractCountableStage.java @@ -155,7 +155,8 @@ public void initPlayerDatas(@NotNull PlayerAccount acc, @NotNull Map<@NotNull St */ public boolean event(@NotNull Player p, @UnknownNullability Object object, int amount) { if (amount < 0) throw new IllegalArgumentException("Event amount must be positive (" + amount + ")"); - if (!canUpdate(p)) return true; + if (!canUpdate(p) || !hasStarted(p)) + return true; PlayerAccount acc = PlayersManager.getPlayerAccount(p); for (CountableObject countableObject : objects) { diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageEnchant.java b/core/src/main/java/fr/skytasul/quests/stages/StageEnchant.java index f9cdedbc..92d75cb9 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageEnchant.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageEnchant.java @@ -31,9 +31,6 @@ public StageEnchant(StageController controller, ConfigurationSection section) { @EventHandler (priority = EventPriority.MONITOR, ignoreCancelled = true) public void onEnchant(EnchantItemEvent e) { - if (!hasStarted(e.getEnchanter())) - return; - ItemStack finalItem = e.getItem().clone(); ItemMeta meta = finalItem.getItemMeta(); e.getEnchantsToAdd().forEach((enchant, level) -> meta.addEnchant(enchant, level, false)); diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageFish.java b/core/src/main/java/fr/skytasul/quests/stages/StageFish.java index 34ebaad8..0c9cf37c 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageFish.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageFish.java @@ -36,7 +36,7 @@ public void onFish(PlayerFishEvent e){ if (e.getState() == State.CAUGHT_FISH && e.getCaught() instanceof Item){ Player p = e.getPlayer(); Item item = (Item) e.getCaught(); - if (item.isDead() || !hasStarted(p)) + if (item.isDead()) return; ItemStack fish = item.getItemStack(); event(p, fish, fish.getAmount()); diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageMobs.java b/core/src/main/java/fr/skytasul/quests/stages/StageMobs.java index 6a35c550..dafda32a 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageMobs.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageMobs.java @@ -57,8 +57,7 @@ public void onMobKilled(BQMobDeathEvent e){ Player p = e.getKiller(); if (p == e.getBukkitEntity()) return; // player suicidal - if (hasStarted(p)) - event(p, new KilledMob(e.getPluginMob(), e.getBukkitEntity()), e.getAmount()); + event(p, new KilledMob(e.getPluginMob(), e.getBukkitEntity()), e.getAmount()); } @Override diff --git a/core/src/main/java/fr/skytasul/quests/stages/StagePlaceBlocks.java b/core/src/main/java/fr/skytasul/quests/stages/StagePlaceBlocks.java index 34807859..26f974df 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StagePlaceBlocks.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StagePlaceBlocks.java @@ -3,7 +3,6 @@ import java.util.ArrayList; import java.util.List; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -33,10 +32,9 @@ public StagePlaceBlocks(StageController controller, List Date: Sat, 10 Feb 2024 17:42:53 +0100 Subject: [PATCH 08/32] :chart_with_upwards_trend: Added hook version to metrics --- .../java/fr/skytasul/quests/BeautyQuests.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/fr/skytasul/quests/BeautyQuests.java b/core/src/main/java/fr/skytasul/quests/BeautyQuests.java index d0685e33..bcdbeb48 100644 --- a/core/src/main/java/fr/skytasul/quests/BeautyQuests.java +++ b/core/src/main/java/fr/skytasul/quests/BeautyQuests.java @@ -10,14 +10,12 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; -import java.util.function.Function; import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import org.bstats.bukkit.Metrics; -import org.bstats.charts.AdvancedPie; import org.bstats.charts.DrilldownPie; import org.bstats.charts.SimplePie; import org.bstats.charts.SingleLineChart; @@ -27,6 +25,7 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.NotNull; @@ -328,13 +327,17 @@ private void launchMetrics(String pluginVersion) { if (size > 5) return "5 - 10"; return "0 - 5"; })); - metrics.addCustomChart(new AdvancedPie("hooks", () -> { // replace with bar chart when bStats add them back + metrics.addCustomChart(new DrilldownPie("hooks_v2", () -> { return integrations.getDependencies() - .stream() - .filter(dep -> dep.isEnabled()) - .map(dep -> dep.getFoundPlugin().getName()) - .distinct() - .collect(Collectors.toMap(Function.identity(), __ -> 1)); + .stream() + .filter(dep -> dep.isEnabled()) + .map(dep -> dep.getFoundPlugin()) + .distinct() + .collect(Collectors.toMap(Plugin::getName, plugin -> { + Map entry = new HashMap<>(); + entry.put(plugin.getDescription().getVersion(), 1); + return entry; + })); })); logger.debug("Started bStats metrics"); } From cdacf5c7e69e779ab8dfd54a2d884d036f95561a Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Mon, 26 Feb 2024 14:56:24 +0100 Subject: [PATCH 09/32] :bug: Fixed issues with WorldGuard integration and __global__ regions --- .../integrations/worldguard/BQWorldGuard.java | 10 ++-- .../integrations/worldguard/StageArea.java | 39 +++++++++----- .../worldguard/WorldGuardEntryHandler.java | 54 ++++++++++++++++--- 3 files changed, 82 insertions(+), 21 deletions(-) diff --git a/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/BQWorldGuard.java b/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/BQWorldGuard.java index 56cc1349..1bdd2b7e 100644 --- a/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/BQWorldGuard.java +++ b/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/BQWorldGuard.java @@ -104,10 +104,14 @@ public World getWorld(String id) { public boolean isInRegion(ProtectedRegion region, Location to, boolean mustBeHighest) { ApplicableRegionSet regions = getRegionManager(to.getWorld()) .getApplicableRegions(BlockVector3.at(to.getBlockX(), to.getBlockY(), to.getBlockZ())); + ProtectedRegion global = getRegionManager(to.getWorld()).getRegion("__global__"); + boolean isGlobal = region.equals(global); if (mustBeHighest) { - return regions.getRegions().iterator().next().equals(region); - } else - return regions.getRegions().contains(region); + ProtectedRegion highest = regions.getRegions().isEmpty() ? global : regions.getRegions().iterator().next(); + return highest.equals(region) || (isGlobal && global.getPriority() >= highest.getPriority()); + } else { + return isGlobal || regions.getRegions().contains(region); + } } public boolean regionExists(String name, World w) { diff --git a/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/StageArea.java b/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/StageArea.java index c9ad138b..98f5a620 100644 --- a/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/StageArea.java +++ b/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/StageArea.java @@ -18,6 +18,7 @@ import fr.skytasul.quests.api.gui.ItemUtils; import fr.skytasul.quests.api.localization.Lang; import fr.skytasul.quests.api.options.QuestOption; +import fr.skytasul.quests.api.players.PlayerAccount; import fr.skytasul.quests.api.stages.AbstractStage; import fr.skytasul.quests.api.stages.StageController; import fr.skytasul.quests.api.stages.StageDescriptionPlaceholdersContext; @@ -59,9 +60,12 @@ public StageArea(StageController controller, String regionName, String worldName } @EventHandler - public void onPlayerMove(PlayerMoveEvent e){ - if (BQWorldGuard.getInstance().doHandleEntry()) return; // on WG 7.0 or higher - if (e.getFrom().getBlockX() == e.getTo().getBlockX() && e.getFrom().getBlockY() == e.getTo().getBlockY() && e.getFrom().getBlockZ() == e.getTo().getBlockZ()) return; + public void onPlayerMove(PlayerMoveEvent e) { + if (BQWorldGuard.getInstance().doHandleEntry()) + return; // on WG 7.0 or higher + if (e.getFrom().getBlockX() == e.getTo().getBlockX() && e.getFrom().getBlockY() == e.getTo().getBlockY() + && e.getFrom().getBlockZ() == e.getTo().getBlockZ()) + return; if (hasStarted(e.getPlayer()) && canUpdate(e.getPlayer())) { if (world.equals(e.getTo().getWorld()) && BQWorldGuard.getInstance().isInRegion(region, e.getTo(), false) == !exit) { @@ -98,6 +102,15 @@ public void onRegionExit(WorldGuardExitEvent e) { } } + @Override + public void started(@NotNull PlayerAccount acc) { + super.started(acc); + if (acc.isCurrent()) { + if (BQWorldGuard.getInstance().isInRegion(region, acc.getPlayer().getLocation(), false)) + finishStage(acc.getPlayer()); + } + } + @Override protected void createdPlaceholdersRegistry(@NotNull PlaceholderRegistry placeholders) { super.createdPlaceholdersRegistry(placeholders); @@ -112,14 +125,15 @@ protected void createdPlaceholdersRegistry(@NotNull PlaceholderRegistry placehol @Override public Located getLocated() { - if (region instanceof GlobalProtectedRegion) return null; + if (region instanceof GlobalProtectedRegion) + return null; if (System.currentTimeMillis() - lastCenter > REFRESH_CENTER) { Location centerLoc = BukkitAdapter.adapt(world, - region.getMaximumPoint() - .subtract(region.getMinimumPoint()) - .divide(2) - .add(region.getMinimumPoint())) // midpoint + region.getMaximumPoint() + .subtract(region.getMinimumPoint()) + .divide(2) + .add(region.getMinimumPoint())) // midpoint .add(0.5, 0.5, 0.5); center = Locatable.Located.create(centerLoc); @@ -128,11 +142,11 @@ public Located getLocated() { return center; } - public ProtectedRegion getRegion(){ + public ProtectedRegion getRegion() { return region; } - public World getWorld(){ + public World getWorld() { return world; } @@ -144,7 +158,8 @@ public void serialize(ConfigurationSection section) { } public static StageArea deserialize(ConfigurationSection section, StageController controller) { - return new StageArea(controller, section.getString("region"), section.getString("world"), section.getBoolean("exit", false)); + return new StageArea(controller, section.getString("region"), section.getString("world"), + section.getBoolean("exit", false)); } public static class Creator extends StageCreation { @@ -188,7 +203,7 @@ private void launchRegionEditor(Player p, boolean first) { }, obj -> { if (BQWorldGuard.getInstance().regionExists(obj, p.getWorld())) { setRegion(obj, p.getWorld().getName()); - }else { + } else { Lang.REGION_DOESNT_EXIST.send(p); if (first) context.remove(); diff --git a/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/WorldGuardEntryHandler.java b/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/WorldGuardEntryHandler.java index 24c2ddb6..00b32b17 100644 --- a/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/WorldGuardEntryHandler.java +++ b/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/WorldGuardEntryHandler.java @@ -1,11 +1,14 @@ package fr.skytasul.quests.integrations.worldguard; +import java.util.HashSet; import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.World; import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.bukkit.BukkitPlayer; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.ApplicableRegionSet; @@ -54,8 +57,20 @@ public WorldGuardEntryHandler(Session session) { public void initialize(LocalPlayer player, Location current, ApplicableRegionSet set) { super.initialize(player, current, set); // no need to test that the set is not empty: there is always the __global__ region + // EDIT: actually no, idk if it has changed over time + Set regions = set.getRegions(); + if (current.getExtent() instanceof World) { + ProtectedRegion global = WorldGuard.getInstance().getPlatform().getRegionContainer() + .get((World) current.getExtent()).getRegion("__global__"); + if (global != null) { + regions = new HashSet<>(regions); + regions.add(global); + } + } + + final Set finalRegions = regions; Bukkit.getScheduler().runTaskLater(QuestsPlugin.getPlugin(), () -> { - Bukkit.getPluginManager().callEvent(new WorldGuardEntryEvent(BukkitAdapter.adapt(player), set.getRegions())); + Bukkit.getPluginManager().callEvent(new WorldGuardEntryEvent(BukkitAdapter.adapt(player), finalRegions)); }, 1L); } @@ -63,12 +78,39 @@ public void initialize(LocalPlayer player, Location current, ApplicableRegionSet public boolean onCrossBoundary(LocalPlayer player, Location from, Location to, ApplicableRegionSet toSet, Set entered, Set exited, MoveType moveType) { Player bukkitPlayer = BukkitAdapter.adapt(player); if (!QuestsPlugin.getPlugin().getNpcManager().isNPC(bukkitPlayer)) { - if (!entered.isEmpty()) - Bukkit.getPluginManager().callEvent(new WorldGuardEntryEvent(bukkitPlayer, entered)); - if (!exited.isEmpty()) - Bukkit.getPluginManager().callEvent(new WorldGuardExitEvent(bukkitPlayer, exited)); + // entered and exited do not have global regions + if (!from.getExtent().equals(to.getExtent()) + && (from.getExtent() instanceof World && to.getExtent() instanceof World)) { + ProtectedRegion fromGlobal = WorldGuard.getInstance().getPlatform().getRegionContainer() + .get((World) from.getExtent()).getRegion("__global__"); + ProtectedRegion toGlobal = WorldGuard.getInstance().getPlatform().getRegionContainer() + .get((World) to.getExtent()).getRegion("__global__"); + // a world does not necessarily have a global region + if (toGlobal != null) { + entered = new HashSet<>(entered); + entered.add(toGlobal); + } + if (fromGlobal != null) { + exited = new HashSet<>(exited); + exited.add(fromGlobal); + } + } + + if (!entered.isEmpty() || !exited.isEmpty()) { + final Set enteredFinal = entered; + final Set exitedFinal = exited; + Bukkit.getScheduler().runTask(QuestsPlugin.getPlugin(), () -> { + // We must wait for the end of this tick to fire the entry/exit events + // otherwise the player might be between worlds or still physically + // in the "old" regions. + if (!enteredFinal.isEmpty()) + Bukkit.getPluginManager().callEvent(new WorldGuardEntryEvent(bukkitPlayer, enteredFinal)); + if (!exitedFinal.isEmpty()) + Bukkit.getPluginManager().callEvent(new WorldGuardExitEvent(bukkitPlayer, exitedFinal)); + }); + } } - return super.onCrossBoundary(player, from, to, toSet, entered, exited, moveType); + return true; } } From 6d8f95e8d0a7b56271c2b675f1e1a5e050f0472b Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Mon, 26 Feb 2024 14:56:39 +0100 Subject: [PATCH 10/32] :bug: Fixed issues with particles visible across worlds --- .../src/main/java/fr/skytasul/quests/utils/ParticleEffect.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java b/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java index 031a2daf..77dc67a1 100644 --- a/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java +++ b/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java @@ -112,7 +112,8 @@ public void sendParticle(Location lc, List players, double offX, double } for (Player p : players) { - p.spawnParticle(type.particle, lc, amount, offX, offY, offZ, extra, data); + if (p.getWorld() == lc.getWorld()) + p.spawnParticle(type.particle, lc, amount, offX, offY, offZ, extra, data); } } From fde82c50c3758ab4430c08cf9ba5559009dc139b Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Fri, 8 Mar 2024 18:00:52 +0100 Subject: [PATCH 11/32] :bug: Using longs instead of ints for progress --- .../stages/types/AbstractCountableStage.java | 6 +-- .../api/stages/types/AbstractEntityStage.java | 46 +++++++++---------- .../api/utils/progress/HasProgress.java | 4 +- .../utils/progress/ProgressPlaceholders.java | 16 +++---- .../HasItemsDescriptionConfiguration.java | 12 ++--- .../quests/stages/StageBringBack.java | 4 +- .../skytasul/quests/stages/StageBucket.java | 6 +-- .../fr/skytasul/quests/stages/StageCraft.java | 12 ++--- .../quests/stages/StageDealDamage.java | 10 ++-- .../skytasul/quests/stages/StagePlayTime.java | 8 ++-- .../options/StageOptionProgressBar.java | 8 ++-- 11 files changed, 66 insertions(+), 66 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractCountableStage.java b/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractCountableStage.java index 1c8c1c2b..ebc12d2d 100644 --- a/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractCountableStage.java +++ b/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractCountableStage.java @@ -103,20 +103,20 @@ public Map> cloneObjects() { } @Override - public int getPlayerAmount(@NotNull PlayerAccount account, CountableObject object) { + public long getPlayerAmount(@NotNull PlayerAccount account, CountableObject object) { // we do not use default implementation in HasMultipleObjects to avoid conversion from UUID to // CountableObject return getPlayerRemainings(account, false).get(object.getUUID()); } @Override - public int getPlayerAmount(@NotNull PlayerAccount account) { + public long getPlayerAmount(@NotNull PlayerAccount account) { // same as in getPlayerAmount return getPlayerRemainings(account, false).values().stream().mapToInt(Integer::intValue).sum(); } @Override - public int getTotalAmount() { + public long getTotalAmount() { return objects.stream().mapToInt(CountableObject::getAmount).sum(); } diff --git a/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractEntityStage.java b/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractEntityStage.java index 0b66090a..235c30fd 100644 --- a/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractEntityStage.java +++ b/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractEntityStage.java @@ -29,7 +29,7 @@ @LocatableType (types = LocatedType.ENTITY) public abstract class AbstractEntityStage extends AbstractStage implements Locatable.MultipleLocatable, HasSingleObject { - + protected final @NotNull EntityType entity; protected final int amount; @@ -38,7 +38,7 @@ protected AbstractEntityStage(@NotNull StageController controller, @NotNull Enti this.entity = entity; this.amount = amount; } - + protected void event(@NotNull Player p, @NotNull EntityType type) { PlayerAccount acc = PlayersManager.getPlayerAccount(p); if (hasStarted(p) && canUpdate(p)) { @@ -54,19 +54,19 @@ protected void event(@NotNull Player p, @NotNull EntityType type) { } } } - + protected @NotNull OptionalInt getPlayerAmountOptional(@NotNull PlayerAccount acc) { Integer amount = getData(acc, "amount"); return amount == null ? OptionalInt.empty() : OptionalInt.of(amount.intValue()); } - + @Override - public int getPlayerAmount(@NotNull PlayerAccount account) { + public long getPlayerAmount(@NotNull PlayerAccount account) { return getPlayerAmountOptional(account).orElse(0); } @Override - public int getObjectAmount() { + public long getObjectAmount() { return amount; } @@ -80,24 +80,24 @@ public void initPlayerDatas(@NotNull PlayerAccount acc, @NotNull Map<@NotNull St super.initPlayerDatas(acc, datas); datas.put("amount", amount); } - + @Override protected void serialize(@NotNull ConfigurationSection section) { section.set("entityType", entity == null ? "any" : entity.name()); section.set("amount", amount); } - + @Override protected void createdPlaceholdersRegistry(@NotNull PlaceholderRegistry placeholders) { super.createdPlaceholdersRegistry(placeholders); ProgressPlaceholders.registerObject(placeholders, "mobs", this); } - + @Override public boolean canBeFetchedAsynchronously() { return false; } - + @Override public @NotNull Spliterator<@NotNull Located> getNearbyLocated(@NotNull NearbyFetcher fetcher) { if (!fetcher.isTargeting(LocatedType.ENTITY)) return Spliterators.emptySpliterator(); @@ -114,12 +114,12 @@ public boolean canBeFetchedAsynchronously() { .map(entry -> Located.LocatedEntity.create(entry.getKey())) .spliterator(); } - + public abstract static class AbstractCreator extends StageCreation { - + protected EntityType entity = null; protected int amount = 1; - + protected AbstractCreator(@NotNull StageCreationContext context) { super(context); } @@ -127,14 +127,14 @@ protected AbstractCreator(@NotNull StageCreationContext context) { @Override public void setupLine(@NotNull StageGuiLine line) { super.setupLine(line); - + line.setItem(6, ItemUtils.item(XMaterial.CHICKEN_SPAWN_EGG, Lang.changeEntityType.toString()), event -> { QuestsPlugin.getPlugin().getGuiManager().getFactory().createEntityTypeSelection(x -> { setEntity(x); event.reopen(); }, x -> x == null ? canBeAnyEntity() : canUseEntity(x)).open(event.getPlayer()); }); - + line.setItem(7, ItemUtils.item(XMaterial.REDSTONE, Lang.Amount.quickFormat("amount", 1)), event -> { new TextEditor<>(event.getPlayer(), event::reopen, x -> { setAmount(x); @@ -142,36 +142,36 @@ public void setupLine(@NotNull StageGuiLine line) { }, NumberParser.INTEGER_PARSER_STRICT_POSITIVE).start(); }); } - + public void setEntity(EntityType entity) { this.entity = entity; getLine().refreshItemLoreOptionValue(6, entity == null ? Lang.EntityTypeAny.toString() : entity.name()); } - + public void setAmount(int amount) { this.amount = amount; getLine().refreshItemName(7, Lang.Amount.quickFormat("amount", amount)); } - + @Override public void start(Player p) { super.start(p); setEntity(null); } - + @Override public void edit(T stage) { super.edit(stage); setEntity(stage.entity); setAmount(stage.amount); } - + protected boolean canBeAnyEntity() { return true; } - + protected abstract boolean canUseEntity(@NotNull EntityType type); - + } - + } \ No newline at end of file diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/progress/HasProgress.java b/api/src/main/java/fr/skytasul/quests/api/utils/progress/HasProgress.java index 7813f3c5..94240731 100755 --- a/api/src/main/java/fr/skytasul/quests/api/utils/progress/HasProgress.java +++ b/api/src/main/java/fr/skytasul/quests/api/utils/progress/HasProgress.java @@ -5,8 +5,8 @@ public interface HasProgress { - int getPlayerAmount(@NotNull PlayerAccount account); + long getPlayerAmount(@NotNull PlayerAccount account); - int getTotalAmount(); + long getTotalAmount(); } diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/progress/ProgressPlaceholders.java b/api/src/main/java/fr/skytasul/quests/api/utils/progress/ProgressPlaceholders.java index 1c1732ca..26bcf175 100755 --- a/api/src/main/java/fr/skytasul/quests/api/utils/progress/ProgressPlaceholders.java +++ b/api/src/main/java/fr/skytasul/quests/api/utils/progress/ProgressPlaceholders.java @@ -22,17 +22,17 @@ public final class ProgressPlaceholders { private static final PlaceholderRegistry PROGRESS_REGISTRY = new PlaceholderRegistry() .registerIndexedContextual("remaining", ProgressPlaceholderContext.class, - context -> Integer.toString(context.getProgress().getPlayerAmount(context.getPlayerAccount()))) + context -> Long.toString(context.getProgress().getPlayerAmount(context.getPlayerAccount()))) .registerIndexedContextual("done", ProgressPlaceholderContext.class, - context -> Integer.toString(context.getProgress().getTotalAmount() + context -> Long.toString(context.getProgress().getTotalAmount() - context.getProgress().getPlayerAmount(context.getPlayerAccount()))) .registerIndexedContextual("total", ProgressPlaceholderContext.class, - context -> Integer.toString(context.getProgress().getTotalAmount())) + context -> Long.toString(context.getProgress().getTotalAmount())) .registerIndexedContextual("percentage", ProgressPlaceholderContext.class, context -> { - int perc = (int) (100D - context.getProgress().getPlayerAmount(context.getPlayerAccount()) * 100D + long perc = (long) (100D - context.getProgress().getPlayerAmount(context.getPlayerAccount()) * 100D / context.getProgress().getTotalAmount()); - return Integer.toString(perc); + return Long.toString(perc); }); private static final PlaceholderRegistry DESCRIPTION_REGISTRY = PROGRESS_REGISTRY.with(new PlaceholderRegistry() .registerIndexedContextual("name", ProgressObjectPlaceholderContext.class, @@ -93,7 +93,7 @@ public static void registerObjects(@NotNull PlaceholderRegistry placeholders } private static @NotNull HasSingleObject buildFrom(@NotNull HasMultipleObjects objects, CountableObject object, - int amount) { + long amount) { return new HasSingleObject() { @Override public @NotNull ItemsDescriptionConfiguration getItemsDescriptionConfiguration() { @@ -101,7 +101,7 @@ public static void registerObjects(@NotNull PlaceholderRegistry placeholders } @Override - public int getPlayerAmount(@NotNull PlayerAccount account) { + public long getPlayerAmount(@NotNull PlayerAccount account) { return amount; } @@ -111,7 +111,7 @@ public int getPlayerAmount(@NotNull PlayerAccount account) { } @Override - public int getObjectAmount() { + public long getObjectAmount() { return object.getAmount(); } }; diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/progress/itemdescription/HasItemsDescriptionConfiguration.java b/api/src/main/java/fr/skytasul/quests/api/utils/progress/itemdescription/HasItemsDescriptionConfiguration.java index 4b56ed61..2b3657fa 100755 --- a/api/src/main/java/fr/skytasul/quests/api/utils/progress/itemdescription/HasItemsDescriptionConfiguration.java +++ b/api/src/main/java/fr/skytasul/quests/api/utils/progress/itemdescription/HasItemsDescriptionConfiguration.java @@ -21,10 +21,10 @@ public interface HasSingleObject extends HasItemsDescriptionConfiguration, HasPr @NotNull String getObjectName(); - int getObjectAmount(); + long getObjectAmount(); @Override - default int getTotalAmount() { + default long getTotalAmount() { return getObjectAmount(); } @@ -45,18 +45,18 @@ public interface HasMultipleObjects extends HasItemsDescriptionConfiguration, @NotNull Map, Integer> getPlayerAmounts(@NotNull PlayerAccount account); - default int getPlayerAmount(@NotNull PlayerAccount account, CountableObject object) { + default long getPlayerAmount(@NotNull PlayerAccount account, CountableObject object) { return getPlayerAmounts(account).get(object); } @Override - default int getPlayerAmount(@NotNull PlayerAccount account) { + default long getPlayerAmount(@NotNull PlayerAccount account) { return getPlayerAmounts(account).values().stream().mapToInt(Integer::intValue).sum(); } @Override - default int getTotalAmount() { - return getObjects().stream().mapToInt(CountableObject::getAmount).sum(); + default long getTotalAmount() { + return getObjects().stream().mapToLong(CountableObject::getAmount).sum(); } } diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java b/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java index b83653c4..cdb34904 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java @@ -107,7 +107,7 @@ protected void createdPlaceholdersRegistry(@NotNull PlaceholderRegistry placehol Arrays.stream(items).map(item -> ProgressPlaceholders.formatObject(new HasSingleObject() { @Override - public int getPlayerAmount(@NotNull PlayerAccount account) { + public long getPlayerAmount(@NotNull PlayerAccount account) { return item.getAmount(); } @@ -117,7 +117,7 @@ public int getPlayerAmount(@NotNull PlayerAccount account) { } @Override - public int getObjectAmount() { + public long getObjectAmount() { return item.getAmount(); } }, context)).toArray(String[]::new); diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageBucket.java b/core/src/main/java/fr/skytasul/quests/stages/StageBucket.java index 17586c69..5f2117d3 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageBucket.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageBucket.java @@ -56,7 +56,7 @@ public int getBucketAmount() { } @Override - public int getObjectAmount() { + public long getObjectAmount() { return amount; } @@ -70,7 +70,7 @@ public void onBucketFill(PlayerBucketFillEvent e) { Player p = e.getPlayer(); if (hasStarted(p) && canUpdate(p)) { if (BucketType.fromMaterial(XMaterial.matchXMaterial(e.getItemStack())) == bucket) { - int amount = getPlayerAmount(PlayersManager.getPlayerAccount(p)); + long amount = getPlayerAmount(PlayersManager.getPlayerAccount(p)); if (amount <= 1) { finishStage(p); }else { @@ -81,7 +81,7 @@ public void onBucketFill(PlayerBucketFillEvent e) { } @Override - public int getPlayerAmount(PlayerAccount acc) { + public long getPlayerAmount(PlayerAccount acc) { return getData(acc, "amount"); } diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageCraft.java b/core/src/main/java/fr/skytasul/quests/stages/StageCraft.java index 964bf332..726c366d 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageCraft.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageCraft.java @@ -55,7 +55,7 @@ public ItemStack getItem(){ public void onFurnaceExtract(FurnaceExtractEvent event) { Player p = event.getPlayer(); if (comparisons.isSimilar(result, new ItemStack(event.getItemType())) && hasStarted(p) && canUpdate(p, true)) { - int amount = getPlayerAmount(PlayersManager.getPlayerAccount(p)) - event.getItemAmount(); + long amount = getPlayerAmount(PlayersManager.getPlayerAccount(p)) - event.getItemAmount(); if (amount <= 0) { finishStage(p); }else { @@ -114,7 +114,7 @@ public void onCraft(BQCraftEvent event) { // No use continuing if we haven't actually crafted a thing if (recipeAmount == 0) return; - int amount = getPlayerAmount(PlayersManager.getPlayerAccount(p)) - recipeAmount; + long amount = getPlayerAmount(PlayersManager.getPlayerAccount(p)) - recipeAmount; if (amount <= 0) { finishStage(p); }else { @@ -131,9 +131,9 @@ public void initPlayerDatas(PlayerAccount acc, Map datas) { } @Override - public int getPlayerAmount(PlayerAccount acc) { - Integer amount = getData(acc, "amount"); - return amount == null ? 0 : amount.intValue(); + public long getPlayerAmount(PlayerAccount acc) { + Long amount = getData(acc, "amount"); + return amount == null ? 0 : amount.longValue(); } @Override @@ -142,7 +142,7 @@ public int getPlayerAmount(PlayerAccount acc) { } @Override - public int getObjectAmount() { + public long getObjectAmount() { return result.getAmount(); } diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageDealDamage.java b/core/src/main/java/fr/skytasul/quests/stages/StageDealDamage.java index 921687fd..2a4bca6f 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageDealDamage.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageDealDamage.java @@ -88,13 +88,13 @@ public double getPlayerAmountDouble(@NotNull PlayerAccount account) { } @Override - public int getPlayerAmount(@NotNull PlayerAccount account) { - return (int) Math.ceil(getPlayerAmountDouble(account)); + public long getPlayerAmount(@NotNull PlayerAccount account) { + return (long) Math.ceil(getPlayerAmountDouble(account)); } @Override - public int getTotalAmount() { - return (int) damage; + public long getTotalAmount() { + return (long) damage; } @Override @@ -102,7 +102,7 @@ protected void createdPlaceholdersRegistry(@NotNull PlaceholderRegistry placehol super.createdPlaceholdersRegistry(placeholders); ProgressPlaceholders.registerProgress(placeholders, "damage", this); placeholders.registerIndexedContextual("damage_remaining", StageDescriptionPlaceholdersContext.class, - context -> Integer.toString(getPlayerAmount(context.getPlayerAccount()))); + context -> Long.toString(getPlayerAmount(context.getPlayerAccount()))); placeholders.registerIndexed("target_mobs", getTargetMobsString(targetMobs)); } diff --git a/core/src/main/java/fr/skytasul/quests/stages/StagePlayTime.java b/core/src/main/java/fr/skytasul/quests/stages/StagePlayTime.java index e915acbc..34307461 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StagePlayTime.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StagePlayTime.java @@ -97,13 +97,13 @@ private void launchTask(Player p, long remaining) { } @Override - public int getPlayerAmount(@NotNull PlayerAccount account) { - return (int) (getRemaining(account) * 50L); + public long getPlayerAmount(@NotNull PlayerAccount account) { + return getRemaining(account) * 50L; } @Override - public int getTotalAmount() { - return (int) (playTicks * 50L); + public long getTotalAmount() { + return playTicks * 50L; } @Override diff --git a/core/src/main/java/fr/skytasul/quests/stages/options/StageOptionProgressBar.java b/core/src/main/java/fr/skytasul/quests/stages/options/StageOptionProgressBar.java index 51afb5f1..975b3cb6 100755 --- a/core/src/main/java/fr/skytasul/quests/stages/options/StageOptionProgressBar.java +++ b/core/src/main/java/fr/skytasul/quests/stages/options/StageOptionProgressBar.java @@ -122,7 +122,7 @@ class ProgressBar { private final PlayerAccount acc; private final BQBossBar bar; private final T progress; - private final int totalAmount; + private final long totalAmount; private final PlaceholderRegistry placeholders; private BukkitTask timer; @@ -160,13 +160,13 @@ public void remove() { public void update() { timer(); - int playerRemaining = progress.getPlayerAmount(acc); + long playerRemaining = progress.getPlayerAmount(acc); if (playerRemaining >= 0 && playerRemaining <= totalAmount) { bar.setProgress((totalAmount - playerRemaining) * 1D / totalAmount); } else QuestsPlugin.getPlugin().getLoggerExpanded() - .warning("Amount of objects superior to max objects in " + progress.toString() + " for player " - + acc.getNameAndID() + ": " + playerRemaining + " > " + totalAmount); + .warning("Amount of objects invalid in " + progress.getController().toString() + + " for player " + acc.getNameAndID() + ": " + playerRemaining + " / " + totalAmount); bar.setTitle(MessageUtils.format(getProgressConfig().getBossBarFormat(), placeholders, PlaceholdersContext.of(acc.getPlayer(), true, null))); From 56d953f5f92c876b375bd172096584b32f363a89 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Fri, 8 Mar 2024 18:01:25 +0100 Subject: [PATCH 12/32] :bug: Fixed an issue with WorldGuard integration and worlds --- .../quests/integrations/worldguard/BQWorldGuard.java | 11 ----------- .../quests/integrations/worldguard/StageArea.java | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/BQWorldGuard.java b/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/BQWorldGuard.java index 1bdd2b7e..d5a81163 100644 --- a/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/BQWorldGuard.java +++ b/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/BQWorldGuard.java @@ -90,17 +90,6 @@ public String getRegionID(Object region) { return ((ProtectedRegion) region).getId(); } - public World getWorld(String id) { - for (World w : Bukkit.getWorlds()){ - try{ - if (getRegionManager(w).hasRegion(id)) return w; - }catch (Exception ex){ - continue; - } - } - return null; - } - public boolean isInRegion(ProtectedRegion region, Location to, boolean mustBeHighest) { ApplicableRegionSet regions = getRegionManager(to.getWorld()) .getApplicableRegions(BlockVector3.at(to.getBlockX(), to.getBlockY(), to.getBlockZ())); diff --git a/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/StageArea.java b/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/StageArea.java index 98f5a620..af7d6f83 100644 --- a/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/StageArea.java +++ b/integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/StageArea.java @@ -221,7 +221,7 @@ public void start(Player p) { @Override public void edit(StageArea stage) { super.edit(stage); - setRegion(stage.getRegion().getId(), BQWorldGuard.getInstance().getWorld(stage.getRegion().getId()).getName()); + setRegion(stage.getRegion().getId(), stage.world.getName()); setExit(stage.exit); } From 54592f8deaa8b2fe0a519dc5e0e5bfaeee87095d Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sun, 10 Mar 2024 18:28:32 +0100 Subject: [PATCH 13/32] :technologist: Added missing API methods --- .../quests/api/npcs/dialogs/DialogRunner.java | 8 ++++++++ .../utils/types/DialogRunnerImplementation.java | 15 ++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/npcs/dialogs/DialogRunner.java b/api/src/main/java/fr/skytasul/quests/api/npcs/dialogs/DialogRunner.java index dd062f94..be23d3d9 100644 --- a/api/src/main/java/fr/skytasul/quests/api/npcs/dialogs/DialogRunner.java +++ b/api/src/main/java/fr/skytasul/quests/api/npcs/dialogs/DialogRunner.java @@ -4,9 +4,17 @@ import java.util.function.Predicate; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import fr.skytasul.quests.api.npcs.BqNpc; public interface DialogRunner { + @Nullable + BqNpc getNpc(); + + @Nullable + Dialog getDialog(); + void addTest(Predicate test); void addTestCancelling(Predicate test); diff --git a/core/src/main/java/fr/skytasul/quests/utils/types/DialogRunnerImplementation.java b/core/src/main/java/fr/skytasul/quests/utils/types/DialogRunnerImplementation.java index d5c80c84..9ae96d37 100644 --- a/core/src/main/java/fr/skytasul/quests/utils/types/DialogRunnerImplementation.java +++ b/core/src/main/java/fr/skytasul/quests/utils/types/DialogRunnerImplementation.java @@ -10,6 +10,7 @@ import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitTask; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import fr.skytasul.quests.BeautyQuests; import fr.skytasul.quests.api.QuestsConfiguration; import fr.skytasul.quests.api.QuestsPlugin; @@ -24,8 +25,8 @@ public class DialogRunnerImplementation implements DialogRunner { - private final Dialog dialog; - private final BqNpc npc; + private final @Nullable Dialog dialog; + private final @Nullable BqNpc npc; private List> tests = new ArrayList<>(); private List> testsCancelling = new ArrayList<>(); @@ -34,11 +35,19 @@ public class DialogRunnerImplementation implements DialogRunner { private Map players = new HashMap<>(); private Boolean navigationInitiallyPaused = null; - public DialogRunnerImplementation(Dialog dialog, BqNpc npc) { + public DialogRunnerImplementation(@Nullable Dialog dialog, @Nullable BqNpc npc) { this.dialog = dialog; this.npc = npc; } + public @Nullable BqNpc getNpc() { + return npc; + } + + public @Nullable Dialog getDialog() { + return dialog; + } + @Override public void addTest(Predicate test) { tests.add(test); From 8a6f417a297b06b6384c433e2f5a6ccdbb3acc85 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Tue, 12 Mar 2024 11:09:38 +0100 Subject: [PATCH 14/32] :bug: Breed stage now works with turtles and frogs --- .../fr/skytasul/quests/stages/StageBreed.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageBreed.java b/core/src/main/java/fr/skytasul/quests/stages/StageBreed.java index a22815ef..4cff6039 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageBreed.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageBreed.java @@ -1,21 +1,36 @@ package fr.skytasul.quests.stages; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Animals; import org.bukkit.entity.Breedable; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityBreedEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; import org.jetbrains.annotations.NotNull; import fr.skytasul.quests.api.localization.Lang; import fr.skytasul.quests.api.stages.StageController; import fr.skytasul.quests.api.stages.StageDescriptionPlaceholdersContext; import fr.skytasul.quests.api.stages.creation.StageCreationContext; import fr.skytasul.quests.api.stages.types.AbstractEntityStage; +import fr.skytasul.quests.api.utils.XMaterial; public class StageBreed extends AbstractEntityStage implements Listener { + private static final List EGG_MATERIALS = + Arrays.asList(XMaterial.TURTLE_EGG, XMaterial.FROGSPAWN) + .stream() + .filter(XMaterial::isSupported) + .map(XMaterial::parseMaterial) + .collect(Collectors.toList()); + public StageBreed(StageController controller, EntityType entity, int amount) { super(controller, entity, amount); } @@ -28,6 +43,18 @@ public void onBreed(EntityBreedEvent e) { } } + @EventHandler + public void onEntityChangeBlock(EntityChangeBlockEvent e) { + if (!EGG_MATERIALS.contains(e.getBlock().getType())) + return; + if (!(e.getEntity() instanceof Animals)) + return; + Animals entity = (Animals) e.getEntity(); + Player breeder = Bukkit.getPlayer(entity.getBreedCause()); + if (breeder != null) + event(breeder, e.getEntityType()); + } + @Override public @NotNull String getDefaultDescription(@NotNull StageDescriptionPlaceholdersContext context) { return Lang.SCOREBOARD_BREED.toString(); From 98da1bb8b3d290019b30f56bf87f04f3d9dad0e8 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Wed, 13 Mar 2024 16:08:33 +0100 Subject: [PATCH 15/32] :bug: Fixed UnsupportedOperationException when setting custom quest item --- .../quests/api/gui/layout/LayoutedGUI.java | 6 +++-- .../api/options/UpdatableOptionSet.java | 25 +++++++++++-------- .../quests/options/OptionQuestItem.java | 25 +++++++++---------- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/gui/layout/LayoutedGUI.java b/api/src/main/java/fr/skytasul/quests/api/gui/layout/LayoutedGUI.java index c1cf952d..3f7d7909 100644 --- a/api/src/main/java/fr/skytasul/quests/api/gui/layout/LayoutedGUI.java +++ b/api/src/main/java/fr/skytasul/quests/api/gui/layout/LayoutedGUI.java @@ -42,8 +42,10 @@ public final void onClick(GuiClickEvent event) { if (button == null || !button.isValid()) return; - button.click(new LayoutedClickEvent(event.getPlayer(), this, event.getClicked(), event.getCursor(), event.getSlot(), - event.getClick())); + LayoutedClickEvent subEvent = new LayoutedClickEvent(event.getPlayer(), this, event.getClicked(), event.getCursor(), + event.getSlot(), event.getClick()); + button.click(subEvent); + event.setCancelled(subEvent.isCancelled()); } public void refresh(int slot) { diff --git a/api/src/main/java/fr/skytasul/quests/api/options/UpdatableOptionSet.java b/api/src/main/java/fr/skytasul/quests/api/options/UpdatableOptionSet.java index b4eb44bd..8b24ef61 100644 --- a/api/src/main/java/fr/skytasul/quests/api/options/UpdatableOptionSet.java +++ b/api/src/main/java/fr/skytasul/quests/api/options/UpdatableOptionSet.java @@ -4,32 +4,32 @@ @SuppressWarnings ("rawtypes") public class UpdatableOptionSet implements OptionSet { - + private Map>, OptionWrapper> options = new HashMap<>(); - + @Override public Iterator iterator() { return options.values().stream().map(wrapper -> wrapper.option).iterator(); } - + public void addOption(QuestOption option, Runnable update) { options.put((Class>) option.getClass(), new OptionWrapper(option, update)); } - + @Override public > T getOption(Class optionClass) { return (T) options.get(optionClass).option; } - + @Override public boolean hasOption(Class> clazz) { return options.containsKey(clazz); } - + public OptionWrapper getWrapper(Class> optionClass) { return options.get(optionClass); } - + public void calculateDependencies() { options.values().forEach(wrapper -> wrapper.dependent.clear()); for (OptionWrapper wrapper : options.values()) { @@ -38,17 +38,20 @@ public void calculateDependencies() { } } } - + public class OptionWrapper { public final QuestOption option; public final Runnable update; public final List dependent = new ArrayList<>(); - + public OptionWrapper(QuestOption option, Runnable update) { this.option = option; this.update = update; - option.setValueUpdaterListener(() -> dependent.forEach(Runnable::run)); + option.setValueUpdaterListener(() -> { + update.run(); + dependent.forEach(Runnable::run); + }); } } - + } diff --git a/core/src/main/java/fr/skytasul/quests/options/OptionQuestItem.java b/core/src/main/java/fr/skytasul/quests/options/OptionQuestItem.java index d83ad3f6..045f2727 100644 --- a/core/src/main/java/fr/skytasul/quests/options/OptionQuestItem.java +++ b/core/src/main/java/fr/skytasul/quests/options/OptionQuestItem.java @@ -14,7 +14,7 @@ import fr.skytasul.quests.utils.QuestUtils; public class OptionQuestItem extends QuestOption { - + @Override public void setValue(ItemStack value) { if (value == null || value.getType() == Material.AIR) { @@ -24,28 +24,28 @@ public void setValue(ItemStack value) { } super.setValue(value); } - + @Override public Object save() { return getValue(); } - + @Override public void load(ConfigurationSection config, String key) { setValue(config.isItemStack(key) ? config.getItemStack(key) : XMaterial.valueOf(config.getString(key)).parseItem()); } - + @Override public ItemStack cloneValue(ItemStack value) { return value.clone(); } - + private String[] getLore() { String description = formatDescription(Lang.customMaterialLore.toString()); if (!hasCustomValue()) return new String[] { description, "", Lang.defaultValue.toString() }; return new String[] { description }; } - + @Override public ItemStack getItemStack(OptionSet options) { return ItemUtils.nameAndLore(getValue().clone(), Lang.customMaterial.toString(), getLore()); @@ -54,10 +54,11 @@ public ItemStack getItemStack(OptionSet options) { @Override public void click(QuestCreationGuiClickEvent event) { if (event.hasCursor()) { - QuestUtils.runSync(() -> event.getPlayer().setItemOnCursor(null)); - setValue(event.getCursor()); - ItemUtils.nameAndLore(event.getCursor(), Lang.customMaterial.toString(), getLore()); - event.setCancelled(false); + ItemStack item = event.getCursor(); + QuestUtils.runSync(() -> { + setValue(item); + event.getPlayer().setItemOnCursor(null); + }); } else { Lang.QUEST_MATERIAL.send(event.getPlayer()); new TextEditor<>(event.getPlayer(), event::reopen, obj -> { @@ -66,18 +67,16 @@ public void click(QuestCreationGuiClickEvent event) { } else { setValue(obj.parseItem()); } - event.getGui().updateOptionItem(this); ItemStack setItem = event.getGui().getInventory().getItem(event.getSlot()); if (setItem == null || setItem.getType() == Material.AIR) { // means that the material cannot be treated as an inventory item (ex: fire) resetValue(); Lang.INVALID_ITEM_TYPE.send(event.getPlayer()); - event.getGui().updateOptionItem(this); } event.reopen(); }, QuestsPlugin.getPlugin().getEditorManager().getFactory().getMaterialParser(true, true)) .passNullIntoEndConsumer().start(); } } - + } From 0f139dc536f2943d2e0611698dbcb7bc8566ba51 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Wed, 13 Mar 2024 16:20:42 +0100 Subject: [PATCH 16/32] :bug: Fixed frogs and turtles again --- core/src/main/java/fr/skytasul/quests/stages/StageBreed.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageBreed.java b/core/src/main/java/fr/skytasul/quests/stages/StageBreed.java index 4cff6039..7f6b805e 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageBreed.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageBreed.java @@ -45,7 +45,7 @@ public void onBreed(EntityBreedEvent e) { @EventHandler public void onEntityChangeBlock(EntityChangeBlockEvent e) { - if (!EGG_MATERIALS.contains(e.getBlock().getType())) + if (!EGG_MATERIALS.contains(e.getTo())) return; if (!(e.getEntity() instanceof Animals)) return; From e35072411f4a8deab1587e167944347579d167ad Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sun, 17 Mar 2024 10:56:10 +0100 Subject: [PATCH 17/32] :bug: Fixed "done" button not being refreshed in Command GUI --- .../main/java/fr/skytasul/quests/gui/misc/CommandGUI.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/fr/skytasul/quests/gui/misc/CommandGUI.java b/core/src/main/java/fr/skytasul/quests/gui/misc/CommandGUI.java index ecae845b..974fa25e 100644 --- a/core/src/main/java/fr/skytasul/quests/gui/misc/CommandGUI.java +++ b/core/src/main/java/fr/skytasul/quests/gui/misc/CommandGUI.java @@ -2,6 +2,7 @@ import java.util.HashMap; import java.util.function.Consumer; +import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import fr.skytasul.quests.api.QuestsPlugin; @@ -32,7 +33,7 @@ public CommandGUI(Consumer end, Runnable cancel) { this.end = end; buttons.put(1, - doneButton = LayoutedButton.createLoreValue(XMaterial.COMMAND_BLOCK, Lang.commandValue.toString(), () -> cmd, + LayoutedButton.createLoreValue(XMaterial.COMMAND_BLOCK, Lang.commandValue.toString(), () -> cmd, this::commandClick)); buttons.put(3, LayoutedButton.create(() -> ItemUtils.itemSwitch(Lang.commandConsole.toString(), console), this::consoleClick)); @@ -40,8 +41,9 @@ public CommandGUI(Consumer end, Runnable cancel) { this::parseClick)); buttons.put(5, LayoutedButton.createLoreValue(XMaterial.CLOCK, Lang.commandDelay.toString(), () -> delay, this::delayClick)); - buttons.put(8, - LayoutedButton.create(() -> cmd == null ? QuestsPlugin.getPlugin().getGuiManager().getItemFactory().getNotDone() : QuestsPlugin.getPlugin().getGuiManager().getItemFactory().getDone(), this::doneClick)); + ItemStack notDone = QuestsPlugin.getPlugin().getGuiManager().getItemFactory().getNotDone(); + ItemStack done = QuestsPlugin.getPlugin().getGuiManager().getItemFactory().getDone(); + buttons.put(8, doneButton = LayoutedButton.create(() -> cmd == null ? notDone : done, this::doneClick)); } public CommandGUI setFromExistingCommand(@Nullable Command cmd) { From 02a31d305191cfa4391e3d554cb4c1e6d1ec7e13 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Mon, 18 Mar 2024 15:22:30 +0100 Subject: [PATCH 18/32] :bug: Fixed cast issues between ints and longs --- .../quests/api/stages/AbstractStage.java | 27 +++++++--- .../quests/api/stages/StageController.java | 8 +-- .../api/stages/types/AbstractEntityStage.java | 16 +++--- .../utils/CustomizedObjectTypeAdapter.java | 14 +++--- .../skytasul/quests/stages/StageBucket.java | 20 ++++---- .../fr/skytasul/quests/stages/StageCraft.java | 24 ++++----- .../quests/stages/StageDealDamage.java | 34 ++++++------- .../skytasul/quests/stages/StagePlayTime.java | 28 +++++------ .../StageControllerImplementation.java | 49 +++++++++++++------ 9 files changed, 126 insertions(+), 94 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/stages/AbstractStage.java b/api/src/main/java/fr/skytasul/quests/api/stages/AbstractStage.java index 396c4403..67daa6c0 100644 --- a/api/src/main/java/fr/skytasul/quests/api/stages/AbstractStage.java +++ b/api/src/main/java/fr/skytasul/quests/api/stages/AbstractStage.java @@ -1,12 +1,5 @@ package fr.skytasul.quests.api.stages; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import fr.skytasul.quests.api.QuestsConfiguration; import fr.skytasul.quests.api.players.PlayerAccount; import fr.skytasul.quests.api.players.PlayersManager; @@ -19,6 +12,13 @@ import fr.skytasul.quests.api.utils.AutoRegistered; import fr.skytasul.quests.api.utils.messaging.HasPlaceholders; import fr.skytasul.quests.api.utils.messaging.PlaceholderRegistry; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @AutoRegistered public abstract class AbstractStage implements HasPlaceholders { @@ -172,12 +172,23 @@ protected final void updateObjective(@NotNull Player p, @NotNull String dataKey, controller.updateObjective(p, dataKey, dataValue); } + @Deprecated protected final @Nullable T getData(@NotNull Player p, @NotNull String dataKey) { return getData(PlayersManager.getPlayerAccount(p), dataKey); } + @Deprecated protected final @Nullable T getData(@NotNull PlayerAccount acc, @NotNull String dataKey) { - return controller.getData(acc, dataKey); + return getData(acc, dataKey, null); + } + + protected final @Nullable T getData(@NotNull Player p, @NotNull String dataKey, @NotNull Class dataType) { + return getData(PlayersManager.getPlayerAccount(p), dataKey, dataType); + } + + protected final @Nullable T getData(@NotNull PlayerAccount acc, @NotNull String dataKey, + @NotNull Class dataType) { + return controller.getData(acc, dataKey, dataType); } /** diff --git a/api/src/main/java/fr/skytasul/quests/api/stages/StageController.java b/api/src/main/java/fr/skytasul/quests/api/stages/StageController.java index 5ee40504..bf0e365a 100644 --- a/api/src/main/java/fr/skytasul/quests/api/stages/StageController.java +++ b/api/src/main/java/fr/skytasul/quests/api/stages/StageController.java @@ -1,11 +1,11 @@ package fr.skytasul.quests.api.stages; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import fr.skytasul.quests.api.options.description.DescriptionSource; import fr.skytasul.quests.api.players.PlayerAccount; import fr.skytasul.quests.api.quests.branches.QuestBranch; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public interface StageController { @@ -23,7 +23,7 @@ public interface StageController { public @Nullable String getDescriptionLine(@NotNull PlayerAccount acc, @NotNull DescriptionSource source); - public @Nullable T getData(@NotNull PlayerAccount acc, @NotNull String dataKey); + public @Nullable T getData(@NotNull PlayerAccount acc, @NotNull String dataKey, @Nullable Class dataType); public @NotNull String getFlowId(); diff --git a/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractEntityStage.java b/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractEntityStage.java index 235c30fd..6a09c183 100644 --- a/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractEntityStage.java +++ b/api/src/main/java/fr/skytasul/quests/api/stages/types/AbstractEntityStage.java @@ -1,12 +1,5 @@ package fr.skytasul.quests.api.stages.types; -import java.util.*; -import java.util.Map.Entry; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import com.cryptomorin.xseries.XMaterial; import fr.skytasul.quests.api.QuestsPlugin; import fr.skytasul.quests.api.editors.TextEditor; @@ -26,6 +19,13 @@ import fr.skytasul.quests.api.utils.messaging.PlaceholderRegistry; import fr.skytasul.quests.api.utils.progress.ProgressPlaceholders; import fr.skytasul.quests.api.utils.progress.itemdescription.HasItemsDescriptionConfiguration.HasSingleObject; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.*; +import java.util.Map.Entry; @LocatableType (types = LocatedType.ENTITY) public abstract class AbstractEntityStage extends AbstractStage implements Locatable.MultipleLocatable, HasSingleObject { @@ -56,7 +56,7 @@ protected void event(@NotNull Player p, @NotNull EntityType type) { } protected @NotNull OptionalInt getPlayerAmountOptional(@NotNull PlayerAccount acc) { - Integer amount = getData(acc, "amount"); + Integer amount = getData(acc, "amount", Integer.class); return amount == null ? OptionalInt.empty() : OptionalInt.of(amount.intValue()); } diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/CustomizedObjectTypeAdapter.java b/api/src/main/java/fr/skytasul/quests/api/utils/CustomizedObjectTypeAdapter.java index f9463a4d..61a04ddd 100644 --- a/api/src/main/java/fr/skytasul/quests/api/utils/CustomizedObjectTypeAdapter.java +++ b/api/src/main/java/fr/skytasul/quests/api/utils/CustomizedObjectTypeAdapter.java @@ -1,9 +1,5 @@ package fr.skytasul.quests.api.utils; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.TypeAdapter; @@ -11,6 +7,10 @@ import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; public class CustomizedObjectTypeAdapter extends TypeAdapter { @@ -24,14 +24,16 @@ public static T deserializeNullable(String json, Class classOfT) { if (json == null) return null; return GSON.fromJson(json, classOfT); } - + public static String serializeNullable(Object object) { if (object == null) return null; return GSON.toJson(object); } - + private final TypeAdapter delegate = new Gson().getAdapter(Object.class); + private CustomizedObjectTypeAdapter() {} + @Override public void write(JsonWriter out, Object value) throws IOException { delegate.write(out, value); diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageBucket.java b/core/src/main/java/fr/skytasul/quests/stages/StageBucket.java index 5f2117d3..fcc6b2dd 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageBucket.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageBucket.java @@ -1,14 +1,5 @@ package fr.skytasul.quests.stages; -import java.util.Map; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerBucketFillEvent; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; import fr.skytasul.quests.api.QuestsConfiguration; import fr.skytasul.quests.api.editors.TextEditor; import fr.skytasul.quests.api.editors.parsers.NumberParser; @@ -30,6 +21,15 @@ import fr.skytasul.quests.api.utils.progress.itemdescription.HasItemsDescriptionConfiguration.HasSingleObject; import fr.skytasul.quests.api.utils.progress.itemdescription.ItemsDescriptionConfiguration; import fr.skytasul.quests.gui.misc.BucketTypeGUI; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerBucketFillEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import java.util.Map; public class StageBucket extends AbstractStage implements HasSingleObject, Listener { @@ -82,7 +82,7 @@ public void onBucketFill(PlayerBucketFillEvent e) { @Override public long getPlayerAmount(PlayerAccount acc) { - return getData(acc, "amount"); + return getData(acc, "amount", Long.class); } @Override diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageCraft.java b/core/src/main/java/fr/skytasul/quests/stages/StageCraft.java index 726c366d..e952bca7 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageCraft.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageCraft.java @@ -1,16 +1,5 @@ package fr.skytasul.quests.stages; -import java.util.Map; -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.FurnaceExtractEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; import fr.skytasul.quests.api.QuestsPlugin; import fr.skytasul.quests.api.comparison.ItemComparisonMap; import fr.skytasul.quests.api.events.internal.BQCraftEvent; @@ -31,6 +20,17 @@ import fr.skytasul.quests.api.utils.progress.ProgressPlaceholders; import fr.skytasul.quests.api.utils.progress.itemdescription.HasItemsDescriptionConfiguration.HasSingleObject; import fr.skytasul.quests.gui.items.ItemComparisonGUI; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.FurnaceExtractEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import java.util.Map; /** * @author SkytAsul, ezeiger92, TheBusyBiscuit @@ -132,7 +132,7 @@ public void initPlayerDatas(PlayerAccount acc, Map datas) { @Override public long getPlayerAmount(PlayerAccount acc) { - Long amount = getData(acc, "amount"); + Long amount = getData(acc, "amount", Long.class); return amount == null ? 0 : amount.longValue(); } diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageDealDamage.java b/core/src/main/java/fr/skytasul/quests/stages/StageDealDamage.java index 2a4bca6f..ba3cd680 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageDealDamage.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageDealDamage.java @@ -1,21 +1,5 @@ package fr.skytasul.quests.stages; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; -import org.bukkit.DyeColor; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.entity.Projectile; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.projectiles.ProjectileSource; -import org.jetbrains.annotations.NotNull; import fr.skytasul.quests.api.editors.TextEditor; import fr.skytasul.quests.api.editors.parsers.NumberParser; import fr.skytasul.quests.api.gui.ItemUtils; @@ -36,6 +20,22 @@ import fr.skytasul.quests.api.utils.progress.ProgressPlaceholders; import fr.skytasul.quests.gui.mobs.MobSelectionGUI; import fr.skytasul.quests.mobs.Mob; +import org.bukkit.DyeColor; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.projectiles.ProjectileSource; +import org.jetbrains.annotations.NotNull; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; @SuppressWarnings ("rawtypes") public class StageDealDamage extends AbstractStage implements HasProgress, Listener { @@ -84,7 +84,7 @@ public void onDamage(EntityDamageByEntityEvent event) { } public double getPlayerAmountDouble(@NotNull PlayerAccount account) { - return getData(account, "amount"); + return getData(account, "amount", Double.class); } @Override diff --git a/core/src/main/java/fr/skytasul/quests/stages/StagePlayTime.java b/core/src/main/java/fr/skytasul/quests/stages/StagePlayTime.java index 34307461..6997a375 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StagePlayTime.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StagePlayTime.java @@ -1,14 +1,5 @@ package fr.skytasul.quests.stages; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitTask; -import org.jetbrains.annotations.NotNull; import fr.skytasul.quests.BeautyQuests; import fr.skytasul.quests.api.QuestsPlugin; import fr.skytasul.quests.api.editors.TextEditor; @@ -32,6 +23,15 @@ import fr.skytasul.quests.api.utils.messaging.PlaceholdersContext.PlayerPlaceholdersContext; import fr.skytasul.quests.api.utils.progress.HasProgress; import fr.skytasul.quests.api.utils.progress.ProgressPlaceholders; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitTask; +import org.jetbrains.annotations.NotNull; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; public class StagePlayTime extends AbstractStage implements HasProgress { @@ -66,12 +66,12 @@ protected void createdPlaceholdersRegistry(@NotNull PlaceholderRegistry placehol private long getRemaining(PlayerAccount acc) { switch (timeMode) { case ONLINE: - long remaining = Utils.parseLong(getData(acc, "remainingTime")); - long lastJoin = Utils.parseLong(getData(acc, "lastJoin")); + long remaining = getData(acc, "remainingTime", Long.class); + long lastJoin = getData(acc, "lastJoin", Long.class); long playedTicks = (System.currentTimeMillis() - lastJoin) / 50; return remaining - playedTicks; case OFFLINE: - World world = Bukkit.getWorld(UUID.fromString(getData(acc, "worldUuid"))); + World world = Bukkit.getWorld(getData(acc, "worldUuid", UUID.class)); if (world == null) { QuestsPlugin.getPlugin().getLoggerExpanded().warning("Cannot get remaining time of " + acc.getNameAndID() + " for " + controller + " because the world has changed.", @@ -80,11 +80,11 @@ private long getRemaining(PlayerAccount acc) { return -1; } - long startTime = Utils.parseLong(getData(acc, "worldStartTime")); + long startTime = getData(acc, "worldStartTime", Long.class); long elapsedTicks = world.getGameTime() - startTime; return playTicks - elapsedTicks; case REALTIME: - startTime = Utils.parseLong(getData(acc, "startTime")); + startTime = getData(acc, "startTime", Long.class); elapsedTicks = (System.currentTimeMillis() - startTime) / 50; return playTicks - elapsedTicks; } diff --git a/core/src/main/java/fr/skytasul/quests/structure/StageControllerImplementation.java b/core/src/main/java/fr/skytasul/quests/structure/StageControllerImplementation.java index 03d047c1..0eeb7d78 100644 --- a/core/src/main/java/fr/skytasul/quests/structure/StageControllerImplementation.java +++ b/core/src/main/java/fr/skytasul/quests/structure/StageControllerImplementation.java @@ -1,18 +1,6 @@ package fr.skytasul.quests.structure; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.function.Consumer; -import org.bukkit.Bukkit; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import com.google.gson.JsonSyntaxException; import fr.skytasul.quests.BeautyQuests; import fr.skytasul.quests.api.QuestsAPI; import fr.skytasul.quests.api.QuestsPlugin; @@ -23,10 +11,24 @@ import fr.skytasul.quests.api.players.PlayerQuestDatas; import fr.skytasul.quests.api.players.PlayersManager; import fr.skytasul.quests.api.stages.*; +import fr.skytasul.quests.api.utils.CustomizedObjectTypeAdapter; import fr.skytasul.quests.api.utils.messaging.MessageType; import fr.skytasul.quests.api.utils.messaging.MessageUtils; import fr.skytasul.quests.utils.QuestUtils; import fr.skytasul.quests.utils.compatibility.BQBackwardCompat; +import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Consumer; public class StageControllerImplementation implements StageController, Listener { @@ -97,7 +99,7 @@ public void updateObjective(@NotNull Player player, @NotNull String dataKey, @Nu } @Override - public @Nullable D getData(@NotNull PlayerAccount acc, @NotNull String dataKey) { + public @Nullable D getData(@NotNull PlayerAccount acc, @NotNull String dataKey, @Nullable Class dataType) { PlayerQuestDatas playerDatas = acc.getQuestDatas(branch.getQuest()); Map datas = playerDatas.getStageDatas(getStorageId()); @@ -112,7 +114,24 @@ public void updateObjective(@NotNull Player player, @NotNull String dataKey, @Nu acc.getQuestDatas(branch.getQuest()).setStageDatas(getStorageId(), datas); } - return (D) datas.get(dataKey); + Object data = datas.get(dataKey); + if (dataType == null) // case when we do not have explicit data type to match for: we can only do direct cast + return (D) data; + + if (dataType.isInstance(data)) // easy: the data is directly compatible with the expected type + return dataType.cast(data); + + // hard: the data is not compatible. It may be because the deserialization process previously did + // not know the exact type to deserialize. Hence we go back to serialized to deserialize again, but + // this time with the correct type. + String serialized = CustomizedObjectTypeAdapter.serializeNullable(data); + try { + return CustomizedObjectTypeAdapter.deserializeNullable(serialized, dataType); + } catch (JsonSyntaxException ex) { + QuestsPlugin.getPlugin().getLoggerExpanded().severe( + "Cannot convert data " + dataKey + " to " + dataType.toString() + ". Serialized form: " + serialized); + throw ex; + } } @Override From 2539c7f7dc99d0096c8421325b9f464bceea1f92 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sat, 23 Mar 2024 22:31:26 +0100 Subject: [PATCH 19/32] :bug: Fixed pool start message not being sent to the command sender --- .../java/fr/skytasul/quests/commands/CommandsPools.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/fr/skytasul/quests/commands/CommandsPools.java b/core/src/main/java/fr/skytasul/quests/commands/CommandsPools.java index 47b92ab8..caae6a9e 100644 --- a/core/src/main/java/fr/skytasul/quests/commands/CommandsPools.java +++ b/core/src/main/java/fr/skytasul/quests/commands/CommandsPools.java @@ -1,6 +1,5 @@ package fr.skytasul.quests.commands; -import org.bukkit.entity.Player; import fr.skytasul.quests.api.QuestsPlugin; import fr.skytasul.quests.api.commands.revxrsal.annotation.Default; import fr.skytasul.quests.api.commands.revxrsal.annotation.Subcommand; @@ -15,6 +14,7 @@ import fr.skytasul.quests.api.pools.QuestPool; import fr.skytasul.quests.api.utils.messaging.PlaceholderRegistry; import fr.skytasul.quests.gui.pools.PoolsManageGUI; +import org.bukkit.entity.Player; public class CommandsPools implements OrphanCommand { @@ -49,8 +49,8 @@ public void start(BukkitCommandActor actor, EntitySelector players, Ques return; } - pool.give(player).thenAccept( - result -> Lang.POOL_START_SUCCESS.send(player, pool, acc, PlaceholderRegistry.of("result", result))); + pool.give(player).thenAccept(result -> Lang.POOL_START_SUCCESS.send(actor.getSender(), pool, acc, + PlaceholderRegistry.of("result", result))); } } From e46242dbd25c5b90a92c4d8929497c96e182bedd Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Fri, 5 Apr 2024 20:05:49 +0200 Subject: [PATCH 20/32] :bug: Fixed locale sometimes being completely reset ...when syntax errors in the player-edited locale file --- .../quests/api/localization/Locale.java | 79 +++++++++++-------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/localization/Locale.java b/api/src/main/java/fr/skytasul/quests/api/localization/Locale.java index 90810d9d..13266ded 100644 --- a/api/src/main/java/fr/skytasul/quests/api/localization/Locale.java +++ b/api/src/main/java/fr/skytasul/quests/api/localization/Locale.java @@ -1,5 +1,18 @@ package fr.skytasul.quests.api.localization; +import fr.skytasul.quests.api.QuestsPlugin; +import fr.skytasul.quests.api.utils.ChatColorUtils; +import fr.skytasul.quests.api.utils.Utils; +import fr.skytasul.quests.api.utils.messaging.HasPlaceholders; +import fr.skytasul.quests.api.utils.messaging.MessageType; +import fr.skytasul.quests.api.utils.messaging.MessageUtils; +import fr.skytasul.quests.api.utils.messaging.PlaceholderRegistry; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -10,19 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import fr.skytasul.quests.api.QuestsPlugin; -import fr.skytasul.quests.api.utils.ChatColorUtils; -import fr.skytasul.quests.api.utils.Utils; -import fr.skytasul.quests.api.utils.messaging.HasPlaceholders; -import fr.skytasul.quests.api.utils.messaging.MessageType; -import fr.skytasul.quests.api.utils.messaging.MessageUtils; -import fr.skytasul.quests.api.utils.messaging.PlaceholderRegistry; +import java.util.logging.Level; public interface Locale { @@ -72,10 +73,12 @@ default void quickSend(@NotNull CommandSender sender, @NotNull String key1, @Nul } public static void loadStrings(@NotNull Locale @NotNull [] locales, @NotNull YamlConfiguration defaultConfig, - @NotNull YamlConfiguration config) { + @Nullable YamlConfiguration config) { List missing = new ArrayList<>(); for (Locale l : locales) { - String value = config.getString(l.getPath(), null); + String value = null; + if (config != null) + value = config.getString(l.getPath(), null); if (value == null) { value = defaultConfig.getString(l.getPath(), null); missing.add(l.getPath()); @@ -85,7 +88,7 @@ public static void loadStrings(@NotNull Locale @NotNull [] locales, @NotNull Yam l.setValue(ChatColorUtils.translateHexColorCodes(ChatColor.translateAlternateColorCodes('&', value == null ? "§cunknown string" : value))); } - if (!missing.isEmpty()) { + if (config != null && !missing.isEmpty()) { QuestsPlugin.getPlugin().getLoggerExpanded() .warning("The file is not fully translated! " + missing.size() + " missing translations."); QuestsPlugin.getPlugin().getLoggerExpanded() @@ -116,27 +119,41 @@ public static YamlConfiguration loadLang(@NotNull Plugin plugin, @NotNull Locale res = plugin.getResource("locales/en_US.yml"); created = true; } - YamlConfiguration conf = YamlConfiguration.loadConfiguration(file); - boolean changes = false; - if (res != null) { // if it's a local resource - YamlConfiguration def = YamlConfiguration.loadConfiguration(new InputStreamReader(res, StandardCharsets.UTF_8)); - for (String key : def.getKeys(true)) { // get all keys in resource - if (!def.isConfigurationSection(key)) { // if not a block - if (!conf.contains(key)) { // if string does not exist in the file - conf.set(key, def.get(key)); // copy string - if (!created) QuestsPlugin.getPlugin().getLoggerExpanded().debug("String copied from source file to " + language + ". Key: " + key); - changes = true; + + YamlConfiguration def = null; + if (res != null) + def = YamlConfiguration.loadConfiguration(new InputStreamReader(res, StandardCharsets.UTF_8)); + + YamlConfiguration conf = new YamlConfiguration(); + try { + // we do NOT use YamlConfiguration#loadConfiguration because it swallows all exceptions + conf.load(file); + boolean changes = false; + if (def != null) { // if it's a local resource + for (String key : def.getKeys(true)) { // get all keys in resource + if (!def.isConfigurationSection(key)) { // if not a block + if (!conf.contains(key)) { // if string does not exist in the file + conf.set(key, def.get(key)); // copy string + if (!created) + QuestsPlugin.getPlugin().getLoggerExpanded() + .debug("String copied from source file to " + language + ". Key: " + key); + changes = true; + } } } } + if (changes) { + plugin.getLogger().info("Copied new strings into " + language + " language file."); + conf.save(file); // if there has been changes before, save the edited file + } + } catch (Exception ex) { + conf = def; + // the new configuration to load is the default one, or null if unknown language -> will only load + // default english + plugin.getLogger().log(Level.SEVERE, "Failed to load language file " + file, ex); } loadStrings(locales, YamlConfiguration.loadConfiguration(new InputStreamReader(plugin.getResource("locales/en_US.yml"), StandardCharsets.UTF_8)), conf); - if (changes) { - plugin.getLogger().info("Copied new strings into " + language + " language file."); - conf.save(file); // if there has been changes before, save the edited file - } - plugin.getLogger().info("Loaded language " + loadedLanguage + " (" + (((double) System.currentTimeMillis() - lastMillis) / 1000D) + "s)!"); return conf; } From a5d3f30a7351a0ff89ba08b0a1d266cfee384a4b Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sun, 14 Apr 2024 13:34:53 +0200 Subject: [PATCH 21/32] :technologist: Added "setPlayerStage", "setPlayerEndingStages" and "finishPlayerStage" in the QuestBranch API --- .../api/quests/branches/QuestBranch.java | 36 ++++++++- .../commands/CommandsPlayerManagement.java | 70 ++++++++--------- .../structure/QuestBranchImplementation.java | 75 ++++++++++--------- .../StageControllerImplementation.java | 2 +- .../placeholders/QuestsPlaceholders.java | 27 +++---- 5 files changed, 121 insertions(+), 89 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/quests/branches/QuestBranch.java b/api/src/main/java/fr/skytasul/quests/api/quests/branches/QuestBranch.java index 7d2f53c1..b7dc9a1c 100644 --- a/api/src/main/java/fr/skytasul/quests/api/quests/branches/QuestBranch.java +++ b/api/src/main/java/fr/skytasul/quests/api/quests/branches/QuestBranch.java @@ -1,13 +1,14 @@ package fr.skytasul.quests.api.quests.branches; -import java.util.List; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnmodifiableView; import fr.skytasul.quests.api.options.description.DescriptionSource; import fr.skytasul.quests.api.players.PlayerAccount; import fr.skytasul.quests.api.quests.Quest; import fr.skytasul.quests.api.stages.StageController; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnmodifiableView; +import java.util.List; public interface QuestBranch { @@ -33,4 +34,31 @@ default Quest getQuest() { public boolean hasStageLaunched(@Nullable PlayerAccount acc, @NotNull StageController stage); + /** + * Must be called when a player completes a stage. This causes the stage to end and the next one to + * begin, or the quest to finish if it was the last stage. + * + * @param p player which has completed the stage + * @param stage that the player just completed. If the player did not have this stage launched, the + * call will fail. + */ + void finishPlayerStage(@NotNull Player p, @NotNull StageController stage); + + /** + * Changes which stage the player is currently doing in the branch. If the player did not have + * already started a stage in this branch, an exception will be raised. + * + * @param acc player for which the running stage will be changed + * @param stage new stage to start + */ + void setPlayerStage(@NotNull PlayerAccount acc, @NotNull StageController stage); + + /** + * Similar to {@link #setPlayerStage(PlayerAccount, StageController)} but with ending stages instead + * of a regular stage. + * + * @param acc player for which the ending stages will start + */ + void setPlayerEndingStages(@NotNull PlayerAccount acc); + } diff --git a/core/src/main/java/fr/skytasul/quests/commands/CommandsPlayerManagement.java b/core/src/main/java/fr/skytasul/quests/commands/CommandsPlayerManagement.java index 8b6fb81e..9e1828a1 100644 --- a/core/src/main/java/fr/skytasul/quests/commands/CommandsPlayerManagement.java +++ b/core/src/main/java/fr/skytasul/quests/commands/CommandsPlayerManagement.java @@ -1,15 +1,5 @@ package fr.skytasul.quests.commands; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import fr.skytasul.quests.BeautyQuests; import fr.skytasul.quests.api.QuestsAPI; import fr.skytasul.quests.api.QuestsPlugin; @@ -47,12 +37,22 @@ import fr.skytasul.quests.structure.EndingStageImplementation; import fr.skytasul.quests.structure.QuestBranchImplementation; import fr.skytasul.quests.utils.QuestUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.permissions.Permission; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; public class CommandsPlayerManagement implements OrphanCommand { - + private BukkitCommandPermission startOtherPermission = new BukkitCommandPermission(new Permission("beautyquests.command.start.other")); private BukkitCommandPermission cancelOtherPermission = new BukkitCommandPermission(new Permission("beautyquests.command.cancel.other")); - + @Subcommand ("finishAll") @CommandPermission ("beautyquests.command.finish") public void finishAll(BukkitCommandActor actor, EntitySelector players) { @@ -73,7 +73,7 @@ public void finishAll(BukkitCommandActor actor, EntitySelector players) Lang.LEAVE_ALL_RESULT.send(actor.getSender(), PlaceholderRegistry.of("success", success, "errors", errors)); } } - + @Subcommand ("finish") @CommandPermission ("beautyquests.command.finish") public void finish(BukkitCommandActor actor, EntitySelector players, Quest quest, @Switch boolean force) { @@ -90,7 +90,7 @@ public void finish(BukkitCommandActor actor, EntitySelector players, Que } } } - + @Subcommand ("setStage") @CommandPermission ("beautyquests.command.setStage") public void setStage( @@ -102,7 +102,7 @@ public void setStage( // syntax: no arg: next or start | 1 arg: start branch | 2 args: set branch stage PlayerAccount acc = PlayersManager.getPlayerAccount(player); BranchesManagerImplementation manager = (BranchesManagerImplementation) quest.getBranchesManager(); - + PlayerQuestDatas datas = acc.getQuestDatasIfPresent(quest); if (branchID == null && (datas == null || !datas.hasStarted())) { // start quest quest.start(player); @@ -110,19 +110,19 @@ public void setStage( return; } if (datas == null) datas = acc.getQuestDatas(quest); // creates quest datas - + QuestBranchImplementation currentBranch = manager.getBranch(datas.getBranch()); - + if (branchID == null) { // next if (!datas.isInEndingStages()) { - currentBranch.finishStage(player, currentBranch.getRegularStage(datas.getStage())); + currentBranch.finishPlayerStage(player, currentBranch.getRegularStage(datas.getStage())); Lang.COMMAND_SETSTAGE_NEXT.send(actor.getSender()); }else Lang.COMMAND_SETSTAGE_NEXT_UNAVAILABLE.send(actor.getSender()); }else { QuestBranchImplementation branch = manager.getBranch(branchID); if (branch == null) throw new CommandErrorException(Lang.COMMAND_SETSTAGE_BRANCH_DOESNTEXIST.quickFormat("branch_id", branchID)); - + if (stageID != null) { if (currentBranch == null) throw new CommandErrorException( @@ -144,18 +144,18 @@ public void setStage( branch.start(acc); }else { // set stage in branch datas.setBranch(branchID); - branch.setStage(acc, stageID); + branch.setPlayerStage(acc, branch.getRegularStage(stageID)); } QuestsAPI.getAPI().propagateQuestsHandlers(handler -> handler.questUpdated(acc, quest)); } } - + @Subcommand ("startDialog") @CommandPermission ("beautyquests.command.setStage") public void startDialog(BukkitCommandActor actor, Player player, Quest quest) { PlayerAccount acc = PlayersManager.getPlayerAccount(player); PlayerQuestDatas datas = acc.getQuestDatasIfPresent(quest); - + DialogRunner runner = null; if (datas == null || !quest.hasStarted(acc)) { if (quest.hasOption(OptionStartDialog.class)) { @@ -173,7 +173,7 @@ public void startDialog(BukkitCommandActor actor, Player player, Quest quest) { } } } - + if (runner == null) { Lang.COMMAND_STARTDIALOG_NO.send(actor.getSender()); }else { @@ -185,7 +185,7 @@ public void startDialog(BukkitCommandActor actor, Player player, Quest quest) { } } } - + @Subcommand ("resetPlayer") @CommandPermission ("beautyquests.command.resetPlayer") public void resetPlayer(BukkitCommandActor actor, EntitySelector players) { @@ -233,7 +233,7 @@ public void resetPlayer(BukkitCommandActor actor, EntitySelector players } } - + @Subcommand ("resetPlayerQuest") @CommandPermission ("beautyquests.command.resetPlayer") public void resetPlayerQuest(BukkitCommandActor actor, Player player, @Optional Quest quest) { @@ -245,7 +245,7 @@ public void resetPlayerQuest(BukkitCommandActor actor, Player player, @Optional }, PlayersManager.getPlayerAccount(player), true, false, true).open(actor.requirePlayer()); } } - + private void reset(CommandSender sender, Player target, Quest qu) { PlayerAccount acc = PlayersManager.getPlayerAccount(target); qu.resetPlayer(acc).whenComplete(QuestsPlugin.getPlugin().getLoggerExpanded().logError(__ -> { @@ -255,7 +255,7 @@ private void reset(CommandSender sender, Player target, Quest qu) { Lang.DATA_QUEST_REMOVED_INFO.send(sender, acc, qu); }, "An error occurred while removing player quest data", sender)); } - + @Subcommand ("resetQuest") @CommandPermission ("beautyquests.command.resetQuest") public void resetQuest(BukkitCommandActor actor, Quest quest) { @@ -291,13 +291,13 @@ public void resetQuest(BukkitCommandActor actor, Quest quest) { }).whenComplete(QuestsPlugin.getPlugin().getLoggerExpanded().logError()); } - + @Subcommand ("seePlayer") @CommandPermission ("beautyquests.command.seePlayer") public void seePlayer(Player actor, Player player) { new PlayerListGUI(BeautyQuests.getInstance().getPlayersManager().getAccount(player), false).open(actor); } - + @Subcommand ("start") @CommandPermission ("beautyquests.command.start") public void start(BukkitCommandActor actor, ExecutableCommand command, EntitySelector players, @@ -307,7 +307,7 @@ public void start(BukkitCommandActor actor, ExecutableCommand command, EntitySel if (players.isEmpty() || players.size() > 1 || (players.get(0) != actor.getAsPlayer())) throw new NoPermissionException(command, startOtherPermission); } - + for (Player player : players) { if (quest == null) { new QuestsListGUI(obj -> { @@ -328,7 +328,7 @@ private void start(CommandSender sender, Player player, Quest quest, boolean ove quest.start(player); Lang.START_QUEST.send(sender, quest, acc); } - + @Subcommand ("cancel") @CommandPermission ("beautyquests.command.cancel") public void cancel(BukkitCommandActor actor, ExecutableCommand command, EntitySelector players, @@ -337,10 +337,10 @@ public void cancel(BukkitCommandActor actor, ExecutableCommand command, EntitySe if (players.isEmpty() || players.size() > 1 || (players.get(0) != actor.getAsPlayer())) throw new NoPermissionException(command, cancelOtherPermission); } - + for (Player player : players) { PlayerAccount acc = PlayersManager.getPlayerAccount(player); - + if (quest == null) { new QuestsListGUI(obj -> { cancel(actor.getSender(), acc, obj); @@ -350,7 +350,7 @@ public void cancel(BukkitCommandActor actor, ExecutableCommand command, EntitySe } } } - + private void cancel(CommandSender sender, PlayerAccount acc, Quest quest) { if (!quest.isCancellable()) { Lang.CANCEL_QUEST_UNAVAILABLE.send(sender, quest); @@ -368,5 +368,5 @@ private void cancel(CommandSender sender, PlayerAccount acc, Quest quest) { } } } - + } diff --git a/core/src/main/java/fr/skytasul/quests/structure/QuestBranchImplementation.java b/core/src/main/java/fr/skytasul/quests/structure/QuestBranchImplementation.java index 4fe2ed87..1e1f7c41 100644 --- a/core/src/main/java/fr/skytasul/quests/structure/QuestBranchImplementation.java +++ b/core/src/main/java/fr/skytasul/quests/structure/QuestBranchImplementation.java @@ -1,14 +1,5 @@ package fr.skytasul.quests.structure; -import java.util.*; -import java.util.stream.Collectors; -import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnmodifiableView; import fr.skytasul.quests.QuestsConfigurationImplementation; import fr.skytasul.quests.api.QuestsConfiguration; import fr.skytasul.quests.api.QuestsPlugin; @@ -29,6 +20,15 @@ import fr.skytasul.quests.players.AdminMode; import fr.skytasul.quests.utils.DebugUtils; import fr.skytasul.quests.utils.QuestUtils; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnmodifiableView; +import java.util.*; +import java.util.stream.Collectors; public class QuestBranchImplementation implements QuestBranch { @@ -173,13 +173,14 @@ public void remove(@NotNull PlayerAccount acc, boolean end) { public void start(@NotNull PlayerAccount acc) { acc.getQuestDatas(getQuest()).setBranch(getId()); if (!regularStages.isEmpty()){ - setStage(acc, 0); + setPlayerStage(acc, regularStages.get(0)); }else { - setEndingStages(acc, true); + setPlayerEndingStages(acc); } } - public void finishStage(@NotNull Player p, @NotNull StageControllerImplementation stage) { + @Override + public void finishPlayerStage(@NotNull Player p, @NotNull StageController stage) { QuestsPlugin.getPlugin().getLoggerExpanded().debug("Next stage for player " + p.getName() + " (coming from " + stage.toString() + ") via " + DebugUtils.stackTraces(1, 3)); PlayerAccount acc = PlayersManager.getPlayerAccount(p); @NotNull @@ -200,7 +201,7 @@ public void finishStage(@NotNull Player p, @NotNull StageControllerImplementatio } } datas.setStage(-1); - endStage(acc, stage, () -> { + endStage(acc, (StageControllerImplementation) stage, () -> { if (!manager.getQuest().hasStarted(acc)) return; if (regularStages.contains(stage)){ // not ending stage - continue the branch or finish the quest int newId = getRegularStageId(stage) + 1; @@ -210,9 +211,9 @@ public void finishStage(@NotNull Player p, @NotNull StageControllerImplementatio getQuest().finish(p); return; } - setEndingStages(acc, true); + setPlayerEndingStages(acc); }else { - setStage(acc, newId); + setPlayerStage(acc, regularStages.get(newId)); } }else { // ending stage - redirect to other branch remove(acc, false); @@ -275,37 +276,39 @@ private void endStage(@NotNull PlayerAccount acc, @NotNull StageControllerImplem } } - public void setStage(@NotNull PlayerAccount acc, int id) { - StageControllerImplementation stage = regularStages.get(id); + @Override + public void setPlayerStage(@NotNull PlayerAccount acc, @NotNull StageController stage) { Player p = acc.getPlayer(); - if (stage == null){ - if (p != null) - DefaultErrors.sendGeneric(p, " noStage"); - QuestsPlugin.getPlugin().getLoggerExpanded().severe("Error into the StageManager of quest " + getQuest().getName() + " : the stage " + id + " doesn't exists."); - remove(acc, true); - }else { - PlayerQuestDatas questDatas = acc.getQuestDatas(getQuest()); - if (QuestsConfiguration.getConfig().getQuestsConfig().playerQuestUpdateMessage() && p != null - && questDatas.getStage() != -1) - Lang.QUEST_UPDATED.send(p, getQuest()); - questDatas.setStage(id); - if (p != null) playNextStage(p); - stage.start(acc); - Bukkit.getPluginManager().callEvent(new PlayerSetStageEvent(acc, getQuest(), stage)); - } + PlayerQuestDatas questDatas = acc.getQuestDatas(getQuest()); + if (questDatas.getBranch() != getId()) + throw new IllegalStateException("The player is not in the right branch"); + + if (QuestsConfiguration.getConfig().getQuestsConfig().playerQuestUpdateMessage() && p != null + && questDatas.getStage() != -1) + Lang.QUEST_UPDATED.send(p, getQuest()); + questDatas.setStage(getRegularStageId(stage)); + if (p != null) + playNextStage(p); + ((StageControllerImplementation) stage).start(acc); + Bukkit.getPluginManager().callEvent(new PlayerSetStageEvent(acc, getQuest(), stage)); } - public void setEndingStages(@NotNull PlayerAccount acc, boolean launchStage) { + @Override + public void setPlayerEndingStages(@NotNull PlayerAccount acc) { Player p = acc.getPlayer(); - if (QuestsConfiguration.getConfig().getQuestsConfig().playerQuestUpdateMessage() && p != null && launchStage) - Lang.QUEST_UPDATED.send(p, getQuest()); PlayerQuestDatas datas = acc.getQuestDatas(getQuest()); + if (datas.getBranch() != getId()) + throw new IllegalStateException("The player is not in the right branch"); + + if (QuestsConfiguration.getConfig().getQuestsConfig().playerQuestUpdateMessage() && p != null) + Lang.QUEST_UPDATED.send(p, getQuest()); datas.setInEndingStages(); for (EndingStageImplementation endStage : endStages) { endStage.getStage().start(acc); Bukkit.getPluginManager().callEvent(new PlayerSetStageEvent(acc, getQuest(), endStage.getStage())); } - if (p != null && launchStage) playNextStage(p); + if (p != null) + playNextStage(p); } private void playNextStage(@NotNull Player p) { diff --git a/core/src/main/java/fr/skytasul/quests/structure/StageControllerImplementation.java b/core/src/main/java/fr/skytasul/quests/structure/StageControllerImplementation.java index 0eeb7d78..35610a0c 100644 --- a/core/src/main/java/fr/skytasul/quests/structure/StageControllerImplementation.java +++ b/core/src/main/java/fr/skytasul/quests/structure/StageControllerImplementation.java @@ -72,7 +72,7 @@ public void setStage(@NotNull T stage) { @Override public void finishStage(@NotNull Player player) { - QuestUtils.runSync(() -> branch.finishStage(player, this)); + QuestUtils.runSync(() -> branch.finishPlayerStage(player, this)); } @Override diff --git a/integrations/src/main/java/fr/skytasul/quests/integrations/placeholders/QuestsPlaceholders.java b/integrations/src/main/java/fr/skytasul/quests/integrations/placeholders/QuestsPlaceholders.java index 43721706..d1e81bd5 100644 --- a/integrations/src/main/java/fr/skytasul/quests/integrations/placeholders/QuestsPlaceholders.java +++ b/integrations/src/main/java/fr/skytasul/quests/integrations/placeholders/QuestsPlaceholders.java @@ -1,17 +1,5 @@ package fr.skytasul.quests.integrations.placeholders; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Consumer; -import java.util.stream.Collectors; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.scheduler.BukkitTask; import fr.skytasul.quests.api.QuestsAPI; import fr.skytasul.quests.api.QuestsPlugin; import fr.skytasul.quests.api.localization.Lang; @@ -23,6 +11,18 @@ import fr.skytasul.quests.api.utils.ChatColorUtils; import me.clip.placeholderapi.events.ExpansionRegisterEvent; import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.scheduler.BukkitTask; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Consumer; +import java.util.stream.Collectors; public class QuestsPlaceholders extends PlaceholderExpansion implements Listener { @@ -183,7 +183,8 @@ public String onRequest(OfflinePlayer off, String identifier) { return "§c" + ex.getMessage(); } }catch (Exception ex) { - QuestsPlugin.getPlugin().getLoggerExpanded().warning("An error occurred while parsing palceholder " + identifier + " for " + p.getName(), ex); + QuestsPlugin.getPlugin().getLoggerExpanded().warning( + "An error occurred while parsing placeholder " + identifier + " for " + p.getName(), ex); return "§cinvalid placeholder"; } }finally { From 273b26721869830f7efb05d246d8a013adb95c91 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sat, 4 May 2024 11:54:12 +0200 Subject: [PATCH 22/32] :bug: Fix "bring xxx" message wrongly numbered --- .../fr/skytasul/quests/stages/StageBringBack.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java b/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java index cdb34904..39668274 100644 --- a/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java +++ b/core/src/main/java/fr/skytasul/quests/stages/StageBringBack.java @@ -1,11 +1,5 @@ package fr.skytasul.quests.stages; -import java.util.*; -import java.util.Map.Entry; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; import fr.skytasul.quests.api.QuestsConfiguration; import fr.skytasul.quests.api.comparison.ItemComparisonMap; import fr.skytasul.quests.api.editors.TextEditor; @@ -29,6 +23,12 @@ import fr.skytasul.quests.api.utils.progress.itemdescription.HasItemsDescriptionConfiguration.HasSingleObject; import fr.skytasul.quests.gui.items.ItemComparisonGUI; import fr.skytasul.quests.gui.items.ItemsGUI; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import java.util.*; +import java.util.Map.Entry; public class StageBringBack extends StageNPC{ @@ -70,7 +70,7 @@ public void sendNeedMessage(Player p) { return; Message msg = new Message(MessageUtils.format(text, getPlaceholdersRegistry(), StageDescriptionPlaceholdersContext .of(true, PlayersManager.getPlayerAccount(p), DescriptionSource.FORCELINE, null)), Sender.NPC); - msg.sendMessage(p, getNPC(), getNpcName(), 1, 1); + msg.sendMessage(p, getNPC(), getNpcName(), 0, 1); } public void removeItems(Player p){ From 807cb3f1c70315e7f38eb11d31af3ce3690a1020 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sun, 5 May 2024 11:54:49 +0200 Subject: [PATCH 23/32] :arrow_up: Added support for MC 1.20.5/6 --- api/pom.xml | 4 +- .../fr/skytasul/quests/api/gui/ItemUtils.java | 55 +++++-- .../quests/api/utils/MinecraftNames.java | 146 ++++-------------- .../quests/api/utils/MinecraftVersion.java | 10 ++ .../quests/api/utils/PotionMapping.java | 117 ++++++++++++++ .../fr/skytasul/quests/api/utils/Utils.java | 67 +++++--- core/pom.xml | 2 +- .../QuestsConfigurationImplementation.java | 26 ++-- .../quests/gui/DefaultItemFactory.java | 8 +- .../quests/gui/blocks/SelectBlockGUI.java | 27 ++-- .../quests/gui/quests/DialogHistoryGUI.java | 31 ++-- .../quests/gui/quests/PlayerListGUI.java | 38 ++--- .../fr/skytasul/quests/players/AdminMode.java | 31 ++-- .../skytasul/quests/utils/ParticleEffect.java | 15 +- core/src/main/resources/config.yml | 6 +- dist/pom.xml | 7 + pom.xml | 3 +- v1_20_R4/pom.xml | 83 ++++++++++ .../skytasul/quests/utils/nms/v1_20_R4.java | 49 ++++++ 19 files changed, 476 insertions(+), 249 deletions(-) create mode 100755 api/src/main/java/fr/skytasul/quests/api/utils/PotionMapping.java create mode 100755 v1_20_R4/pom.xml create mode 100755 v1_20_R4/src/main/java/fr/skytasul/quests/utils/nms/v1_20_R4.java diff --git a/api/pom.xml b/api/pom.xml index 13722b3d..f1b905c0 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -40,7 +40,7 @@ com/cryptomorin/xseries/XMaterial* com/cryptomorin/xseries/XBlock* - com/cryptomorin/xseries/XPotion* + com/cryptomorin/xseries/XEnchantment* @@ -152,7 +152,7 @@ com.github.cryptomorin XSeries - 9.8.0 + 9.10.0 diff --git a/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java b/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java index 3f2486c5..323d69da 100644 --- a/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java +++ b/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java @@ -1,9 +1,12 @@ package fr.skytasul.quests.api.gui; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import com.cryptomorin.xseries.XMaterial; +import fr.skytasul.quests.api.QuestsPlugin; +import fr.skytasul.quests.api.options.QuestOption; +import fr.skytasul.quests.api.utils.ChatColorUtils; +import fr.skytasul.quests.api.utils.MinecraftNames; +import fr.skytasul.quests.api.utils.MinecraftVersion; +import fr.skytasul.quests.api.utils.Utils; import org.apache.commons.lang.Validate; import org.bukkit.DyeColor; import org.bukkit.enchantments.Enchantment; @@ -11,12 +14,10 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.*; import org.jetbrains.annotations.Nullable; -import com.cryptomorin.xseries.XMaterial; -import fr.skytasul.quests.api.QuestsPlugin; -import fr.skytasul.quests.api.options.QuestOption; -import fr.skytasul.quests.api.utils.ChatColorUtils; -import fr.skytasul.quests.api.utils.MinecraftNames; -import fr.skytasul.quests.api.utils.MinecraftVersion; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; public final class ItemUtils { @@ -139,11 +140,17 @@ public static ItemStack clearVisibleAttributes(ItemStack is) { // add flags to hide various descriptions, // depending on the item type/attributes/other things - if (im.hasEnchants()) im.addItemFlags(ItemFlag.HIDE_ENCHANTS); - if (MinecraftVersion.MAJOR >= 11 && im.isUnbreakable()) im.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); - if (is.getType().getMaxDurability() != 0 || (MinecraftVersion.MAJOR > 12 && im.hasAttributeModifiers())) im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); - if (im instanceof BookMeta || im instanceof PotionMeta || im instanceof EnchantmentStorageMeta || (MinecraftVersion.MAJOR >= 12 && im instanceof KnowledgeBookMeta)) im.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS); - if (im instanceof LeatherArmorMeta) im.addItemFlags(ItemFlag.HIDE_DYE); + if (im.hasEnchants()) + im.addItemFlags(ItemFlag.HIDE_ENCHANTS); + if (MinecraftVersion.MAJOR >= 11 && im.isUnbreakable()) + im.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); + if (is.getType().getMaxDurability() != 0 || (MinecraftVersion.MAJOR > 12 && im.hasAttributeModifiers())) + im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + if (im instanceof BookMeta || im instanceof PotionMeta || im instanceof EnchantmentStorageMeta + || (MinecraftVersion.MAJOR >= 12 && im instanceof KnowledgeBookMeta)) + im.addItemFlags(Utils.valueOfEnum(ItemFlag.class, "HIDE_POTION_EFFECTS", "HIDE_ADDITIONAL_TOOLTIP")); + if (im instanceof LeatherArmorMeta) + im.addItemFlags(ItemFlag.HIDE_DYE); is.setItemMeta(im); return is; @@ -314,6 +321,24 @@ public static ItemStack removeEnchant(ItemStack is, Enchantment en){ return is; } + public static boolean isGlittering(ItemStack is) { + ItemMeta im = is.getItemMeta(); + return (MinecraftVersion.isHigherThan(20, 6) && im.hasEnchantmentGlintOverride() && im.getEnchantmentGlintOverride()) + || im.hasEnchants(); + } + + public static void setGlittering(ItemStack is, boolean glitter) { + ItemMeta im = is.getItemMeta(); + if (MinecraftVersion.isHigherThan(20, 6)) { + im.setEnchantmentGlintOverride(glitter ? Boolean.TRUE : null); + } else { + if (glitter) + im.addEnchant(Enchantment.getByName("DURABILITY"), 0, true); + else + im.removeEnchant(Enchantment.getByName("DURABILITY")); + } + } + /** * Get a glass pane ItemStack instance with the color wanted * @param color DyeColor wanted diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftNames.java b/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftNames.java index 632de31a..b336f138 100644 --- a/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftNames.java +++ b/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftNames.java @@ -1,34 +1,29 @@ package fr.skytasul.quests.api.utils; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; +import com.cryptomorin.xseries.XMaterial; +import com.google.gson.GsonBuilder; +import fr.skytasul.quests.api.QuestsPlugin; import org.apache.commons.lang.WordUtils; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.potion.PotionData; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import com.cryptomorin.xseries.XMaterial; -import com.cryptomorin.xseries.XPotion; -import com.google.gson.GsonBuilder; -import fr.skytasul.quests.api.QuestsPlugin; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.Map.Entry; public class MinecraftNames { - + public static final String LANG_DOWNLOAD_URL = "https://github.com/InventivetalentDev/minecraft-assets/raw/%version%/assets/minecraft/lang/%language%.json"; - + private static Map map; - + private static Map cachedEntities = new HashMap<>(); private static Map cachedMaterials = new HashMap<>(); - + public static boolean intialize(@NotNull Path path) { try { if (!Files.exists(path)) { @@ -36,27 +31,29 @@ public static boolean intialize(@NotNull Path path) { .warning("File " + path.getFileName() + " not found for translations."); return false; } - + map = new GsonBuilder().create().fromJson(Files.newBufferedReader(path, StandardCharsets.UTF_8), HashMap.class); QuestsPlugin.getPlugin().getLoggerExpanded().info("Loaded vanilla translation file for language: " + map.get("language.name") + ". Sorting values."); for (Entry en : map.entrySet()) { String key = en.getKey(); + String value = (String) en.getValue(); if (key.startsWith("entity.minecraft.")) { - cachedEntities.put(EntityType.fromName(key.substring(17)), (String) en.getValue()); + cachedEntities.put(EntityType.fromName(key.substring(17)), value); }else if (key.startsWith("block.minecraft.")) { - cachedMaterials.put(XMaterial.matchXMaterial(key.substring(16)).orElse(null), (String) en.getValue()); + cachedMaterials.put(XMaterial.matchXMaterial(key.substring(16)).orElse(null), value); }else if (key.startsWith("item.minecraft.")) { String item = key.substring(15); if (item.startsWith("potion.effect.")) { - PotionMapping potion = PotionMapping.matchFromTranslationKey(item.substring(14)); - if (potion != null) potion.normal = (String) en.getValue(); + PotionMapping.matchFromTranslationKey(item.substring(14)) + .forEachRemaining(potion -> potion.setNormalName(value)); }else if (item.startsWith("splash_potion.effect.")) { - PotionMapping potion = PotionMapping.matchFromTranslationKey(item.substring(21)); - if (potion != null) potion.splash = (String) en.getValue(); + PotionMapping.matchFromTranslationKey(item.substring(21)) + .forEachRemaining(potion -> potion.setSplashName(value)); }else if (item.startsWith("lingering_potion.effect.")) { - PotionMapping potion = PotionMapping.matchFromTranslationKey(item.substring(24)); - if (potion != null) potion.lingering = (String) en.getValue(); - }else cachedMaterials.put(XMaterial.matchXMaterial(item).orElse(null), (String) en.getValue()); + PotionMapping.matchFromTranslationKey(item.substring(24)) + .forEachRemaining(potion -> potion.setLingeringName(value)); + } else + cachedMaterials.put(XMaterial.matchXMaterial(item).orElse(null), value); } } }catch (Exception e) { @@ -64,11 +61,11 @@ public static boolean intialize(@NotNull Path path) { } return true; } - + public static @Nullable Object getRaw(@Nullable String path) { return map.get(path); } - + public static @NotNull String getEntityName(@NotNull EntityType type) { String defaultName = type.getName(); if (defaultName == null) defaultName = type.name(); @@ -77,23 +74,14 @@ public static boolean intialize(@NotNull Path path) { if (name == null) return defaultFormat(defaultName); return name; } - + public static @NotNull String getMaterialName(ItemStack item) { XMaterial type = XMaterial.matchXMaterial(item); - if (MinecraftVersion.MAJOR > 8 + if (MinecraftVersion.isHigherThan(20, 2) && (type == XMaterial.POTION || type == XMaterial.LINGERING_POTION || type == XMaterial.SPLASH_POTION)) { PotionMeta meta = (PotionMeta) item.getItemMeta(); - try { - PotionData basePotion = meta.getBasePotionData(); - PotionMapping mapping = basePotion.getType().name().equals("TURTLE_MASTER") ? PotionMapping.TURTLE_MASTER - : PotionMapping.matchFromXPotion(XPotion.matchXPotion(basePotion.getType().getEffectType())); - String string = mapping.getTranslated(type); - if (basePotion.isUpgraded()) { - string += " II" + mapping.strongDuration; - } else if (mapping.baseDuration != null) - string += basePotion.isExtended() ? mapping.extendedDuration : mapping.baseDuration; - return string; - }catch (NullPointerException ex) {} // happens with potions with no effect + if (meta.getBasePotionType() != null) + return PotionMapping.matchFromPotionType(meta.getBasePotionType()).getTranslated(type); } return getMaterialName(type); } @@ -104,81 +92,9 @@ public static boolean intialize(@NotNull Path path) { if (name == null) return defaultFormat(type.name()); return name; } - + public static @NotNull String defaultFormat(@NotNull String value) { return WordUtils.capitalize(value.toLowerCase().replace('_', ' ')); } - - private static class PotionMapping { - - private static final List MAPPINGS = new ArrayList<>(); - public static final PotionMapping TURTLE_MASTER; - - static { - MAPPINGS.add(new PotionMapping(XPotion.FIRE_RESISTANCE, "fire_resistance", 3600, 9600, -1)); - MAPPINGS.add(new PotionMapping(XPotion.HARM, "harming", -1, -1, -1)); - MAPPINGS.add(new PotionMapping(XPotion.HEAL, "healing", -1, -1, -1)); - MAPPINGS.add(new PotionMapping(XPotion.INCREASE_DAMAGE, "strength", 3600, 9600, 1800)); - MAPPINGS.add(new PotionMapping(XPotion.INVISIBILITY, "invisibility", 3600, 9600, -1)); - MAPPINGS.add(new PotionMapping(XPotion.JUMP, "leaping", 3600, 9600, 1800)); - MAPPINGS.add(new PotionMapping(XPotion.LEVITATION, "levitation", -1, -1, -1)); - MAPPINGS.add(new PotionMapping(XPotion.LUCK, "luck", 6000, -1, -1)); - MAPPINGS.add(new PotionMapping(XPotion.NIGHT_VISION, "night_vision", 3600, 9600, -1)); - MAPPINGS.add(new PotionMapping(XPotion.POISON, "poison", 900, 1800, 432)); - MAPPINGS.add(new PotionMapping(XPotion.REGENERATION, "regeneration", 900, 1800, 450)); - MAPPINGS.add(new PotionMapping(XPotion.SLOW, "slowness", 1800, 4800, 400)); - MAPPINGS.add(new PotionMapping(XPotion.SLOW_FALLING, "slow_falling", 1800, 4800, -1)); - MAPPINGS.add(new PotionMapping(XPotion.SPEED, "swiftness", 3600, 9600, 1800)); - MAPPINGS.add(new PotionMapping(XPotion.WATER_BREATHING, "water_breathing", 3600, 9600, -1)); - MAPPINGS.add(new PotionMapping(XPotion.WEAKNESS, "weakness", 1800, 4800, -1)); - MAPPINGS.add(TURTLE_MASTER = new PotionMapping(null, "turtle_master", 400, 800, 400)); - } - - private final @Nullable XPotion mappedPotion; - private final @NotNull String key; - private final @Nullable String baseDuration, extendedDuration, strongDuration; - private @NotNull String normal, splash, lingering; - - private PotionMapping(@Nullable XPotion mappedPotion, @NotNull String key, int baseDuration, int extendedDuration, - int strongDuration) { - this.mappedPotion = mappedPotion; - this.key = key; - this.baseDuration = baseDuration == 0 ? null : " (" + Utils.ticksToElapsedTime(baseDuration) + ")"; - this.extendedDuration = extendedDuration == 0 ? null : " (" + Utils.ticksToElapsedTime(extendedDuration) + ")"; - this.strongDuration = strongDuration == 0 ? "" : " (" + Utils.ticksToElapsedTime(strongDuration) + ")"; - this.normal = "potion of " + key; - this.splash = "splash potion of " + key; - this.lingering = "lingering potion of " + key; - } - - public @NotNull String getTranslated(XMaterial material) { - if (material == XMaterial.POTION) - return normal; - if (material == XMaterial.SPLASH_POTION) - return splash; - if (material == XMaterial.LINGERING_POTION) - return lingering; - throw new IllegalArgumentException("Argument is not a potion material"); - } - - public static @Nullable PotionMapping matchFromTranslationKey(String key) { - for (PotionMapping potion : MAPPINGS) { - if (key.equals(potion.key)) - return potion; - } - return null; - } - - public static @NotNull PotionMapping matchFromXPotion(XPotion xpotion) { - for (PotionMapping potion : MAPPINGS) { - if (xpotion.equals(potion.mappedPotion)) - return potion; - } - PotionMapping potion = new PotionMapping(xpotion, defaultFormat(xpotion.name()), -1, -1, -1); - MAPPINGS.add(potion); - return potion; - } - - } } \ No newline at end of file diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftVersion.java b/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftVersion.java index 6c2b279c..e9a223cd 100644 --- a/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftVersion.java +++ b/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftVersion.java @@ -24,4 +24,14 @@ public final class MinecraftVersion { private MinecraftVersion() {} + public static boolean isHigherThan(int major, int minor) { + if (MAJOR > major) + return true; + + if (MAJOR == major && MINOR >= minor) + return true; + + return false; + } + } diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/PotionMapping.java b/api/src/main/java/fr/skytasul/quests/api/utils/PotionMapping.java new file mode 100755 index 00000000..a02efd67 --- /dev/null +++ b/api/src/main/java/fr/skytasul/quests/api/utils/PotionMapping.java @@ -0,0 +1,117 @@ +package fr.skytasul.quests.api.utils; + +import com.cryptomorin.xseries.XMaterial; +import org.bukkit.potion.PotionType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +// In a separate file because it uses >= 1.20.2 API +class PotionMapping { + + private static final List MAPPINGS = new ArrayList<>(); + + private static void addMapping(PotionType base, String translationKey, int baseDuration, int longDuration, + int strongDuration) { + MAPPINGS.add(new PotionMapping(base, translationKey, baseDuration, false)); + + try { + MAPPINGS.add( + new PotionMapping(PotionType.valueOf("LONG_" + base.name()), translationKey, longDuration, true)); + } catch (IllegalArgumentException ex) { + } + + try { + MAPPINGS.add(new PotionMapping(PotionType.valueOf("STRONG_" + base.name()), translationKey, strongDuration, true)); + } catch (IllegalArgumentException ex) { + } + } + + static { + addMapping(PotionType.FIRE_RESISTANCE, "fire_resistance", 3600, 9600, -1); + addMapping(PotionType.HARMING, "harming", -1, -1, -1); + addMapping(PotionType.HEALING, "healing", -1, -1, -1); + addMapping(PotionType.STRENGTH, "strength", 3600, 9600, 1800); + addMapping(PotionType.INVISIBILITY, "invisibility", 3600, 9600, -1); + addMapping(PotionType.LEAPING, "leaping", 3600, 9600, 1800); + // addMapping(PotionType.LEVITATION, "levitation", -1, -1, -1); + // does not exist anymore? + addMapping(PotionType.LUCK, "luck", 6000, -1, -1); + addMapping(PotionType.NIGHT_VISION, "night_vision", 3600, 9600, -1); + addMapping(PotionType.POISON, "poison", 900, 1800, 432); + addMapping(PotionType.REGENERATION, "regeneration", 900, 1800, 450); + addMapping(PotionType.SLOWNESS, "slowness", 1800, 4800, 400); + addMapping(PotionType.SLOW_FALLING, "slow_falling", 1800, 4800, -1); + addMapping(PotionType.SWIFTNESS, "swiftness", 3600, 9600, 1800); + addMapping(PotionType.WATER_BREATHING, "water_breathing", 3600, 9600, -1); + addMapping(PotionType.WEAKNESS, "weakness", 1800, 4800, -1); + addMapping(PotionType.TURTLE_MASTER, "turtle_master", 400, 800, 400); + // experimental : wind_charged, weaving, oozing, infested + } + + private final @Nullable PotionType mappedPotion; + private final @NotNull String key; + private final @Nullable String duration; + private final boolean strong; + + private @NotNull String normalName, splashName, lingeringName; + + protected PotionMapping(@NotNull PotionType mappedPotion, @NotNull String key, int duration, boolean strong) { + this.mappedPotion = mappedPotion; + this.key = key; + this.duration = duration == -1 ? null : " (" + Utils.ticksToElapsedTime(duration) + ")"; + this.strong = strong; + + this.normalName = "potion of " + key; + this.splashName = "splash potion of " + key; + this.lingeringName = "lingering potion of " + key; + } + + public @NotNull String getTranslated(XMaterial material) { + String name; + if (material == XMaterial.POTION) + name = normalName; + else if (material == XMaterial.SPLASH_POTION) + name = splashName; + else if (material == XMaterial.LINGERING_POTION) + name = lingeringName; + else + throw new IllegalArgumentException("Argument is not a potion material"); + + if (strong) + name += " II"; + if (duration != null) + name += duration; + return name; + } + + public void setNormalName(@NotNull String normalName) { + this.normalName = normalName; + } + + public void setSplashName(@NotNull String splashName) { + this.splashName = splashName; + } + + public void setLingeringName(@NotNull String lingeringName) { + this.lingeringName = lingeringName; + } + + public static @NotNull Iterator matchFromTranslationKey(String key) { + return MAPPINGS.stream().filter(mapping -> mapping.key.equals(key)).iterator(); + // we return an iterator because there can be multiple mappings (one for "normal", one for + // "extended", one for "strong"... + } + + public static @NotNull PotionMapping matchFromPotionType(PotionType potion) { + for (PotionMapping mapping : MAPPINGS) { + if (potion.equals(mapping.mappedPotion)) + return mapping; + } + addMapping(potion, MinecraftNames.defaultFormat(potion.name()), -1, -1, -1); + return matchFromPotionType(potion); + } + +} \ No newline at end of file diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/Utils.java b/api/src/main/java/fr/skytasul/quests/api/utils/Utils.java index 50d7713c..8bd6d894 100644 --- a/api/src/main/java/fr/skytasul/quests/api/utils/Utils.java +++ b/api/src/main/java/fr/skytasul/quests/api/utils/Utils.java @@ -1,5 +1,19 @@ package fr.skytasul.quests.api.utils; +import com.cryptomorin.xseries.XMaterial; +import fr.skytasul.quests.api.gui.ItemUtils; +import fr.skytasul.quests.api.localization.Lang; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.MemoryConfiguration; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -11,19 +25,6 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Stream; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.MemoryConfiguration; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import com.cryptomorin.xseries.XMaterial; -import fr.skytasul.quests.api.gui.ItemUtils; -import fr.skytasul.quests.api.localization.Lang; /** * A bunch of static methods who can be useful @@ -259,20 +260,40 @@ public static boolean isQuestItem(ItemStack item) { return false; } + public static > T valueOfEnum(Class enumClass, @NotNull String... names) { + for (String name : names) { + try { + return Enum.valueOf(enumClass, name); + } catch (IllegalArgumentException ex) { + } + } + throw new IllegalArgumentException("Cannot find " + Arrays.toString(names) + " from enum " + enumClass.getName()); + } + public static XMaterial mobItem(EntityType type) { - if (type == null) return XMaterial.SPONGE; + if (type == null) + return XMaterial.SPONGE; Optional material = XMaterial.matchXMaterial(type.name() + "_SPAWN_EGG"); if (material.isPresent() && material.get().isSupported()) return material.get(); - if (type == EntityType.WITHER) return XMaterial.WITHER_SKELETON_SKULL; - if (type == EntityType.IRON_GOLEM) return XMaterial.IRON_BLOCK; - if (type == EntityType.SNOWMAN) return XMaterial.SNOW_BLOCK; - if (type == EntityType.MUSHROOM_COW) return XMaterial.MOOSHROOM_SPAWN_EGG; - if (type == EntityType.GIANT) return XMaterial.ZOMBIE_SPAWN_EGG; - if (type == EntityType.ARMOR_STAND) return XMaterial.ARMOR_STAND; - if (type == EntityType.PLAYER) return XMaterial.PLAYER_HEAD; - if (type == EntityType.ENDER_DRAGON) return XMaterial.DRAGON_HEAD; - if (type.name().equals("PIG_ZOMBIE") || type.name().equals("ZOMBIFIED_PIGLIN")) return XMaterial.ZOMBIFIED_PIGLIN_SPAWN_EGG; + if (type == EntityType.WITHER) + return XMaterial.WITHER_SKELETON_SKULL; + if (type == EntityType.IRON_GOLEM) + return XMaterial.IRON_BLOCK; + if (type == EntityType.GIANT) + return XMaterial.ZOMBIE_SPAWN_EGG; + if (type == EntityType.ARMOR_STAND) + return XMaterial.ARMOR_STAND; + if (type == EntityType.PLAYER) + return XMaterial.PLAYER_HEAD; + if (type == EntityType.ENDER_DRAGON) + return XMaterial.DRAGON_HEAD; + if (type.name().equals("MUSHROOM_COW") || type.name().equals("MOOSHROOM")) + return XMaterial.MOOSHROOM_SPAWN_EGG; + if (type.name().equals("SNOWMAN") || type.name().equals("SNOW_GOLEM")) + return XMaterial.SNOW_BLOCK; + if (type.name().equals("PIG_ZOMBIE") || type.name().equals("ZOMBIFIED_PIGLIN")) + return XMaterial.ZOMBIFIED_PIGLIN_SPAWN_EGG; if (type.name().equals("ILLUSIONER")) return XMaterial.BLAZE_POWDER; return XMaterial.SPONGE; } diff --git a/core/pom.xml b/core/pom.xml index 645e9802..2818467b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -158,7 +158,7 @@ fr.mrmicky fastboard - 2.0.2 + 2.1.2 compile diff --git a/core/src/main/java/fr/skytasul/quests/QuestsConfigurationImplementation.java b/core/src/main/java/fr/skytasul/quests/QuestsConfigurationImplementation.java index 71bf65e4..5acfb462 100644 --- a/core/src/main/java/fr/skytasul/quests/QuestsConfigurationImplementation.java +++ b/core/src/main/java/fr/skytasul/quests/QuestsConfigurationImplementation.java @@ -1,13 +1,5 @@ package fr.skytasul.quests; -import java.util.*; -import java.util.stream.Collectors; -import org.bukkit.*; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.FireworkMeta; -import org.jetbrains.annotations.NotNull; import fr.skytasul.quests.api.QuestsConfiguration; import fr.skytasul.quests.api.QuestsPlugin; import fr.skytasul.quests.api.gui.ItemUtils; @@ -20,6 +12,14 @@ import fr.skytasul.quests.utils.ParticleEffect; import fr.skytasul.quests.utils.ParticleEffect.ParticleShape; import fr.skytasul.quests.utils.compatibility.InternalIntegrations; +import org.bukkit.*; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.FireworkMeta; +import org.jetbrains.annotations.NotNull; +import java.util.*; +import java.util.stream.Collectors; public class QuestsConfigurationImplementation implements QuestsConfiguration { @@ -111,9 +111,13 @@ void init() { usePlayerBlockTracker = config.getBoolean("usePlayerBlockTracker"); if (MinecraftVersion.MAJOR >= 9) { - particleStart = loadParticles("start", new ParticleEffect(Particle.REDSTONE, ParticleShape.POINT, Color.YELLOW)); - particleTalk = loadParticles("talk", new ParticleEffect(Particle.VILLAGER_HAPPY, ParticleShape.BAR, null)); - particleNext = loadParticles("next", new ParticleEffect(Particle.SMOKE_NORMAL, ParticleShape.SPOT, null)); + particleStart = loadParticles("start", new ParticleEffect(Utils.valueOfEnum(Particle.class, "REDSTONE", "DUST"), + ParticleShape.POINT, Color.YELLOW)); + particleTalk = loadParticles("talk", new ParticleEffect( + Utils.valueOfEnum(Particle.class, "VILLAGER_HAPPY", "HAPPY_VILLAGER"), ParticleShape.BAR, null)); + particleNext = + loadParticles("next", new ParticleEffect(Utils.valueOfEnum(Particle.class, "SMOKE_NORMAL", "SMOKE"), + ParticleShape.SPOT, null)); } holoLaunchItem = loadHologram("launchItem"); diff --git a/core/src/main/java/fr/skytasul/quests/gui/DefaultItemFactory.java b/core/src/main/java/fr/skytasul/quests/gui/DefaultItemFactory.java index 5f1e907a..106d46be 100755 --- a/core/src/main/java/fr/skytasul/quests/gui/DefaultItemFactory.java +++ b/core/src/main/java/fr/skytasul/quests/gui/DefaultItemFactory.java @@ -3,14 +3,14 @@ import static fr.skytasul.quests.api.gui.ItemUtils.addEnchant; import static fr.skytasul.quests.api.gui.ItemUtils.item; import static fr.skytasul.quests.api.gui.ItemUtils.name; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; import fr.skytasul.quests.api.QuestsConfiguration; import fr.skytasul.quests.api.gui.ItemFactory; import fr.skytasul.quests.api.localization.Lang; +import fr.skytasul.quests.api.utils.XEnchantment; import fr.skytasul.quests.api.utils.XMaterial; import net.md_5.bungee.api.ChatColor; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; public class DefaultItemFactory implements ItemFactory { @@ -33,7 +33,7 @@ public class DefaultItemFactory implements ItemFactory { @Override public @NotNull ItemStack getDone() { - return addEnchant(item(XMaterial.DIAMOND, Lang.done.toString()), Enchantment.DURABILITY, 0); + return addEnchant(item(XMaterial.DIAMOND, Lang.done.toString()), XEnchantment.DURABILITY.getEnchant(), 0); } @Override diff --git a/core/src/main/java/fr/skytasul/quests/gui/blocks/SelectBlockGUI.java b/core/src/main/java/fr/skytasul/quests/gui/blocks/SelectBlockGUI.java index 2d8f1a19..69211605 100644 --- a/core/src/main/java/fr/skytasul/quests/gui/blocks/SelectBlockGUI.java +++ b/core/src/main/java/fr/skytasul/quests/gui/blocks/SelectBlockGUI.java @@ -1,16 +1,5 @@ package fr.skytasul.quests.gui.blocks; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.function.BiConsumer; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; import fr.skytasul.quests.BeautyQuests; import fr.skytasul.quests.api.QuestsPlugin; import fr.skytasul.quests.api.blocks.BQBlock; @@ -27,6 +16,16 @@ import fr.skytasul.quests.api.utils.XMaterial; import fr.skytasul.quests.api.utils.messaging.PlaceholderRegistry; import fr.skytasul.quests.utils.nms.NMS; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.function.BiConsumer; public class SelectBlockGUI extends LayoutedGUI.LayoutedRowsGUI { @@ -66,7 +65,7 @@ public void place(@NotNull Inventory inventory, int slot) { Lang.materialNotItemLore.quickFormat("block_type", type.name())))); } if (tag == null) - ItemUtils.addEnchant(inventory.getItem(slot), Enchantment.DURABILITY, 1); + ItemUtils.setGlittering(inventory.getItem(slot), true); } }); @@ -75,7 +74,7 @@ public void place(@NotNull Inventory inventory, int slot) { ItemStack item = ItemUtils.item(XMaterial.COMMAND_BLOCK, Lang.blockData.toString(), QuestOption.formatNullableValue(blockData, blockData == null)); if (blockData != null) - ItemUtils.addEnchant(item, Enchantment.DAMAGE_ALL, 1); + ItemUtils.setGlittering(item, true); return item; }, this::dataClick)); @@ -84,7 +83,7 @@ public void place(@NotNull Inventory inventory, int slot) { QuestOption.formatDescription(Lang.blockTagLore.toString()), "", QuestOption.formatNullableValue(tag, tag == null)); if (tag != null) - ItemUtils.addEnchant(item, Enchantment.DAMAGE_ALL, 1); + ItemUtils.setGlittering(item, true); return item; }, this::tagClick)); } diff --git a/core/src/main/java/fr/skytasul/quests/gui/quests/DialogHistoryGUI.java b/core/src/main/java/fr/skytasul/quests/gui/quests/DialogHistoryGUI.java index d54ae36c..994b4aaa 100644 --- a/core/src/main/java/fr/skytasul/quests/gui/quests/DialogHistoryGUI.java +++ b/core/src/main/java/fr/skytasul/quests/gui/quests/DialogHistoryGUI.java @@ -1,15 +1,7 @@ package fr.skytasul.quests.gui.quests; -import java.util.*; -import java.util.stream.Stream; -import org.apache.commons.lang.Validate; -import org.bukkit.DyeColor; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.ItemFlag; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; import fr.skytasul.quests.api.QuestsConfiguration; +import fr.skytasul.quests.api.gui.ItemUtils; import fr.skytasul.quests.api.gui.close.CloseBehavior; import fr.skytasul.quests.api.gui.close.StandardCloseBehavior; import fr.skytasul.quests.api.gui.templates.PagedGUI; @@ -25,6 +17,13 @@ import fr.skytasul.quests.gui.quests.DialogHistoryGUI.WrappedDialogable; import fr.skytasul.quests.options.OptionStartDialog; import fr.skytasul.quests.utils.QuestUtils; +import org.apache.commons.lang.Validate; +import org.bukkit.DyeColor; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import java.util.*; +import java.util.stream.Stream; public class DialogHistoryGUI extends PagedGUI { @@ -50,7 +49,7 @@ public DialogHistoryGUI(PlayerAccount acc, Quest quest, Runnable end) { @Override public ItemStack getItemStack(WrappedDialogable object) { - return object.setMeta(XMaterial.WRITTEN_BOOK.parseItem()); + return object.setMeta(ItemUtils.clearVisibleAttributes(XMaterial.WRITTEN_BOOK.parseItem())); } @Override @@ -163,13 +162,11 @@ public Page getCurrentPage() { } public ItemStack setMeta(ItemStack item) { - ItemMeta meta = item.getItemMeta(); - meta.setLore(getCurrentPage().lines); - meta.setDisplayName("§8" + objects.indexOf(this) + " (" + dialogable.getNPC().getNpc().getName() + "§8) - " - + getCurrentPage().header); - meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS); - item.setItemMeta(meta); - return item; + return ItemUtils.nameAndLore( + item, + "§8" + objects.indexOf(this) + " (" + dialogable.getNPC().getNpc().getName() + "§8) - " + + getCurrentPage().header, + getCurrentPage().lines); } } diff --git a/core/src/main/java/fr/skytasul/quests/gui/quests/PlayerListGUI.java b/core/src/main/java/fr/skytasul/quests/gui/quests/PlayerListGUI.java index 08876cab..892ab0bf 100644 --- a/core/src/main/java/fr/skytasul/quests/gui/quests/PlayerListGUI.java +++ b/core/src/main/java/fr/skytasul/quests/gui/quests/PlayerListGUI.java @@ -1,19 +1,5 @@ package fr.skytasul.quests.gui.quests; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import org.bukkit.DyeColor; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import fr.skytasul.quests.api.QuestsAPI; import fr.skytasul.quests.api.QuestsConfiguration; import fr.skytasul.quests.api.QuestsPlugin; @@ -31,6 +17,18 @@ import fr.skytasul.quests.options.OptionStartable; import fr.skytasul.quests.players.PlayerAccountImplementation; import fr.skytasul.quests.utils.QuestUtils; +import org.bukkit.DyeColor; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; public class PlayerListGUI extends PagedGUI { @@ -205,17 +203,15 @@ public void click(@NotNull Quest qu, @NotNull ItemStack item, @NotNull ClickType private void toggleCategorySelected() { ItemStack is = getInventory().getItem(cat.getSlot() * 9 + 8); - ItemMeta im = is.getItemMeta(); - String name = im.getDisplayName(); - if (!im.hasEnchant(Enchantment.DURABILITY)) { - im.addEnchant(Enchantment.DURABILITY, 0, true); + String name = ItemUtils.getName(is); + if (!ItemUtils.isGlittering(is)) { + ItemUtils.setGlittering(is, true); name = SELECTED_PREFIX + name.substring(UNSELECTED_PREFIX.length()); }else{ - im.removeEnchant(Enchantment.DURABILITY); + ItemUtils.setGlittering(is, false); name = UNSELECTED_PREFIX + name.substring(SELECTED_PREFIX.length()); } - im.setDisplayName(name); - is.setItemMeta(im); + ItemUtils.name(is, name); } @Override diff --git a/core/src/main/java/fr/skytasul/quests/players/AdminMode.java b/core/src/main/java/fr/skytasul/quests/players/AdminMode.java index b6b9d578..246a5668 100644 --- a/core/src/main/java/fr/skytasul/quests/players/AdminMode.java +++ b/core/src/main/java/fr/skytasul/quests/players/AdminMode.java @@ -1,31 +1,32 @@ package fr.skytasul.quests.players; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import org.bukkit.Particle; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; import fr.skytasul.quests.BeautyQuests; import fr.skytasul.quests.api.localization.Lang; import fr.skytasul.quests.api.utils.MinecraftVersion; +import fr.skytasul.quests.api.utils.Utils; import fr.skytasul.quests.utils.ParticleEffect; +import org.bukkit.Particle; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; public class AdminMode { private static final Set senders = new HashSet<>(); - + private static ParticleEffect enterParticle; private static ParticleEffect leaveParticle; - + static { if (MinecraftVersion.MAJOR >= 9) { enterParticle = new ParticleEffect(Particle.FLAME, null, null); - leaveParticle = new ParticleEffect(Particle.SMOKE_NORMAL, null, null); + leaveParticle = new ParticleEffect(Utils.valueOfEnum(Particle.class, "SMOKE_NORMAL", "SMOKE"), null, null); } } - + public static void toggle(CommandSender sender){ if (senders.add(sender)) { Lang.ADMIN_MODE_ENTERED.send(sender); @@ -38,20 +39,20 @@ public static void toggle(CommandSender sender){ leaveParticle.sendParticle(((Player) sender).getEyeLocation(), getAdminPlayers(), 1, 1, 1, 15); } } - + public static void broadcast(String message){ BeautyQuests.getInstance().getLoggerExpanded().getHandler().write("[ADMIN]: " + message); for (CommandSender p : senders){ p.sendMessage("§e" + message); } } - + public static Set getAdminSenders() { return senders; } - + public static List getAdminPlayers(){ return senders.stream().filter(Player.class::isInstance).map(Player.class::cast).collect(Collectors.toList()); } - + } diff --git a/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java b/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java index 77dc67a1..319fda9a 100644 --- a/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java +++ b/core/src/main/java/fr/skytasul/quests/utils/ParticleEffect.java @@ -1,7 +1,8 @@ package fr.skytasul.quests.utils; -import java.util.List; -import java.util.Random; +import fr.skytasul.quests.api.utils.MinecraftVersion; +import fr.skytasul.quests.utils.compatibility.Post1_13; +import fr.skytasul.quests.utils.nms.NMS; import org.apache.commons.lang.Validate; import org.bukkit.Color; import org.bukkit.Location; @@ -11,9 +12,9 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import fr.skytasul.quests.api.utils.MinecraftVersion; -import fr.skytasul.quests.utils.compatibility.Post1_13; -import fr.skytasul.quests.utils.nms.NMS; +import java.util.Arrays; +import java.util.List; +import java.util.Random; public class ParticleEffect { @@ -132,7 +133,7 @@ public static ParticleEffect deserialize(ConfigurationSection data) { public static boolean canHaveColor(Particle particle) { if (MinecraftVersion.MAJOR >= 13) return particle.getDataType() == Post1_13.getDustOptionClass(); - return particle == Particle.REDSTONE || particle == Particle.SPELL_MOB || particle == Particle.SPELL_MOB_AMBIENT; + return Arrays.asList("REDSTONE", "SPELL_MOB", "SPELL_MOB_AMBIENT").contains(particle.name()); } public enum ParticleShape { @@ -160,7 +161,7 @@ private ParticleType(Particle particle) { dustColored = false; } }else { - colored = particle == Particle.REDSTONE || particle == Particle.SPELL_MOB || particle == Particle.SPELL_MOB_AMBIENT; + colored = canHaveColor(particle); dustColored = false; } diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml index 69be671d..17f3466a 100644 --- a/core/src/main/resources/config.yml +++ b/core/src/main/resources/config.yml @@ -204,7 +204,7 @@ questDescription: # Particles shown on a NPC when the player can start the quest start: enabled: true - particleEffect: redstone + particleEffect: dust particleColor: RED: 255 BLUE: 0 @@ -213,7 +213,7 @@ start: # Particles shown on the NPC to which the player has to talk talk: enabled: true - particleEffect: villager_happy + particleEffect: happy_villager particleColor: RED: 255 BLUE: 0 @@ -222,7 +222,7 @@ talk: # Particles shown when the player finish a stage of a quest next: enabled: true - particleEffect: smoke_normal + particleEffect: smoke particleColor: RED: 255 BLUE: 0 diff --git a/dist/pom.xml b/dist/pom.xml index bba5f7ff..eab0eaaa 100644 --- a/dist/pom.xml +++ b/dist/pom.xml @@ -170,5 +170,12 @@ jar compile + + ${project.groupId} + beautyquests-v1_20_R4 + ${revision} + jar + compile + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5f01eb51..23eadd11 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ unknown 1.0.3-SNAPSHOT 1.0.3 - 1.20.4-R0.1-SNAPSHOT + 1.20.6-R0.1-SNAPSHOT @@ -85,6 +85,7 @@ v1_20_R1 v1_20_R2 v1_20_R3 + v1_20_R4 dist diff --git a/v1_20_R4/pom.xml b/v1_20_R4/pom.xml new file mode 100755 index 00000000..fdb8a6bf --- /dev/null +++ b/v1_20_R4/pom.xml @@ -0,0 +1,83 @@ + + + 4.0.0 + jar + beautyquests-v1_20_R4 + + fr.skytasul + beautyquests-parent + ${revision} + + + + true + 1.20.6-R0.1-SNAPSHOT + 21 + ${java.version} + ${java.version} + ${java.version} + + + + + jitpack.io + https://jitpack.io + + + + + + fr.skytasul + beautyquests-core + ${revision} + provided + + + org.spigotmc + spigot + ${spigot.version} + remapped-mojang + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 2.0.3 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${spigot.version}:txt:maps-mojang + true + org.spigotmc:spigot:${spigot.version}:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${revision}-remapped-obf.jar + org.spigotmc:minecraft-server:${spigot.version}:csrg:maps-spigot + org.spigotmc:spigot:${spigot.version}:jar:remapped-obf + + + + + + + diff --git a/v1_20_R4/src/main/java/fr/skytasul/quests/utils/nms/v1_20_R4.java b/v1_20_R4/src/main/java/fr/skytasul/quests/utils/nms/v1_20_R4.java new file mode 100755 index 00000000..e6817202 --- /dev/null +++ b/v1_20_R4/src/main/java/fr/skytasul/quests/utils/nms/v1_20_R4.java @@ -0,0 +1,49 @@ +package fr.skytasul.quests.utils.nms; + +import net.minecraft.core.Holder.Reference; +import net.minecraft.core.HolderLookup.RegistryLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.protocol.game.ClientboundOpenBookPacket; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.Property; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_20_R4.entity.CraftPlayer; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import java.util.List; + +public class v1_20_R4 extends NMS{ + + @Override + public void openBookInHand(Player p) { + ClientboundOpenBookPacket packet = new ClientboundOpenBookPacket(InteractionHand.MAIN_HAND); + ((CraftPlayer) p).getHandle().connection.send(packet); + } + + @Override + public double entityNameplateHeight(Entity en) { + return en.getHeight(); + } + + @Override + public List getAvailableBlockProperties(Material material) { + RegistryLookup blockRegistry = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK); + Reference block = blockRegistry + .getOrThrow(ResourceKey.create(Registries.BLOCK, new ResourceLocation(material.getKey().getKey()))); + StateDefinition stateList = block.value().getStateDefinition(); + return stateList.getProperties().stream().map(Property::getName).toList(); + } + + @Override + public List getAvailableBlockTags() { + return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK).listTags() + .map(x -> x.key().location().toString()).toList(); + } + +} From a2737c5251005f2e0c32aa4f20160656393c8584 Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sun, 5 May 2024 13:49:54 +0200 Subject: [PATCH 24/32] :alien: Updated to work on Paper with relocation --- .../quests/api/utils/MinecraftVersion.java | 14 ++--- .../fr/skytasul/quests/utils/nms/NMS.java | 63 +++++++++++-------- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftVersion.java b/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftVersion.java index e9a223cd..342a6209 100644 --- a/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftVersion.java +++ b/api/src/main/java/fr/skytasul/quests/api/utils/MinecraftVersion.java @@ -5,21 +5,15 @@ public final class MinecraftVersion { public static final String VERSION_STRING; - public static final String VERSION_NMS; public static final int MAJOR; public static final int MINOR; static { + // e.g. Bukkit.getBukkitVersion() -> 1.17.1-R0.1-SNAPSHOT VERSION_STRING = Bukkit.getBukkitVersion().split("-R")[0]; - VERSION_NMS = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3].substring(1); - String[] versions = VERSION_NMS.split("_"); - MAJOR = Integer.parseInt(versions[1]); // 1.X - if (MAJOR >= 17) { - // e.g. Bukkit.getBukkitVersion() -> 1.17.1-R0.1-SNAPSHOT - versions = VERSION_STRING.split("\\."); - MINOR = versions.length <= 2 ? 0 : Integer.parseInt(versions[2]); - } else - MINOR = Integer.parseInt(versions[2].substring(1)); // 1.X.Y + String[] versions = VERSION_STRING.split("\\."); + MAJOR = Integer.parseInt(versions[1]); + MINOR = versions.length <= 2 ? 0 : Integer.parseInt(versions[2]); } private MinecraftVersion() {} diff --git a/core/src/main/java/fr/skytasul/quests/utils/nms/NMS.java b/core/src/main/java/fr/skytasul/quests/utils/nms/NMS.java index e7f568ac..79de5af2 100644 --- a/core/src/main/java/fr/skytasul/quests/utils/nms/NMS.java +++ b/core/src/main/java/fr/skytasul/quests/utils/nms/NMS.java @@ -1,25 +1,27 @@ package fr.skytasul.quests.utils.nms; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; +import fr.skytasul.quests.BeautyQuests; +import fr.skytasul.quests.api.QuestsPlugin; +import fr.skytasul.quests.api.utils.MinecraftVersion; +import fr.skytasul.quests.utils.ReflectUtils; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.inventory.meta.ItemMeta; -import fr.skytasul.quests.api.QuestsPlugin; -import fr.skytasul.quests.api.utils.MinecraftVersion; -import fr.skytasul.quests.utils.ReflectUtils; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; public abstract class NMS{ - + private ReflectUtils nmsReflect = ReflectUtils.fromPackage("net.minecraft.server." + getClass().getSimpleName()); private ReflectUtils craftReflect = ReflectUtils.fromPackage("org.bukkit.craftbukkit." + getClass().getSimpleName()); - + private Field unhandledTags; private Method equalsCommon; - + public NMS() { if (!(this instanceof NullNMS)) { try { @@ -33,61 +35,70 @@ public NMS() { } } } - + public abstract double entityNameplateHeight(Entity en); // can be remplaced by Entity.getHeight from 1.11 - + public List getAvailableBlockProperties(Material material){ throw new UnsupportedOperationException(); } - + public List getAvailableBlockTags() { throw new UnsupportedOperationException(); } - + public boolean equalsWithoutNBT(ItemMeta meta1, ItemMeta meta2) throws ReflectiveOperationException { ((Map) unhandledTags.get(meta1)).clear(); ((Map) unhandledTags.get(meta2)).clear(); return (boolean) equalsCommon.invoke(meta1, meta2); } - + public ReflectUtils getNMSReflect(){ return nmsReflect; } - + public ReflectUtils getCraftReflect(){ return craftReflect; } - + public abstract void openBookInHand(Player p); - + public static NMS getNMS() { return nms; } - + public static boolean isValid() { return versionValid; } - + private static boolean versionValid = false; private static NMS nms; - + static { + String versionNms; + + if (!BeautyQuests.getInstance().isRunningPaper() || !MinecraftVersion.isHigherThan(20, 5)) { + versionNms = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3].substring(1); + } else { + versionNms = "1_20_R4"; + // TODO: find better way + } + try { - nms = (NMS) Class.forName("fr.skytasul.quests.utils.nms.v" + MinecraftVersion.VERSION_NMS).newInstance(); + nms = (NMS) Class.forName("fr.skytasul.quests.utils.nms.v" + versionNms).newInstance(); versionValid = true; QuestsPlugin.getPlugin().getLoggerExpanded() - .info("Loaded valid Minecraft version " + MinecraftVersion.VERSION_NMS + "."); + .info("Loaded valid Minecraft version " + versionNms + "."); }catch (ClassNotFoundException ex) { QuestsPlugin.getPlugin().getLoggerExpanded() - .warning("The Minecraft version " + MinecraftVersion.VERSION_NMS + " is not supported by BeautyQuests."); + .warning("The Minecraft version " + versionNms + " is not supported by BeautyQuests."); }catch (Exception ex) { QuestsPlugin.getPlugin().getLoggerExpanded().warning("An error ocurred when loading Minecraft Server version " - + MinecraftVersion.VERSION_NMS + " compatibilities.", ex); + + versionNms + " compatibilities.", ex); } if (!versionValid) { nms = new NullNMS(); QuestsPlugin.getPlugin().getLoggerExpanded().warning("Some functionnalities of the plugin have not been enabled."); } } - + } From 3b0b805db821b9275d6896406e506a9802861afb Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sun, 5 May 2024 14:15:38 +0200 Subject: [PATCH 25/32] :bug: :lipstick: Fixed upgrading bugs + changed Quests menu icons --- .../fr/skytasul/quests/api/gui/ItemUtils.java | 1 + .../quests/api/utils/PlayerListCategory.java | 12 ++++++------ .../fr/skytasul/quests/api/utils/Utils.java | 15 ++++++++------- .../quests/gui/quests/PlayerListGUI.java | 18 ++++++++---------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java b/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java index 323d69da..5a227275 100644 --- a/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java +++ b/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java @@ -337,6 +337,7 @@ public static void setGlittering(ItemStack is, boolean glitter) { else im.removeEnchant(Enchantment.getByName("DURABILITY")); } + is.setItemMeta(im); } /** diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/PlayerListCategory.java b/api/src/main/java/fr/skytasul/quests/api/utils/PlayerListCategory.java index b38f958d..5eb2a1ab 100644 --- a/api/src/main/java/fr/skytasul/quests/api/utils/PlayerListCategory.java +++ b/api/src/main/java/fr/skytasul/quests/api/utils/PlayerListCategory.java @@ -1,27 +1,27 @@ package fr.skytasul.quests.api.utils; -import org.bukkit.DyeColor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import com.cryptomorin.xseries.XMaterial; import fr.skytasul.quests.api.QuestsConfiguration; import fr.skytasul.quests.api.localization.Lang; +import org.bukkit.DyeColor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public enum PlayerListCategory { FINISHED( 1, - XMaterial.WRITTEN_BOOK, + XMaterial.BOOK, Lang.finisheds.toString(), DyeColor.GREEN), IN_PROGRESS( 2, - XMaterial.BOOK, + XMaterial.WRITABLE_BOOK, Lang.inProgress.toString(), DyeColor.YELLOW), NOT_STARTED( 3, - XMaterial.WRITABLE_BOOK, + XMaterial.PAPER, Lang.notStarteds.toString(), DyeColor.RED); diff --git a/api/src/main/java/fr/skytasul/quests/api/utils/Utils.java b/api/src/main/java/fr/skytasul/quests/api/utils/Utils.java index 8bd6d894..222781db 100644 --- a/api/src/main/java/fr/skytasul/quests/api/utils/Utils.java +++ b/api/src/main/java/fr/skytasul/quests/api/utils/Utils.java @@ -276,9 +276,9 @@ public static XMaterial mobItem(EntityType type) { Optional material = XMaterial.matchXMaterial(type.name() + "_SPAWN_EGG"); if (material.isPresent() && material.get().isSupported()) return material.get(); - if (type == EntityType.WITHER) + if (type == EntityType.WITHER) // got its egg return XMaterial.WITHER_SKELETON_SKULL; - if (type == EntityType.IRON_GOLEM) + if (type == EntityType.IRON_GOLEM) // got its egg return XMaterial.IRON_BLOCK; if (type == EntityType.GIANT) return XMaterial.ZOMBIE_SPAWN_EGG; @@ -286,15 +286,16 @@ public static XMaterial mobItem(EntityType type) { return XMaterial.ARMOR_STAND; if (type == EntityType.PLAYER) return XMaterial.PLAYER_HEAD; - if (type == EntityType.ENDER_DRAGON) + if (type == EntityType.ENDER_DRAGON) // got its egg return XMaterial.DRAGON_HEAD; - if (type.name().equals("MUSHROOM_COW") || type.name().equals("MOOSHROOM")) + if (type.name().equals("MUSHROOM_COW")) return XMaterial.MOOSHROOM_SPAWN_EGG; - if (type.name().equals("SNOWMAN") || type.name().equals("SNOW_GOLEM")) + if (type.name().equals("SNOWMAN")) // got its egg return XMaterial.SNOW_BLOCK; - if (type.name().equals("PIG_ZOMBIE") || type.name().equals("ZOMBIFIED_PIGLIN")) + if (type.name().equals("PIG_ZOMBIE")) return XMaterial.ZOMBIFIED_PIGLIN_SPAWN_EGG; - if (type.name().equals("ILLUSIONER")) return XMaterial.BLAZE_POWDER; + if (type.name().equals("ILLUSIONER")) + return XMaterial.BLAZE_POWDER; return XMaterial.SPONGE; } diff --git a/core/src/main/java/fr/skytasul/quests/gui/quests/PlayerListGUI.java b/core/src/main/java/fr/skytasul/quests/gui/quests/PlayerListGUI.java index 892ab0bf..14862332 100644 --- a/core/src/main/java/fr/skytasul/quests/gui/quests/PlayerListGUI.java +++ b/core/src/main/java/fr/skytasul/quests/gui/quests/PlayerListGUI.java @@ -72,13 +72,11 @@ protected void populate(@NotNull Player player, @NotNull Inventory inventory) { private void setCategory(PlayerListCategory category){ if (cat == category) return; if (cat != null) - toggleCategorySelected(); + setCategorySelected(false); cat = category; + setCategorySelected(true); setSeparatorColor(cat.getColor()); - DyeColor color = cat == PlayerListCategory.FINISHED ? DyeColor.GREEN: (cat == PlayerListCategory.IN_PROGRESS ? DyeColor.YELLOW : DyeColor.RED); - for (int i = 0; i < 5; i++) - getInventory().setItem(i * 9 + 7, ItemUtils.itemSeparator(color)); List quests; switch (cat) { @@ -201,15 +199,15 @@ public void click(@NotNull Quest qu, @NotNull ItemStack item, @NotNull ClickType } } - private void toggleCategorySelected() { + private void setCategorySelected(boolean selected) { ItemStack is = getInventory().getItem(cat.getSlot() * 9 + 8); - String name = ItemUtils.getName(is); - if (!ItemUtils.isGlittering(is)) { + String name; + if (selected) { ItemUtils.setGlittering(is, true); - name = SELECTED_PREFIX + name.substring(UNSELECTED_PREFIX.length()); - }else{ + name = SELECTED_PREFIX + cat.getName(); + } else { ItemUtils.setGlittering(is, false); - name = UNSELECTED_PREFIX + name.substring(SELECTED_PREFIX.length()); + name = UNSELECTED_PREFIX + cat.getName(); } ItemUtils.name(is, name); } From 5b190ca0b73edfefc77aefd4c4e1a824ac38474d Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sun, 5 May 2024 14:21:50 +0200 Subject: [PATCH 26/32] :green_heart: Fixed adventure snapshot artifact not found --- api/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/pom.xml b/api/pom.xml index f1b905c0..cf6b79e9 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -116,6 +116,10 @@ jitpack.io https://jitpack.io + + sonatype-oss-snapshots1 + https://s01.oss.sonatype.org/content/repositories/snapshots/ + From ebfcb3b77ade7407c0f7ec8e1d32376a7893862f Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Fri, 10 May 2024 14:00:37 +0200 Subject: [PATCH 27/32] :bug: Fix for fireworks on 1.17/1.18/1.19 --- .../fr/skytasul/quests/utils/QuestUtils.java | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/fr/skytasul/quests/utils/QuestUtils.java b/core/src/main/java/fr/skytasul/quests/utils/QuestUtils.java index 56e3310c..49711292 100644 --- a/core/src/main/java/fr/skytasul/quests/utils/QuestUtils.java +++ b/core/src/main/java/fr/skytasul/quests/utils/QuestUtils.java @@ -1,11 +1,12 @@ package fr.skytasul.quests.utils; -import java.lang.annotation.Annotation; -import java.lang.annotation.Inherited; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.function.BiConsumer; -import java.util.function.Consumer; +import fr.skytasul.quests.BeautyQuests; +import fr.skytasul.quests.QuestsConfigurationImplementation; +import fr.skytasul.quests.api.QuestsConfiguration; +import fr.skytasul.quests.api.QuestsPlugin; +import fr.skytasul.quests.api.utils.AutoRegistered; +import fr.skytasul.quests.api.utils.MinecraftVersion; +import fr.skytasul.quests.utils.nms.NMS; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Sound; @@ -21,13 +22,12 @@ import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.scoreboard.DisplaySlot; import org.jetbrains.annotations.NotNull; -import fr.skytasul.quests.BeautyQuests; -import fr.skytasul.quests.QuestsConfigurationImplementation; -import fr.skytasul.quests.api.QuestsConfiguration; -import fr.skytasul.quests.api.QuestsPlugin; -import fr.skytasul.quests.api.utils.AutoRegistered; -import fr.skytasul.quests.api.utils.MinecraftVersion; -import fr.skytasul.quests.utils.nms.NMS; +import java.lang.annotation.Annotation; +import java.lang.annotation.Inherited; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.function.BiConsumer; +import java.util.function.Consumer; public final class QuestUtils { @@ -153,10 +153,11 @@ public static void spawnFirework(Location lc, FireworkMeta meta) { fw.setMetadata("questFinish", new FixedMetadataValue(BeautyQuests.getInstance(), true)); fw.setFireworkMeta(meta); }; - if (MinecraftVersion.MAJOR >= 12) { + if ((MinecraftVersion.MAJOR >= 12 && MinecraftVersion.MAJOR < 17) || MinecraftVersion.MAJOR >= 20) { lc.getWorld().spawn(lc, Firework.class, fw -> fwConsumer.accept(fw)); - // much better to use the built-in since 1.12 method to do operations on entity - // before it is sent to the players, as it will not create flickering + // Much better to use the built-in since 1.12 method to do operations on entity + // before it is sent to the players, as it will not create flickering. + // From 1.17.1 to 1.19.4, the method was moved from World to RegionAccessor. } else { fwConsumer.accept(lc.getWorld().spawn(lc, Firework.class)); } From 990dd571a98052383bc77cc5e96a258541b0aefd Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Fri, 24 May 2024 17:35:21 +0200 Subject: [PATCH 28/32] :arrow_up: Updated UltimateTimber --- integrations/libs.sh | 4 ++-- integrations/pom.xml | 4 ++-- .../quests/integrations/BQUltimateTimber.java | 12 ++++++------ .../integrations/IntegrationsLoader.java | 19 ++++++++++++++++--- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/integrations/libs.sh b/integrations/libs.sh index 621336c1..fb8e01ef 100755 --- a/integrations/libs.sh +++ b/integrations/libs.sh @@ -23,10 +23,10 @@ echo -e "Maven path: $mavenPath\e[39m" "$mavenPath" install:install-file -Dfile=$jarsPath/Boss.jar -DgroupId=org.mineacademy -DartifactId=boss -Dversion=4.2.1 -Dpackaging=jar -DgeneratePom=true "$mavenPath" install:install-file -Dfile=$jarsPath/CMI.jar -DgroupId=com.zrips -DartifactId=cmi -Dversion=9.0.2.1 -Dpackaging=jar -DgeneratePom=true "$mavenPath" install:install-file -Dfile=$jarsPath/CMILib.jar -DgroupId=com.zrips -DartifactId=cmilib -Dversion=1.2.3.3 -Dpackaging=jar -DgeneratePom=true -"$mavenPath" install:install-file -Dfile=$jarsPath/UltimateTimber.jar -DgroupId=com.songoda -DartifactId=UltimateTimber -Dversion=2.3.5 -Dpackaging=jar -DgeneratePom=true +"$mavenPath" org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=$jarsPath/UltimateTimber.jar # contains pom.xml file, version 3.0.1 "$mavenPath" install:install-file -Dfile=$jarsPath/AdvancedSpawners-API.jar -DgroupId=gcspawners -DartifactId=gcspawners -Dversion=3.3.0 -Dpackaging=jar -DgeneratePom=true "$mavenPath" install:install-file -Dfile=$jarsPath/znpcs.jar -DgroupId=io.github.gonalez -DartifactId=znpcs -Dversion=4.2 -Dpackaging=jar -DgeneratePom=true #"$mavenPath" install:install-file -Dfile=$jarsPath/MythicMobs.jar -DgroupId=io.lumine.xikage -DartifactId=MythicMobs -Dversion=4.12.0 -Dpackaging=jar -DgeneratePom=true #"$mavenPath" install:install-file -Dfile=$jarsPath/TokenEnchantAPI.jar -DgroupId=com.vk2gpz.tokenenchant -DartifactId=TokenEnchantAPI -Dversion=18.15.2 -Dpackaging=jar -DgeneratePom=true -echo -e "\e[92mOperation complete." \ No newline at end of file +echo -e "\e[92mOperation complete." diff --git a/integrations/pom.xml b/integrations/pom.xml index 656a1573..5de75407 100644 --- a/integrations/pom.xml +++ b/integrations/pom.xml @@ -239,9 +239,9 @@ provided - com.songoda + com.craftaro UltimateTimber - 2.3.5 + 3.0.1 provided diff --git a/integrations/src/main/java/fr/skytasul/quests/integrations/BQUltimateTimber.java b/integrations/src/main/java/fr/skytasul/quests/integrations/BQUltimateTimber.java index 92e71b36..18dcad8f 100644 --- a/integrations/src/main/java/fr/skytasul/quests/integrations/BQUltimateTimber.java +++ b/integrations/src/main/java/fr/skytasul/quests/integrations/BQUltimateTimber.java @@ -1,17 +1,17 @@ package fr.skytasul.quests.integrations; -import java.util.stream.Collectors; +import com.craftaro.ultimatetimber.events.TreeFellEvent; +import com.craftaro.ultimatetimber.tree.ITreeBlock; +import fr.skytasul.quests.api.events.internal.BQBlockBreakEvent; import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import com.songoda.ultimatetimber.events.TreeFellEvent; -import com.songoda.ultimatetimber.tree.ITreeBlock; -import fr.skytasul.quests.api.events.internal.BQBlockBreakEvent; +import java.util.stream.Collectors; public class BQUltimateTimber implements Listener { - + @EventHandler (priority = EventPriority.MONITOR) public void onTreeFell(TreeFellEvent e) { Bukkit.getPluginManager().callEvent(new BQBlockBreakEvent(e.getPlayer(), @@ -22,5 +22,5 @@ public void onTreeFell(TreeFellEvent e) { .map(ITreeBlock::getBlock) .collect(Collectors.toList()))); } - + } diff --git a/integrations/src/main/java/fr/skytasul/quests/integrations/IntegrationsLoader.java b/integrations/src/main/java/fr/skytasul/quests/integrations/IntegrationsLoader.java index b7e94780..f996b4fb 100644 --- a/integrations/src/main/java/fr/skytasul/quests/integrations/IntegrationsLoader.java +++ b/integrations/src/main/java/fr/skytasul/quests/integrations/IntegrationsLoader.java @@ -1,7 +1,5 @@ package fr.skytasul.quests.integrations; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; import fr.skytasul.quests.api.AbstractHolograms; import fr.skytasul.quests.api.QuestsAPI; import fr.skytasul.quests.api.QuestsPlugin; @@ -30,6 +28,8 @@ import fr.skytasul.quests.integrations.vault.economy.MoneyReward; import fr.skytasul.quests.integrations.vault.permission.PermissionReward; import fr.skytasul.quests.integrations.worldguard.BQWorldGuard; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; public class IntegrationsLoader { @@ -111,7 +111,8 @@ public IntegrationsLoader() { manager.addDependency(new BQDependency("TokenEnchant", () -> Bukkit.getPluginManager().registerEvents(new BQTokenEnchant(), QuestsPlugin.getPlugin()))); manager.addDependency(new BQDependency("UltimateTimber", - () -> Bukkit.getPluginManager().registerEvents(new BQUltimateTimber(), QuestsPlugin.getPlugin()))); + () -> Bukkit.getPluginManager().registerEvents(new BQUltimateTimber(), QuestsPlugin.getPlugin()), null, + this::isUltimateTimberValid)); manager.addDependency(new BQDependency("ItemsAdder", BQItemsAdder::initialize, BQItemsAdder::unload)); manager.addDependency(new BQDependency("MMOItems", BQMMOItems::initialize, BQMMOItems::unload)); } @@ -184,6 +185,18 @@ private void registerSkillApi() { ItemUtils.item(XMaterial.EXPERIENCE_BOTTLE, Lang.RWSkillApiXp.toString()), SkillAPIXpReward::new)); } + private boolean isUltimateTimberValid(Plugin plugin) { + try { + Class.forName("com.craftaro.ultimatetimber.UltimateTimber"); + } catch (ClassNotFoundException ex) { + QuestsPlugin.getPlugin().getLoggerExpanded().warning("Your version of UltimateTimber (" + + plugin.getDescription().getVersion() + + ") is not compatible with BeautyQuests. Please use 3.0.0 or higher."); + return false; + } + return true; + } + private boolean isBossVersionValid(Plugin plugin) { try { Class.forName("org.mineacademy.boss.model.Boss"); From fe9c2609466c9bdba76ff843c4aca203d615795b Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Fri, 24 May 2024 19:33:14 +0200 Subject: [PATCH 29/32] :goal_net: Catch bizarre things in account loading --- .../events/accounts/PlayerAccountEvent.java | 12 +-- .../players/AbstractPlayersManager.java | 75 +++++++++++-------- 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/events/accounts/PlayerAccountEvent.java b/api/src/main/java/fr/skytasul/quests/api/events/accounts/PlayerAccountEvent.java index a0b613d9..02f2208a 100644 --- a/api/src/main/java/fr/skytasul/quests/api/events/accounts/PlayerAccountEvent.java +++ b/api/src/main/java/fr/skytasul/quests/api/events/accounts/PlayerAccountEvent.java @@ -1,26 +1,26 @@ package fr.skytasul.quests.api.events.accounts; +import fr.skytasul.quests.api.players.PlayerAccount; import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import fr.skytasul.quests.api.players.PlayerAccount; public abstract class PlayerAccountEvent extends Event { - + protected final @NotNull PlayerAccount account; protected PlayerAccountEvent(@NotNull PlayerAccount account) { this.account = account; } - + public boolean isAccountCurrent() { return account.isCurrent(); } - + public @Nullable Player getPlayer() { if (!account.isCurrent()) - throw new IllegalStateException("Account is not currently used"); + throw new IllegalStateException("Account " + account.debugName() + " is not currently used"); return account.getPlayer(); } @@ -28,5 +28,5 @@ public boolean isAccountCurrent() { public @NotNull PlayerAccount getPlayerAccount() { return account; } - + } \ No newline at end of file diff --git a/core/src/main/java/fr/skytasul/quests/players/AbstractPlayersManager.java b/core/src/main/java/fr/skytasul/quests/players/AbstractPlayersManager.java index 73d34974..f77f675c 100644 --- a/core/src/main/java/fr/skytasul/quests/players/AbstractPlayersManager.java +++ b/core/src/main/java/fr/skytasul/quests/players/AbstractPlayersManager.java @@ -1,17 +1,5 @@ package fr.skytasul.quests.players; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnknownNullability; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -27,7 +15,19 @@ import fr.skytasul.quests.api.utils.MissingDependencyException; import fr.skytasul.quests.players.accounts.AbstractAccount; import fr.skytasul.quests.players.accounts.UUIDAccount; -import fr.skytasul.quests.utils.DebugUtils; +import fr.skytasul.quests.utils.DebugUtils; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnknownNullability; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.*; +import java.util.concurrent.CompletableFuture; public abstract class AbstractPlayersManager implements PlayersManager { @@ -36,11 +36,11 @@ public abstract class AbstractPlayersManager implements PlayersManager { private boolean loaded = false; public abstract void load(@NotNull AccountFetchRequest request); - + public abstract void unloadAccount(@NotNull PlayerAccountImplementation acc); protected abstract @NotNull CompletableFuture removeAccount(@NotNull PlayerAccountImplementation acc); - + public abstract @NotNull CompletableFuture removeQuestDatas(@NotNull Quest quest); public abstract @NotNull PlayerQuestDatasImplementation createPlayerQuestDatas(@NotNull PlayerAccountImplementation acc, @@ -52,7 +52,7 @@ public abstract class AbstractPlayersManager implements PlayersManager { public @NotNull CompletableFuture playerQuestDataRemoved(@NotNull PlayerQuestDatasImplementation datas) { return CompletableFuture.completedFuture(null); } - + public @NotNull CompletableFuture playerPoolDataRemoved(@NotNull PlayerPoolDatasImplementation datas) { return CompletableFuture.completedFuture(null); } @@ -61,14 +61,14 @@ public void load() { if (loaded) throw new IllegalStateException("Already loaded"); loaded = true; } - + public boolean isLoaded() { return loaded; } @Override public abstract void save(); - + @Override public void addAccountData(@NotNull SavableData data) { if (loaded) @@ -82,7 +82,7 @@ public void addAccountData(@NotNull SavableData data) { accountDatas.add(data); QuestsPlugin.getPlugin().getLoggerExpanded().debug("Registered account data " + data.getId()); } - + @Override public @NotNull Collection<@NotNull SavableData> getAccountDatas() { return accountDatas; @@ -129,7 +129,7 @@ public void addAccountData(@NotNull SavableData data) { } return null; } - + public synchronized void loadPlayer(@NotNull Player p) { cachedPlayerNames.put(p.getUniqueId(), p.getName()); @@ -181,17 +181,26 @@ private boolean tryLoad(@NotNull Player p, long time) { "New account registered for " + p.getName() + " (" + request.getAccount().abstractAcc.getIdentifier() + "), index " + request.getAccount().index + " via " + DebugUtils.stackTraces(2, 4)); + if (!request.getAccount().getOfflinePlayer().equals(p)) { + QuestsPlugin.getPlugin().getLogger() + .severe("UUID mismatch between player " + p.getName() + " (" + p.getUniqueId() + ") and loaded account " + + request.getAccount().debugName()); + return false; + } + cachedAccounts.put(p, request.getAccount()); - Bukkit.getScheduler().runTask(BeautyQuests.getInstance(), () -> { - String loadMessage = - "Completed load of " + p.getName() + " (" + request.getAccount().debugName() + ") datas within " - + (System.currentTimeMillis() - time) + " ms (" + request.getAccount().getQuestsDatas().size() - + " quests, " + request.getAccount().getPoolDatas().size() + " pools)"; - if (request.getLoadedFrom() != null) - loadMessage += " | Loaded from " + request.getLoadedFrom(); + String loadMessage = + "Completed load of " + p.getName() + " (" + request.getAccount().debugName() + ") datas within " + + (System.currentTimeMillis() - time) + " ms (" + request.getAccount().getQuestsDatas().size() + + " quests, " + request.getAccount().getPoolDatas().size() + " pools)"; - QuestsPlugin.getPlugin().getLoggerExpanded().debug(loadMessage); + if (request.getLoadedFrom() != null) + loadMessage += " | Loaded from " + request.getLoadedFrom(); + + QuestsPlugin.getPlugin().getLoggerExpanded().debug(loadMessage); + + Bukkit.getScheduler().runTask(BeautyQuests.getInstance(), () -> { if (p.isOnline()) { Bukkit.getPluginManager() @@ -207,7 +216,7 @@ private boolean tryLoad(@NotNull Player p, long time) { }); return false; } - + public synchronized void unloadPlayer(@NotNull Player p) { PlayerAccountImplementation acc = cachedAccounts.get(p); if (acc == null) return; @@ -216,7 +225,7 @@ public synchronized void unloadPlayer(@NotNull Player p) { unloadAccount(acc); cachedAccounts.remove(p); } - + @Override public @UnknownNullability PlayerAccountImplementation getAccount(@NotNull Player p) { if (BeautyQuests.getInstance().getNpcManager().isNPC(p)) @@ -225,7 +234,7 @@ public synchronized void unloadPlayer(@NotNull Player p) { QuestsPlugin.getPlugin().getLoggerExpanded().severe("Trying to fetch the account of an offline player (" + p.getName() + ")"); QuestsPlugin.getPlugin().getLoggerExpanded().debug("(via " + DebugUtils.stackTraces(2, 5) + ")"); } - + return cachedAccounts.get(p); } @@ -330,7 +339,7 @@ public String getDebugPlayerName() { /** * This method must be called when the request results in a successfully loaded account. - * + * * @param account account that has been loaded * @param from source of the saved account */ @@ -346,7 +355,7 @@ public void loaded(PlayerAccountImplementation account, String from) { *

* It cannot be called when the {@link AccountFetchRequest#mustCreateMissing()} * method returns false. - * + * * @param account account that has been created */ public void created(PlayerAccountImplementation account) { From 691b9cbc773c5ab28a7afb35a32b6092b612ef7f Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Fri, 24 May 2024 20:20:23 +0200 Subject: [PATCH 30/32] :bug: Fixed issues with 1.20.5+ and item components --- .../fr/skytasul/quests/api/gui/ItemUtils.java | 17 ++++++++++---- .../quests/gui/items/ItemCreatorGUI.java | 23 +++++++++---------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java b/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java index 5a227275..d7d9dae8 100644 --- a/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java +++ b/api/src/main/java/fr/skytasul/quests/api/gui/ItemUtils.java @@ -9,6 +9,7 @@ import fr.skytasul.quests.api.utils.Utils; import org.apache.commons.lang.Validate; import org.bukkit.DyeColor; +import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; @@ -41,7 +42,7 @@ public static ItemStack item(XMaterial type, String name, String... lore) { } ItemStack is = type.parseItem(); ItemMeta im = is.getItemMeta(); - im.addItemFlags(ItemFlag.values()); + addSpecificFlags(im, is.getType()); is.setItemMeta(applyMeta(im, name, lore)); return is; } @@ -61,7 +62,7 @@ public static ItemStack item(XMaterial type, String name, List lore) { } ItemStack is = type.parseItem(); ItemMeta im = is.getItemMeta(); - im.addItemFlags(ItemFlag.values()); + addSpecificFlags(im, is.getType()); is.setItemMeta(applyMeta(im, name, lore)); return is; } @@ -138,13 +139,20 @@ public static ItemStack clearVisibleAttributes(ItemStack is) { im.setDisplayName(null); im.setLore(null); + addSpecificFlags(im, is.getType()); + + is.setItemMeta(im); + return is; + } + + public static ItemMeta addSpecificFlags(ItemMeta im, Material material) { // add flags to hide various descriptions, // depending on the item type/attributes/other things if (im.hasEnchants()) im.addItemFlags(ItemFlag.HIDE_ENCHANTS); if (MinecraftVersion.MAJOR >= 11 && im.isUnbreakable()) im.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); - if (is.getType().getMaxDurability() != 0 || (MinecraftVersion.MAJOR > 12 && im.hasAttributeModifiers())) + if (material.getMaxDurability() != 0 || (MinecraftVersion.MAJOR > 12 && im.hasAttributeModifiers())) im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); if (im instanceof BookMeta || im instanceof PotionMeta || im instanceof EnchantmentStorageMeta || (MinecraftVersion.MAJOR >= 12 && im instanceof KnowledgeBookMeta)) @@ -152,8 +160,7 @@ public static ItemStack clearVisibleAttributes(ItemStack is) { if (im instanceof LeatherArmorMeta) im.addItemFlags(ItemFlag.HIDE_DYE); - is.setItemMeta(im); - return is; + return im; } /** diff --git a/core/src/main/java/fr/skytasul/quests/gui/items/ItemCreatorGUI.java b/core/src/main/java/fr/skytasul/quests/gui/items/ItemCreatorGUI.java index ccdce05c..7d601e46 100644 --- a/core/src/main/java/fr/skytasul/quests/gui/items/ItemCreatorGUI.java +++ b/core/src/main/java/fr/skytasul/quests/gui/items/ItemCreatorGUI.java @@ -1,16 +1,5 @@ package fr.skytasul.quests.gui.items; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemFlag; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.NotNull; import fr.skytasul.quests.api.QuestsPlugin; import fr.skytasul.quests.api.editors.TextEditor; import fr.skytasul.quests.api.editors.TextListEditor; @@ -20,6 +9,16 @@ import fr.skytasul.quests.api.gui.ItemUtils; import fr.skytasul.quests.api.localization.Lang; import fr.skytasul.quests.api.utils.XMaterial; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; public class ItemCreatorGUI extends AbstractGui { @@ -147,7 +146,7 @@ private ItemStack build() { if (name != null) im.setDisplayName(name); if (flags) - im.addItemFlags(ItemFlag.values()); + ItemUtils.addSpecificFlags(im, is.getType()); is.setItemMeta(im); is.setAmount(amount); From 0dd9abbbfd87897683726a8690e9ba6a7b69ff5d Mon Sep 17 00:00:00 2001 From: SkytAsul Date: Sat, 25 May 2024 12:04:12 +0200 Subject: [PATCH 31/32] :globe_with_meridians: Updated many translations --- core/src/main/resources/locales/cs_CZ.yml | 668 +++++++-- core/src/main/resources/locales/de_DE.yml | 19 +- core/src/main/resources/locales/es_ES.yml | 1447 ++++++++++---------- core/src/main/resources/locales/hu_HU.yml | 25 +- core/src/main/resources/locales/ko_KR.yml | 3 + core/src/main/resources/locales/nl_NL.yml | 28 +- core/src/main/resources/locales/pl_PL.yml | 43 + core/src/main/resources/locales/pt_BR.yml | 1464 ++++++++++---------- core/src/main/resources/locales/ru_RU.yml | 7 + core/src/main/resources/locales/tr_TR.yml | 1508 +++++++++++---------- core/src/main/resources/locales/zh_CN.yml | 12 +- 11 files changed, 2869 insertions(+), 2355 deletions(-) diff --git a/core/src/main/resources/locales/cs_CZ.yml b/core/src/main/resources/locales/cs_CZ.yml index 2b0a42bd..9a50b5f3 100755 --- a/core/src/main/resources/locales/cs_CZ.yml +++ b/core/src/main/resources/locales/cs_CZ.yml @@ -1,51 +1,112 @@ --- -inv: - create: - bringBack: '§aPřinést zpět předměty' - bucket: '§aVyplnit kbelíky' - craft: '§aVyrobit předmět' - findNPC: '§aNajít NPC' - findRegion: '§aNajít region' - fish: '§aChytat ryby' - killMobs: '§aZabít monstra' - mineBlocks: '§aRozbít bloky' - placeBlocks: '§aPostav bloky' - talkChat: '§aPsát do chatu' msg: + quest: + finished: + base: '§aBlahopřejeme! Dokončil jsi svůj úkol §e{quest_name}§a!' + obtain: '§aObdržel jsi {rewards}!' + started: '§aTvůj úkol právě začíná §r§e{quest_name}§o§6!' + created: '§aBlahopřejeme! Vytvořil jsi nový úkol §e{quest}§a, který obsahuje {quest_branches} větev(e)!' + edited: '§aBlahopřejeme! Upravil jsi úkol §e{quest}§a, který obsahuje nyní {quest_branches} větev(e)!' + createCancelled: '§cVytváření nebo úprava úkolu byla přerušena jiným pluginem!' + cancelling: '§cProces vytváření úkolu byl zrušen.' + editCancelling: '§cProces úpravy úkolu byl zrušen.' + invalidID: '§cÚkol s ID {quest_id} neexistuje.' + invalidPoolID: '§cPool {pool_id} neexistuje' + alreadyStarted: '§cTvůj úkol byl už zahájen!' + notStarted: '§cMomentálně neděláš tento úkol.' + quests: + maxLaunched: '§cNemůžeš mít více než {quests_max_amount} úkol zároveň...' + updated: '§7Úkol §e{quest_name}§7 a jeho nastavení bylo aktualizováno.' + checkpoint: '§7Dosáhl jsi kontrolního bodu úkolu!' + failed: '§cSelhal jsi v plnění úkolu {quest_name}' + pools: + noTime: '§cMusíš počkat {time_left} než budeš dělat jiný úkol.' + allCompleted: '§7Všechny úkoly byly dokončeny!' + noAvailable: '§7Žádný další úkol není k dispozici...' + maxQuests: '§cNemůžeš mít zároveň více než {pool_max_quests} úkol(ů)...' + questItem: + drop: '§cPředmět, který je součástí tvého úkolu, není možné zahodit!' + craft: '§cNemůžeš použít item z úkolu k výrobě!' + eat: '§cNemůžeš sníst úkolový předmět!' + stageMobs: + listMobs: '§aMusíš zabít {mobs}' + writeNPCText: '§aNapiš dialog který NPC řekně hráči: (Napiš "help" pro získání pomoci)' + writeRegionName: '§aNapiš název regionu vyžadovaného pro krok:' + writeXPGain: '§aNapiš množství bodů zkušenosti, které hráč získá: (poslední hodnota: {xp_amount})' + writeMobAmount: '§aNapiš počet mobů, k zabíjení:' + writeMobName: '§aNapiš vlastní jméno moba, kterého budeš zabíjet:' + writeChatMessage: '§aNapište požadovanou zprávu: (Přidejte "\{SLASH}" na začátek, pokud chcete příkaz.)' + writeMessage: '§aNapiš zprávu, která bude odeslána hráči' + writeStartMessage: '§aNapište zprávu, která bude odeslána na začátku úkolu, „null“, pokud chcete výchozí, nebo „none“, pokud nechcete žádnou:' + writeEndMsg: '§aNapište zprávu, která bude odeslána na konci úkolu, "null", pokud chcete výchozí nebo "none", pokud nechcete žádnou. Můžete použít "\{rewards}", které bude nahrazeno získanými odměnami.' + writeEndSound: '§aNapiš název zvuku, který bude na konci úkolu přehrán hráči, "null", pokud chcete výchozí nebo "none", pokud nechcete žádný:' + writeDescriptionText: '§aNapiš text, který popisuje cíl fáze:' + writeStageText: '§aNapiš text, který bude odeslán hráči na začátku kroku:' + moveToTeleportPoint: '§aJdi na místo určení teleportu.' + writeNpcName: '§aNapiš jméno NPC:' + writeNpcSkinName: '§aNapiš jméno skinu, který má být použit na NPC:' + writeQuestName: '§aNapiš jméno úkolu:' + writeCommand: '§aNapište požadovaný příkaz: (Příkaz je bez "/" a zástupného "{player}" je podporován. Bude nahrazen jménem vykonavatele.)' + writeHologramText: '§aNapište text hologramu: (Napište „none“, pokud nechcete hologram, a „null“, pokud chcete výchozí text.)' + writeQuestTimer: '§aNapište požadovaný čas (v minutách), než budete moci úlohu znovu spustit: (Pokud chcete výchozí časovač, napište „null“.)' + writeConfirmMessage: '§aNapiš potvrzovací zprávu zobrazenou když se hráč chystá spustit úkol: (Write "null", pokud chceš výchozí zprávu.)' + writeQuestDescription: '§aNapiš popis úkolu, který bude zobrazen v GUI úkolu hráče.' + writeQuestMaterial: '§aNapiš jméno materiálu pro předmět úkolu.' + requirements: + quest: '§cMusíš dokončit Quest §e{quest_name}§c!' + level: '§cTvůj level musí být {long_level}!' + job: '§cTvá úroveň pro úkol §e{job_name}§c musí být {long_level}!' + skill: '§cTvá úroveň pro dovednost §e{skill_name}§c musí být {long_level}!' + combatLevel: '§cTvoje bojová úroveň musí být {long_level}!' + money: '§cMusíš mít {money}!' + waitTime: '§cMusis počkat {time_left} , než budeš moci restartovat tento úkol!' + experience: + edited: '§aZměnil jsi zisk z {old_xp_amount} na {xp_amount} bodů.' + selectNPCToKill: '§aVyberte NPC pro zabíjení.' + regionDoesntExists: '§cTento region neexistuje. (Musíš být ve stejném světě.)' + npcDoesntExist: '§cNPC s ID {npc_id} neexistuje.' + number: + negative: '§cMusíš zadat kladné číslo!' + zero: '§cMusíte zadat jiné číslo než 0!' + invalid: '§c{input} není platné číslo.' + notInBounds: '§cVaše číslo musí být mezi {min} a {max}.' + errorOccurred: '§cDošlo k chybě, obraťte se na adminstrátor! §4§lChybový kód: {error}' + indexOutOfBounds: '§cČíslo {index} je mimo hranice! Musí být mezi {min} a {max}.' + invalidBlockData: '§cBlokdata {block_data}jsou neplatné nebo nekompatibilní s blokem {block_material}.' + invalidBlockTag: '§cNedostupný tag bloku {block_tag}.' bringBackObjects: Přineste mě zpět {items}. + inventoryFull: '§cTvůj inventář je plný, předmět byl vyhozen na zem.' + versionRequired: 'Vyžadována verze: §l{version}' + restartServer: '§7Pro zobrazení úprav restartujte váš server.' + dialogs: + skipped: '§8§o Dialog přeskočen.' + tooFar: '§7§oJsi příliš daleko od {npc_name}...' command: - adminModeEntered: '§aSpustil jsi režim správce.' - adminModeLeft: '§aOpustil jsi režim správce.' - backupCreated: '§6Úspěšně jsi vytvořil zálohy všech úkolů a informací o hráči.' - backupPlayersFailed: '§cVytváření zálohy pro všechny hráčské informace se nezdařilo.' - backupQuestsFailed: '§cVytváření zálohy pro všechny úkoly se nezdařilo.' - cancelQuest: '§6Zrušil jsi úkol {quest}.' - cancelQuestUnavailable: '§cQuest {quest} nemůže být zrušen.' + downloadTranslations: + syntax: '§cMusíte zadat jazyk ke stažení. Příklad: "/quests downloadTranslations en_US".' + notFound: '§cJazyk {lang} nebyl nalezen pro verzi {version}.' + exists: '§cSoubor {file_name} již existuje. Připojte "-overwrite" k vašemu příkazu k jeho přepsání. (/quests downloadTranslations -overwrite)' + downloaded: '§aJazyk {lang} byl stažen! §7Nyní musíte upravit soubor "/plugins/BeautyQuests/config.yml" pro změnu hodnoty §ominecraftTranslationsFile§7 s {lang}, poté restartovat server.' checkpoint: noCheckpoint: '§cNebyl nalezen žádný kontrolní bod pro úkol {quest}.' questNotStarted: '§cTento úkol aktuálně neděláš.' - help: - adminMode: '§6/{label} adminMod: §ePřepni režim správce. (Pouze pro zobrazení malých zpráv v logech.)' - create: '§6/{label} vytvořit: §eVytvoř úkol.' - edit: '§6/{label} editace: §eEdituj úkol.' - finishAll: '§6/{label} dokončil všechny : §eDokonči všechny questy hráče.' - header: '§6§lBeautyQuests — Nápověda' - list: '§6/{label} seznam: §ePodívejte se na seznam úkolů. (Pouze pro podporované verze)' - remove: '§6/{label} remove : §eVymazat úkol se zadaným id nebo kliknout na NPC pokud není definováno.' - resetPlayer: '§6/{label} resetPlayer : §eOdstraňte všechny informace o hráči.' - resetPlayerQuest: '§6/{label} resetPlayerQuest [id]: §eVymazat informace o hledání pro hráče.' - save: '§6/{label} save: §eVytvoří manuální uložení pluginu.' - seePlayer: '§6/{label} seePlayer : §eZobrazit informace o hráči.' - setItem: '§6/{label} setItem : §eSave položku hologramu.' - setStage: '§6/{label} setStage [new branch] [new stage]: §ePřeskočit aktuální scénu/spustit větev/nastavit scénu pro větev.' - start: '§6/{label} start [id]: §eVynutit spuštění úkolu.' - version: '§6/{label} verze: §ePodívejte se na aktuální verzi pluginu.' + setStage: + branchDoesntExist: '§cVětev s ID {branch_id} neexistuje.' + doesntExist: '§cStage s ID {stage_id} neexistuje.' + next: '§aFáze byla přeskočena.' + nextUnavailable: '§cMožnost "přeskočit" není k dispozici, když je hráč na konci větve.' + set: '§aFáze {stage_id} byla spuštěna.' + startDialog: + impossible: '§cDialog teď nelze spustit' + noDialog: '§cHráč nemá žádný čekající dialog.' + alreadyIn: '§cHráč již přehrává dialog.' + success: '§aZahájen dialog pro hráče {player} v úkolu {quest}!' invalidCommand: simple: '§cTento příkaz neexistuje, napište §ehelp§c.' itemChanged: '§aPředmět byl upraven. Změny se projeví po restartu.' itemRemoved: '§aHologramový předmět byl odstraněn.' - leaveAll: '§aVynutil jsi konec {success} úkolů. Chyby: {errors}' removed: '§aQuest {quest_name} byl úspěšně odstraněn.' + leaveAll: '§aVynutil jsi konec {success} úkolů. Chyby: {errors}' resetPlayer: player: '§6Všechny informace o tvých {quest_amount} úkol(ech) byly smazány hráčem {deleter_name}.' remover: '§6{quest_amount} informace o úkolu {player} byla smazány.' @@ -53,126 +114,455 @@ msg: player: '§6Všechny informace o výpravě {quest} byly smazány hráčem {deleter_name}.' remover: '§6{player} informace o úkolu {quest} byla smazány.' resetQuest: '§6Odstraněna data hledání pro {player_amount} hráčů.' + startQuest: '§6Vynutili jste spuštění úkolu {quest} pro {player}.' + startQuestNoRequirements: '§cHráč nesplňuje požadavky pro quest {quest}... Připojte "-overrideRequirements" na konec vašeho příkazu, aby obešel kontrolu požadavků.' + cancelQuest: '§6Zrušil jsi úkol {quest}.' + cancelQuestUnavailable: '§cQuest {quest} nemůže být zrušen.' + backupCreated: '§6Úspěšně jsi vytvořil zálohy všech úkolů a informací o hráči.' + backupPlayersFailed: '§cVytváření zálohy pro všechny hráčské informace se nezdařilo.' + backupQuestsFailed: '§cVytváření zálohy pro všechny úkoly se nezdařilo.' + adminModeEntered: '§aSpustil jsi režim správce.' + adminModeLeft: '§aOpustil jsi režim správce.' + resetPlayerPool: + timer: '§aResetoval jsi časovač poolu {pool} pro {player}.' + full: '§aResetovali jste data poolu {pool} pro {player}.' + startPlayerPool: + error: 'Nepodařilo se spustit pool {pool} pro {player}.' + success: 'Pool {pool} začal pro {player} Výsledek: {result}' scoreboard: - hidden: '§6Scoreboard hráče {player_name} byl schován.' - lineInexistant: '§cŘádek {line_id} neexistuje.' - lineRemoved: '§6Úspěšně jsi odstranil řádek {line_id}.' - lineReset: '§6Úspěšně jsi resetoval řádek {line_id}.' lineSet: '§6Řádek {line_id} byl úspěšně upraven.' + lineReset: '§6Úspěšně jsi resetoval řádek {line_id}.' + lineRemoved: '§6Úspěšně jsi odstranil řádek {line_id}.' + lineInexistant: '§cŘádek {line_id} neexistuje.' resetAll: '§6Úspěšně jsi obnovil tabulku skóre hráče {player_name}.' + hidden: '§6Scoreboard hráče {player_name} byl schován.' shown: '§6Scoreboard hráče {player_name} byl zobrazen.' - setStage: - branchDoesntExist: '§cVětev s ID {branch_id} neexistuje.' - doesntExist: '§cStage s ID {stage_id} neexistuje.' - next: '§aFáze byla přeskočena.' - nextUnavailable: '§cMožnost "přeskočit" není k dispozici, když je hráč na konci větve.' - set: '§aFáze {stage_id} byla spuštěna.' - startQuest: '§6Vynutil jsi spuštění Questu {quest} (UUID: {player}).' + own: + hidden: '§6Tvá tabulka questů je nyní skryta.' + shown: '§6Tvá tabulka questů je znovu zobrazena.' + help: + header: '§6§lBeautyQuests — Nápověda' + create: '§6/{label} vytvořit: §eVytvoř úkol.' + edit: '§6/{label} editace: §eEdituj úkol.' + remove: '§6/{label} remove : §eVymazat úkol se zadaným id nebo kliknout na NPC pokud není definováno.' + finishAll: '§6/{label} dokončil všechny : §eDokonči všechny questy hráče.' + setStage: '§6/{label} setStage [new branch] [new stage]: §ePřeskočit aktuální scénu/spustit větev/nastavit scénu pro větev.' + startDialog: '§6/{label} startDialog : §eZačne čekající dialog pro fázi NPC nebo úvodní dialog pro quest.' + resetPlayer: '§6/{label} resetPlayer : §eOdstraňte všechny informace o hráči.' + resetPlayerQuest: '§6/{label} resetPlayerQuest [id]: §eVymazat informace o hledání pro hráče.' + seePlayer: '§6/{label} seePlayer : §eZobrazit informace o hráči.' + reload: '§6/{label} reload: §eUloží a znovu načte konfiguraci a soubory. (§cdeprecated§e)' + start: '§6/{label} start [id]: §eVynutit spuštění úkolu.' + setItem: '§6/{label} setItem : §eSave položku hologramu.' + setFirework: '§6/{label} setFirework: §eUpraví výchozí končící ohňostroj' + adminMode: '§6/{label} adminMod: §ePřepni režim správce. (Pouze pro zobrazení malých zpráv v logech.)' + version: '§6/{label} verze: §ePodívejte se na aktuální verzi pluginu.' + downloadTranslations: '§6/{label} downloadTranslations : §eStáhne vanilla soubor překladu' + save: '§6/{label} save: §eVytvoří manuální uložení pluginu.' + list: '§6/{label} seznam: §ePodívejte se na seznam úkolů. (Pouze pro podporované verze)' + typeCancel: '§aNapište "cancel" pro návrat k poslednímu textu.' editor: - already: '§cJiž jsi v editoru.' blockAmount: '§aNapiš množství bloků:' - blockData: '§aNapište bloková data (dostupná bloková data: {available_datas}):' blockName: '§aNapište název bloku:' - dialog: - cleared: '§a{amount} odstranilo zprávy.' - help: - header: '§6§lBeautyQuests - nápověda pro editor dialogů' - list: '§6Seznam: §evšech zpráv.' - remove: '§6remove : §eOdebrat zprávu.' - syntaxRemove: '§cSprávná sytax: odstranit ' + blockData: '§aNapište bloková data (dostupná bloková data: {available_datas}):' + blockTag: '§aNapište tag bloku (dostupné tagy: §7{available_tags}§a):' + typeBucketAmount: '§aNapiš množství kbelíků k naplnění:' + typeDamageAmount: 'Napište množství poškození, které musí hráč udělit:' + goToLocation: '§aPřejít na požadovanou polohu pro stage.' + typeLocationRadius: '§aNapsat požadovanou vzdálenost od polohy:' + typeGameTicks: '§aNapište požadované herní ticks' + already: '§cJiž jsi v editoru.' + stage: + location: + typeWorldPattern: '§aNapište regex pro jména světů:' enter: - subtitle: '§6Napiš "/quests exitEditor" pro vynucení ukončení editoru.' title: '§6~ Mód editoru ~' - goToLocation: '§aPřejít na požadovanou polohu pro stage.' - itemCreator: - invalidBlockType: '§cNeplatný typ bloku.' - itemName: '§aNapiš název předmětu:' - unknownBlockType: '§cNeznámý typ bloku.' - unknownItemType: '§cNeznámý typ předmětu.' - mythicmobs: - disabled: '§cMythicMobs jsou vypnuty.' + subtitle: '§6Napiš "/quests exitEditor" pro vynucení ukončení editoru.' + list: '§c⚠ §7Zadali jste editor "seznamu". Použij "add" pro přidání řádků. Použijte "help" (bez lomítka) pro nápovědu. §e§lNapište "close" pro zavření editoru.' + chat: '§6Momentálně jste v režimu editoru. Napište "/quests exitEditor" pro vynucení opuštění editoru. (Zcela nedoporučujeme, zvažte použití příkazů jako "close" nebo "cancel" pro návrat k předchozímu GUI.)' npc: - choseStarter: '§aVyberte NPC u kterého začíná Quest.' enter: '§aKlikni na NPC, nebo napiš "cancel".' + choseStarter: '§aVyberte NPC u kterého začíná Quest.' notStarter: '§cU tohoto NPC quest nezačíná.' text: argNotSupported: '§cArgument {arg} není podporován.' - chooseJobRequired: '§aNapiš jméno požadované práce:' chooseLvlRequired: '§aNapiš požadované množství úrovní:' + chooseJobRequired: '§aNapiš jméno požadované práce:' + choosePermissionRequired: '§aNapište požadované oprávnění pro spuštění úkolu:' + choosePermissionMessage: '§aMůžete zvolit zprávu odmítnutí, pokud hráč nemá požadované oprávnění. (Pro přeskočení tohoto kroku napište "null".)' + choosePlaceholderRequired: + identifier: '§aNapiš název požadovaného zástupce bez znaku procenta:' + value: '§aNapište požadovanou hodnotu pro zástupce §e%§e{placeholder}§e%§a:' + chooseSkillRequired: '§aNapište název požadované dovednosti:' chooseMoneyRequired: '§aNapište částku požadovaných peněz:' - chooseObjectiveRequired: '§aNapiš název objektu.' reward: permissionName: '§aNapiš jméno oprávnění.' + permissionWorld: '§aNapiš svět, ve kterém bude oprávnění upraveno, nebo "null", pokud to chcete globálně.' + money: '§aNapište částku obdržených peněz:' + wait: '§aNapište dobu čekání herních ticků (1 sekunda = 20 ticků)' + random: + min: '§aNapište minimální odměnu která bude udělena hráči (včetně).' + max: '§aNapište maximální odměnu která bude udělena hráči (včetně).' + chooseObjectiveRequired: '§aNapiš název objektu.' + chooseObjectiveTargetScore: '§aNapište cílové skóre pro daný cíl.' + itemCreator: + itemName: '§aNapiš název předmětu:' + unknownItemType: '§cNeznámý typ předmětu.' + unknownBlockType: '§cNeznámý typ bloku.' + invalidBlockType: '§cNeplatný typ bloku.' + dialog: + syntaxRemove: '§cSprávná sytax: odstranit ' + cleared: '§a{amount} odstranilo zprávy.' + help: + header: '§6§lBeautyQuests - nápověda pro editor dialogů' + remove: '§6remove : §eOdebrat zprávu.' + list: '§6Seznam: §evšech zpráv.' + mythicmobs: + disabled: '§cMythicMobs jsou vypnuty.' textList: syntax: '§cSprávná syntaxe: ' - typeBucketAmount: '§aNapiš množství kbelíků k naplnění:' - typeGameTicks: '§aNapište požadované herní ticks' - typeLocationRadius: '§aNapsat požadovanou vzdálenost od polohy:' - errorOccurred: '§cDošlo k chybě, obraťte se na adminstrátor! §4§lChybový kód: {error}' - experience: - edited: '§aZměnil jsi zisk z {old_xp_amount} na {xp_amount} bodů.' - indexOutOfBounds: '§cČíslo {index} je mimo hranice! Musí být mezi {min} a {max}.' - invalidBlockData: '§cBlokdata {block_data}jsou neplatné nebo nekompatibilní s blokem {block_material}.' - inventoryFull: '§cTvůj inventář je plný, předmět byl vyhozen na zem.' - moveToTeleportPoint: '§aJdi na místo určení teleportu.' - npcDoesntExist: '§cNPC s ID {npc_id} neexistuje.' - number: - invalid: '§c{input} není platné číslo.' - negative: '§cMusíš zadat kladné číslo!' - zero: '§cMusíte zadat jiné číslo než 0!' - pools: - allCompleted: '§7Všechny úkoly byly dokončeny!' - maxQuests: '§cNemůžeš mít zároveň více než {pool_max_quests} úkol(ů)...' - noAvailable: '§7Žádný další úkol není k dispozici...' - noTime: '§cMusíš počkat {time_left} než budeš dělat jiný úkol.' - quest: - alreadyStarted: '§cTvůj úkol byl už zahájen!' - cancelling: '§cProces vytváření úkolu byl zrušen.' - createCancelled: '§cVytváření nebo úprava úkolu byla přerušena jiným pluginem!' - created: '§aBlahopřejeme! Vytvořil jsi nový úkol §e{quest}§a, který obsahuje {quest_branches} větev(e)!' - editCancelling: '§cProces úpravy úkolu byl zrušen.' - edited: '§aBlahopřejeme! Upravil jsi úkol §e{quest}§a, který obsahuje nyní {quest_branches} větev(e)!' - finished: - base: '§aBlahopřejeme! Dokončil jsi svůj úkol §e{quest_name}§a!' - obtain: '§aObdržel jsi {rewards}!' - invalidID: '§cÚkol s ID {quest_id} neexistuje.' - started: '§aTvůj úkol právě začíná §r§e{quest_name}§o§6!' - questItem: - craft: '§cNemůžeš použít item z úkolu k výrobě!' - drop: '§cPředmět, který je součástí tvého úkolu, není možné zahodit!' - quests: - checkpoint: '§7Dosáhl jsi kontrolního bodu úkolu!' - failed: '§cSelhal jsi v plnění úkolu {quest_name}' - maxLaunched: '§cNemůžeš mít více než {quests_max_amount} úkol zároveň...' - updated: '§7Úkol §e{quest_name}§7 a jeho nastavení bylo aktualizováno.' - regionDoesntExists: '§cTento region neexistuje. (Musíš být ve stejném světě.)' - requirements: - combatLevel: '§cTvoje bojová úroveň musí být {long_level}!' - job: '§cTvá úroveň pro úkol §e{job_name}§c musí být {long_level}!' - level: '§cTvůj level musí být {long_level}!' - money: '§cMusíš mít {money}!' - quest: '§cMusíš dokončit Quest §e{quest_name}§c!' - skill: '§cTvá úroveň pro dovednost §e{skill_name}§c musí být {long_level}!' - waitTime: '§cMusis počkat {time_left} , než budeš moci restartovat tento úkol!' - selectNPCToKill: '§aVyberte NPC pro zabíjení.' - stageMobs: - listMobs: '§aMusíš zabít {mobs}' - typeCancel: '§aNapište "cancel" pro návrat k poslednímu textu.' - writeChatMessage: '§aNapiš povinnou zprávu: (Přidat "{SLASH}na začátek, pokud chceš příkaz.)' - writeCommand: '§aNapište požadovaný příkaz: (Příkaz je bez "/" a zástupného znaku "{PLAYER}je podporován. Bude nahrazeno jménem vykonavatele.)' - writeConfirmMessage: '§aNapiš potvrzovací zprávu zobrazenou když se hráč chystá spustit úkol: (Write "null", pokud chceš výchozí zprávu.)' - writeDescriptionText: '§aNapiš text, který popisuje cíl fáze:' - writeHologramText: '§aNapište text hologramu: (Napište „none“, pokud nechcete hologram, a „null“, pokud chcete výchozí text.)' - writeMobAmount: '§aNapiš počet mobů, k zabíjení:' - writeMobName: '§aNapiš vlastní jméno moba, kterého budeš zabíjet:' - writeNPCText: '§aNapiš dialog který NPC řekně hráči: (Napiš "help" pro získání pomoci)' - writeNpcName: '§aNapiš jméno NPC:' - writeNpcSkinName: '§aNapiš jméno skinu, který má být použit na NPC:' - writeQuestDescription: '§aNapiš popis úkolu, který bude zobrazen v GUI úkolu hráče.' - writeQuestMaterial: '§aNapiš jméno materiálu pro předmět úkolu.' - writeQuestName: '§aNapiš jméno úkolu:' - writeQuestTimer: '§aNapište požadovaný čas (v minutách), než budete moci úlohu znovu spustit: (Pokud chcete výchozí časovač, napište „null“.)' - writeRegionName: '§aNapiš název regionu vyžadovaného pro krok:' - writeStageText: '§aNapiš text, který bude odeslán hráči na začátku kroku:' - writeStartMessage: '§aNapište zprávu, která bude odeslána na začátku úkolu, „null“, pokud chcete výchozí, nebo „none“, pokud nechcete žádnou:' - writeXPGain: '§aNapiš množství bodů zkušenosti, které hráč získá: (poslední hodnota: {xp_amount})' + writeCommandDelay: '§aNapište požadované zpoždění příkazu v tikách.' +advancement: + notStarted: Není spuštěno! +inv: + validate: '§bValidovat' + cancel: '§c§lStorno' + addObject: Přidat objekt + confirm: + name: Jste si jistý? + 'yes': '§aPotvrdit' + 'no': '§cZrušit' + create: + findNPC: '§aNajít NPC' + bringBack: '§aPřinést zpět předměty' + findRegion: '§aNajít region' + killMobs: '§aZabít monstra' + mineBlocks: '§aRozbít bloky' + placeBlocks: '§aPostav bloky' + talkChat: '§aPsát do chatu' + fish: '§aChytat ryby' + craft: '§aVyrobit předmět' + bucket: '§aVyplnit kbelíky' + selectRegion: '§7Vyberte region' + toggleRegionExit: Při odchodu + stageStartMsg: '§eUpravit úvodní zprávu' + selectBlockLocation: '§eVybrat umístění bloku' + selectBlockMaterial: '§eVyberte blok materiálu' + leftClick: Kliknutí musí být levým tlačítkem + editFishes: '§eUpravte ryby k chytání' + editItemsToMelt: '§eUpravte předměty pro tání' + editItemsToEnchant: '§eUpravte předměty k zaklínání' + editItem: '§eUpravte předměty pro tání' + editBucketType: '§eUpravte typ kbelku k vyplnění' + editBucketAmount: '§eUpravte typ kbelku k vyplnění' + editLocation: '§eUpravit polohu' + editRadius: '§eUpravit vzdálenost od polohy' + currentRadius: '§eAktuální vzdálenost: §6{radius}' + changeTicksRequired: '§eJe vyžadována změna přehraných ticků' + changeEntityType: '§eZměnit typ entity' + stage: + location: + worldPattern: '§aNastavte vzor názvu světa §d(ADVANCED)' + worldPatternLore: 'Pokud chcete, aby byla fáze dokončena pro kterýkoliv svět odpovídající určitému vzoru, zadejte zde regex (regulární výraz).' + death: + causes: '§aNastavte příčiny smrti §d(ADVANCED)' + anyCause: Jakákoli příčina smrti + setCauses: 'Příčiny úmrtí {causes_amount}' + dealDamage: + damage: '§ePoškození k obchodu' + targetMobs: '§cZranit stvoření' + eatDrink: + items: '§eUpravte předměty pro jídlo nebo pití' + playTime: + changeTimeMode: 'Změnit strategii počítání času' + modes: + online: 'Přehrávač musí být připojen k serveru' + offline: 'Přehrávač může být offline, ale server musí být spuštěn, aby mohl počítat čas' + realtime: 'Čas se počítá i v případě, že hráč a server jsou offline' + stages: + name: Vytvořit fáze + nextPage: '§eDalší stránka' + laterPage: '§ePředchozí stránka' + endingItem: '§eUpravit koncové odměny' + descriptionTextItem: '§eUpravit popis' + regularPage: '§aPravidelné fáze' + branchesPage: '§dVětev' + previousBranch: '§eZpět do předchozí větve' + newBranch: '§ePřejít na novou větev' + validationRequirements: '§eOvěřovací požadavky' + validationRequirementsLore: Všechny požadavky musí odpovídat hráči, který se pokouší dokončit fázi. Pokud ne, fáze nemůže být dokončena. + details: + hologramLaunch: '§eUpravit hologram položky "spustit"' + hologramLaunchLore: Hologram zobrazený nad hlavou Startovní NPC, když hráč může začít úkol. + hologramLaunchNo: '§eUpravit hologram položky "spustit"' + hologramLaunchNoLore: Hologram zobrazený nad hlavou Startovní NPC, když hráč může začít úkol. + customConfirmMessage: '§eUpravit potvrzovací zprávu úkolu' + customConfirmMessageLore: Zpráva zobrazená v GUI potvrzení, když se hráč chystá zahájit úkol. + customDescription: '§eUpravit popis' + customDescriptionLore: Popis zobrazený níže v názvu výpravy v GUI. + name: Detaily poslední výpravy + multipleTime: + itemName: Přepnout opakovatelné + requirements: '{amount} požadavky(y)' + rewards: '{amount} odměna(y)' + actions: '{amount} akce' + rewardsLore: Akce provedené při ukončení úkolu. + customMaterial: '§eUpravit materiál úkolu' + customMaterialLore: Položka zástupce tohoto úkolu v nabídce úkolů. + failOnDeath: Selhání při smrti + failOnDeathLore: Bude výprava zrušena, až hráč naftu? + questPool: '§eÚkolový bazén' + questPoolLore: Připojit tento úkol k úložišti + firework: '§dKonec ohňostroje' + fireworkLore: Ohňostroj spuštěn, když hráč dokončí hledání + fireworkLoreDrop: Sem přetáhněte vlastní ohňostroj + visibility: '§bViditelnost úkolu' + visibilityLore: Zvolte, ve kterých kartách menu se zobrazí výprava, a pokud je výprava viditelná na dynamických mapách. + keepDatas: Zachovat data hráčů + keepDatasLore: |- + Vynutit uchování dat hráčů, i když fáze byly upraveny. + §c§lWARNING §c- povolení této možnosti může poškodit data hráčů. + loreReset: '§ePokrok všech hráčů bude obnoven' + optionValue: '§8Hodnocení: §7{value}' + defaultValue: '§8(výchozí hodnota)' + requiredParameter: '§7Povinný parametr' + itemsSelect: + name: Upravit položku + none: |- + §aPřesuňte předmět sem nebo + klikněte pro otevření editoru položek. + itemSelect: + name: Vyberte položky + npcCreate: + name: Vytvořit NPC + setName: '§eUpravit název NPC' + setSkin: '§eUpravit název NPC' + setType: '§eUpravit název NPC' + move: + itemName: '§ePřesunout' + itemLore: '§aZměň umístění NPC.' + moveItem: '§a§lOvěřit místo' + npcSelect: + name: Vybrat nebo vytvořit? + selectStageNPC: '§eVybrat existující NPC' + createStageNPC: '§Vytvořit NPC' + entityType: + name: eZměnit typ entity + chooseQuest: + name: Který úkol? + menu: '§aQuests Menu' + menuLore: Vrátí tě do nabídky úkolů. + mobs: + name: Vybrat stvoření + none: '§aKlepnutím přidáte stvoření.' + editAmount: Upravit částku + editMobName: eUpravit název NPC + setLevel: Nastavit minimální úroveň + mobSelect: + name: Nastavit typ monstra + bukkitEntityType: '§eZměnit typ entity' + mythicMob: '§6Vyber Mythic stvoření' + epicBoss: '§6Vyber Epického šéfa' + boss: '§6Vyber Epického šéfa' + advancedSpawners: '§6Vyber šikovné stvoření' + stageEnding: + locationTeleport: '§eUpravit polohu teleportu' + block: + blockName: '§bVlastní název bloku' + blockData: '§dBlockdata (pokročilé)' + blockTag: '§dTag (pokročilý)' + blockTagLore: 'Vyberte značku, která popisuje seznam možných bloků. Tagy lze přizpůsobit pomocí datapacků. Seznam značek můžete najít na Minecraftu wiki.' + blocksList: + name: Vybrat bloky + addBlock: '§aKlepnutím přidáte stvoření.' + blockAction: + name: eVybrat umístění bloku + location: '§eVybrat umístění bloku' + material: '§eVyberte blok materiálu' + buckets: + name: Typ kbelíku + permission: + name: Vyberte oprávnění + perm: '§aPráva' + world: '§aWorld' + worldGlobal: '§lGlobál' + remove: Odstranit oprávnění? + removeLore: '§7Oprávnění bude odebráno\n§7místo vydání.' + permissionList: + name: Oprávnění Seznam + removed: '§eVybráno z: §6{permission_removed}' + world: '§eWorld: §6{permission_world}' + classesRequired.name: bTřídy jsou vyžadovány + classesList.name: Seznam tříd + factionsRequired.name: bFakce jsou vyžadovány + factionsList.name: Seznam akcí + poolsManage: + name: eÚkolový bazén + itemName: '§aPool {pool}' + poolNPC: '§8NPC: §7{pool_npc_id}' + poolMaxQuests: '§8Max úkolů: §7{pool_max_quests}' + poolQuestsPerLaunch: '§8Úkoly zadané na spuštění: §7{pool_quests_per_launch}' + poolRedo: '§8Můžeš znovu provést dokončené úkoly: §7{pool_redo}' + poolTime: '§8Čas mezi úkoly: §7{pool_time}' + poolHologram: '§8Hologram text: §7{pool_hologram}' + poolAvoidDuplicates: '§8Vyhnout se duplicitě: §7{pool_duplicates}' + poolQuestsList: '§7{pool_quests_amount} §8questy: §7{pool_quests}' + create: '§aVytvoř sbor hledání' + edit: '§e> §6§oUpravte pool... §e<' + choose: '§e> §6Vyber tento bazén §e<' + poolCreation: + name: Vytváření sdružení úkolů + hologramText: '§ePool vlastní hologram' + maxQuests: '§aMax úkolů' + questsPerLaunch: '§aÚkoly byly spuštěny při spuštění' + time: '§8Čas mezi úkoly' + redoAllowed: Je povoleno znovu + avoidDuplicates: Vyhnout se duplicitám + avoidDuplicatesLore: '§8> §7Pokusit se vyhnout\n stejné hledání znova a' + requirements: '§bPožadavky na zahájení výpravy' + poolsList.name: eÚkolový bazén + itemComparisons: + name: Porovnání položek + bukkit: Nativní porovnání Bukkit + bukkitLore: "Používá výchozí systém pro porovnávání položek.\nPorovnává materiál, odolnost, nbt tagy..." + customBukkit: Nativní porovnání Bukkit +scoreboard: + asyncEnd: '§ex' + stage: + region: '§eNajdi oblast §6{region_id}' + npc: '§ePromluv s NPC §6{dialog_npc_name}' + items: '§ePřines předměty k §6{dialog_npc_name}§e: {items}' + mobs: '§eZabij §6{mobs}' + mine: '§eVytěž {blocks}' + placeBlocks: '§ePostav bloky' + chat: '§eNapiš §6{text}' + interact: '§eKlikni na blok na §6{x} {y} {z}' + interactMaterial: '§eKlikni na blok §6{block}' + fish: '§eVylov §6{items}' + melt: '§eVypeč §6{items}' + enchant: '§eOčaruj §6{items}' + craft: '§eVyrob §6{items}' + bucket: '§eNaplň §6{buckets}' + location: '§eBěž na §6{target_x}§e, §6{target_y}§e, §6{target_z}§e ve světě §6{target_world}' + playTimeFormatted: '§eHraj §6{time_remaining_human}' + breed: '§eRozmnož §6{mobs}' + tame: '§eOchoč §6{mobs}' + die: '§cZemři' + dealDamage: + any: '§cUděl {damage_remaining} poškození' + mobs: '§cUděl {damage_remaining} poškození stvoření {target_mobs}' + eatDrink: '§eKonzumuj §6{items}' +indication: + startQuest: '§7Chceš zahájit úkol {quest_name}?' + closeInventory: '§7Opravdu chcete zavřít GUI?' + cancelQuest: '§7Opravdu chceš zrušit úkol {quest_name}?' + removeQuest: '§7Opravdu chcete odstranit quest {quest}?' + removePool: '§7Opravdu chceš odebrat pool {pool}?' +description: + requirement: + title: '§8§lPožadavky:' + level: 'Úroveň {short_level}' + jobLevel: 'Úroveň {short_level} pro {job_name}' + combatLevel: 'Bojová úroveň {short_level}' + skillLevel: 'Úroveň {short_level} pro {skill_name}' + class: 'Třída {class_name}' + faction: 'Frakce {faction_name}' + quest: 'Dokončit úkol §e{quest_name}' + reward: + title: '§8§lOdměny:' +misc: + format: + prefix: '§6<§e§lQuesty§r§6> §r' + npcText: '§6[{message_id}/{message_count}] §e§l{npc_name_message}:§r§e {text}' + selfText: '§6[{message_id}/{message_count}] §e§l{player_name}:§r§e {text}' + time: + weeks: '{weeks_amount} týdnů' + days: '{days_amount} dní' + hours: '{hours_amount} hodin' + minutes: '{minutes_amount} minut' + lessThanAMinute: 'pár vteřin' + stageType: + region: Najít oblast + npc: Najít NPC + items: Přinést zpět předměty + mobs: Zabít stvoření + mine: Rozbít bloky + placeBlocks: Položit bloky + chat: Napsat do chatu + interact: Interagovat s blokem + interactLocation: Interagovat s blokem na místě + Fish: Chytit ryby + Melt: Vypéct předměty + Enchant: Očarovat předměty + Craft: Vyrobit předmět + Bucket: Naplnit kbelík + location: Najít lokaci + playTime: Doba hraní + breedAnimals: Rozmnožit zvířata + tameAnimals: Ochočit zvířata + die: Zemřít + dealDamage: Udělit poškození + eatDrink: Sníst nebo vypít + comparison: + equals: rovno {number} + different: jiný než {number} + less: striktně nižší než {number} + lessOrEquals: méně než {number} + greater: striktně větší než {number} + greaterOrEquals: větší než {number} + requirement: + logicalOr: '§dLogické OR (požadavky)' + skillAPILevel: '§bSkillAPI úroveň je vyžadována' + class: '§bTřídy jsou vyžadovány' + faction: '§bFakce jsou vyžadovány' + jobLevel: '§bÚroveň práce je vyžadována' + combatLevel: '§bBojová úroveň je vyžadována' + experienceLevel: '§bÚroveň zkušenosti je vyžadována' + permissions: '§3Oprávnění Vyžadováno' + scoreboard: '§dSkóre je vyžadováno' + region: '§dOblast je vyžadovaná' + placeholder: '§bHodnota zástupce je vyžadována' + quest: '§Úkol je vyžadován' + mcMMOSkillLevel: '§dÚroveň dovednosti je vyžadována' + money: '§dPeníze jsou vyžadovány' + equipment: '§eVybavení je vyžadováno' + reward: + skillApiXp: SkillAPI XP odměna + bucket: + water: Kbelík vody + lava: Kbelík lávy + milk: Kbelík mléka + snow: Kbelík sněhu + click: + right: Pravé kliknutí + left: levé kliknutí + shift-right: Shift a pravé kliknutí + shift-left: Shift a levé kliknutí + middle: Prostřední tlačítko + amounts: + items: '{items_amount} item(ů)' + comparisons: '{comparisons_amount} srovnání' + dialogLines: '{lines_amount} řádků' + permissions: '{permissions_amount} oprávnění' + mobs: '{mobs_amount} stvoření' + xp: '{xp_amount} bod(ů) zkušenosti' + ticks: '{ticks} ticků' + location: |- + Lokace: {x} {y} {z} + Svět: {world} + questItemLore: '§e§oÚkolový předmět' + hologramText: '§8§lÚkolové NPC' + poolHologramText: '§eNový úkol je k dispozici!' + entityType: '§eTyp entity: {entity_type}' + entityTypeAny: '§eJakákoli entita' + enabled: Zapnuto + disabled: Vypnuto + unknown: neznámý + notSet: '§cnenastaveno' + removeRaw: Odebrat + reset: Resetovat + or: nebo + amount: '§ePočet: {amount}' + 'yes': 'Ano' + 'no': 'Ne' + and: a diff --git a/core/src/main/resources/locales/de_DE.yml b/core/src/main/resources/locales/de_DE.yml index f96cd390..acf77eeb 100644 --- a/core/src/main/resources/locales/de_DE.yml +++ b/core/src/main/resources/locales/de_DE.yml @@ -3,7 +3,7 @@ msg: quest: finished: base: '§aGlückwunsch! Du hast die Quest §e{quest_name}§a abgeschlossen!' - obtain: '§aDu erhälst {rewards}!' + obtain: '§aDu erhältst {rewards}!' started: '§aDu hast die Quest §r§e{quest_name}§o§6 gestartet!' created: '§aGlückwunsch! Du hast die Quest §e{quest}§a mit {quest_branches} Zweig(en) erstellt!' edited: '§aGlückwunsch! Du hast die Quest §e{quest}§a bearbeitet, die jetzt {quest_branches} Zweig(e) enthält!' @@ -20,7 +20,7 @@ msg: checkpoint: '§7Quest-Checkpoint erreicht!' failed: '§cDu hast die Quest {quest_name} fehlgeschlagen...' pools: - noTime: '§cDu musst warten, bevor du eine andere Quest absolvieren kannst.' + noTime: '§cDu musst {time_left} warten, bevor du eine andere Quest absolvieren kannst.' allCompleted: '§7Du hast alle Quests abgeschlossen!' noAvailable: '§7Es ist keine Quest mehr verfügbar...' maxQuests: '§cDu kannst nicht mehr als {pool_max_quests} Quest(s) gleichzeitig haben...' @@ -35,8 +35,10 @@ msg: writeXPGain: '§aSchreibe die Menge an Erfahrungspunkten, die der Spieler erhalten wird: (Letzter Wert: {xp_amount})' writeMobAmount: '§aSchreibe die zu tötende Mob‐Menge:' writeMobName: '§aSchreibe den benutzerdefinierten Namen des zu tötenden Mobs:' + writeChatMessage: '§aSchreibe die benötigte Nachricht: (Füge „\{SLASH}” zum Anfang hinzu, wenn du einen Befehl möchtest.)' writeMessage: '§aSchreibe die Nachricht die an den Spieler gesendet wird' writeStartMessage: '§aSchreibe die Nachricht, die zu Beginn der Quest gesendet wird, "null", wenn du die Standardnachricht wünschst, oder "none", wenn du dir keine Nachricht wünschst:' + writeEndMsg: '§aSchreibe die Nachricht, die am Ende der Quest gesendet wird, "null", wenn du die Standardnachricht möchtest oder "none" wenn du keine möchtest. Du kannst "\{rewards}" verwenden, was durch die zu erhaltende Belohnungen ersetzt wird.' writeEndSound: '§aSchreibe den Tonnamen, der am Ende der Quest dem Spieler abgespielt wird, "null" wenn Sie die Standardeinstellung oder "keine" wollen, wenn Sie keine wollen:' writeDescriptionText: '§aSchreibe einen Text, der das Ziel des Schrittes beschreibt:' writeStageText: '§aSchreibe den am Anfang des Schrittes zum Spieler gesendete Text:' @@ -715,6 +717,7 @@ misc: playTime: Spielzeit breedAnimals: Züchte Tiere tameAnimals: Zähme Tiere + die: Sterben comparison: equals: gleich wie {number} different: anders als {number} @@ -737,6 +740,8 @@ misc: quest: '§aQuest benötigt' mcMMOSkillLevel: '§dBenötigtes Fertigkeitslevel' money: '§dGeld benötigt' + reward: + skillApiXp: SkillAPI XP Belohnung bucket: water: Wassereimer lava: Lavaeimer @@ -748,7 +753,17 @@ misc: shift-right: Shift-Rechtsklick shift-left: Shift-Linksklick middle: Mittelklick + amounts: + items: '{items_amount} Item(s)' + comparisons: '{comparisons_amount} Vergleich(e)' + dialogLines: '{lines_amount} Zeile(n)' + permissions: '{permissions_amount} Berechtigung(en)' + mobs: '{mobs_amount} Mob(s)' + xp: '{xp_amount} Erfahrungspunkt(e)' ticks: '{ticks} Ticks' + location: |- + Position: {x} {y} {z} + Welt: {world} questItemLore: '§e§oQuest‐Item' hologramText: '§8§lQuest‐NPC' poolHologramText: '§eNeue Quest verfügbar!' diff --git a/core/src/main/resources/locales/es_ES.yml b/core/src/main/resources/locales/es_ES.yml index a7bed459..9223463b 100644 --- a/core/src/main/resources/locales/es_ES.yml +++ b/core/src/main/resources/locales/es_ES.yml @@ -1,788 +1,777 @@ --- -advancement: - finished: Finalizado - notStarted: No comenzado -description: - requirement: - class: Clase {class_name} - combatLevel: Nivel de combate {short_level} - faction: Facción {faction_name} - jobLevel: Nivel {short_level} de {job_name} - level: Nivel {short_level} - quest: Finalizar misión §e{quest_name} - skillLevel: Nivel {short_level} de {skill_name} - title: '§8§lRequisitos:' - reward: - title: '§8§lRecompensas:' -indication: - cancelQuest: '§7Estás seguro de que quieres cancelar la misión {quest_name}?' - closeInventory: '§7¿Estás seguro de que quieres cerrar la GUI?' - removeQuest: '§7¿Estás seguro de que quieres eliminar la misión {quest}?' - startQuest: '§7Quieres iniciar la misión {quest_name}?' -inv: - addObject: '§aAñadir un objeto' - block: - blockData: '§dBlockdata (avanzado)' - blockTag: '§dEtiqueta (avanzado)' - blockTagLore: Elija una etiqueta que describa una lista de posibles bloques. Las etiquetas se pueden personalizar usando datapacks. Puedes encontrar la lista de etiquetas en la wiki de Minecraft. - materialNotItemLore: El bloque elegido no puede mostrarse como objeto. Todavía se almacena correctamente como {block_material}. - name: Elegir bloque - blockAction: - location: '§eSelecciona una ubicación precisa' - material: '§eSelecciona un material de bloque' - name: Seleccionar acción de bloque - blocksList: - addBlock: '§aClick para añadir un bloque.' - name: Seleccionar bloques - buckets: - name: Tipo de cubo - cancel: '§c§lCancelar' - cancelActions: - name: Cancelar acciones - checkpointActions: - name: Acciones de puntos de control - chooseAccount: - name: '¿Qué cuenta?' - chooseQuest: - menu: '§aMenú de Misiones' - menuLore: Te lleva a tu Menú de Misiones. - name: '¿Qué misión?' - classesList.name: Lista de clases - classesRequired.name: Clases requeridas - command: - console: Consola - delay: '§bRetraso' - name: Comando - parse: Analizar marcadores de posición (placeholders) - value: '§eComando' - commandsList: - name: Lista de comandos - value: '§Comando: {command_label}' - confirm: - name: Estas seguro? - 'no': Cancelar - 'yes': '§aConfirmar' - create: - NPCSelect: '§eElegir o crear NPC' - NPCText: '§eEditar dialogo' - breedAnimals: '§aReproducir Animales' - bringBack: Trae devuelta ciertos items - bucket: Llena cubetas - cancelMessage: Cancelar envío - cantFinish: '§7¡Debes crear al menos una etapa antes de terminar la creación de misión!' - changeEntityType: '§eCambiar tipo de entidad' - changeTicksRequired: '§eCambiar ticks reproducidos requeridos' - craft: Craftea items - currentRadius: '§eDistancia actual: §6{radius}' - dealDamage: '§cInflige daño a los mobs' - death: '§cMuerte' - eatDrink: '§aIngiere o bebe alimentos o pociones' - editBlocksMine: '§eEditar bloques a romper' - editBlocksPlace: '§eEditar bloques a colocar' - editBucketAmount: '§eEditar cantidad de cubos a rellenar' - editBucketType: '§eEditar tipo de cubo para rellenar' - editFishes: '§eEditar peces para capturar' - editItem: '§eEditar elemento a crear' - editItemsToEnchant: '§eEditar objetos para encantar' - editItemsToMelt: '§eEditar objetos para cocinar' - editLocation: '§eEditar ubicación' - editMessageType: '§eEditar mensaje a escribir' - editMobsKill: '§eEditar mobs a matar' - editRadius: '§eEditar distancia de la ubicación' - enchant: '§dEncantar objetos' - findNPC: Encuentra al NPC - findRegion: Encuentra una región - fish: Pesca peces - hideClues: Ocultar partículas y hologramas - ignoreCase: Ignorar el caso del mensaje - interact: Interactúa con el bloque - killMobs: Asesina mobs - leftClick: Haga clic izquierdo - location: Dirígete a la localización - melt: '§6Cocinar objetos' - mineBlocks: Rompe bloques - mobsKillFromAFar: Necesita ser asesinado con proyectil - placeBlocks: Coloca bloques - playTime: '§eTiempo de juego' - preventBlockPlace: Evita que los jugadores rompan sus propios bloques - replacePlaceholders: Reemplazar {PLAYER} y marcadores de posición de PAPI - selectBlockLocation: '§eSelecciona la ubicación del bloque' - selectBlockMaterial: '§eSeleccionar material de bloque' - selectItems: '§eEditar elementos requeridos' - selectItemsComparisons: '§eSeleccionar comparaciones de objetos (AVANZADO)' - selectItemsMessage: '§eEditar mensaje preguntando' - selectRegion: '§7Elegir región' - stage: - dealDamage: - damage: '§eDaño para infligir' - targetMobs: '§cMobs para dañar' - death: - anyCause: Cualquier causa de muerte - causes: '§aEstablecer causas de muerte §d(AVANZADO)' - setCauses: '{causes_amount} causa(s) de muerte' - eatDrink: - items: '§eEditar items para comer o beber' - location: - worldPattern: '§aEstablecer un patrón del nombre del mundo §d(AVANZADO)' - worldPatternLore: Si desea que el escenario se complete para cualquier mundo que coincida con un patrón específico, ingrese aquí una expresión regular. - stageCreate: '§aCrear nuevo paso' - stageDown: Mover abajo - stageRemove: '§cBorrar este paso' - stageStartMsg: '§eEditar mensaje inicial' - stageType: '§7Tipo de etapa: §e{stage_type}' - stageUp: Mover arriba - talkChat: Escribe en el chat - tameAnimals: '§aDomesticar animales' - toggleRegionExit: Al salir - damageCause: - name: Causa de daño - damageCausesList: - name: Lista de causas de daño - details: - actions: '{amount} acción(es)' - auto: Iniciar automáticamente en el primer ingreso - autoLore: Si está activado, la misión se iniciará automáticamente cuando el jugador se una al servidor por primera vez. - bypassLimit: No cuente el límite de misiones - bypassLimitLore: Si está activado, la misión será iniciada incluso si el jugador ha alcanzado la cantidad máxima de misiones iniciadas. - cancelRewards: '§cCancelar acciones' - cancelRewardsLore: Acciones realizadas cuando los jugadores cancelan esta misión. - cancellable: Cancelar por jugador - cancellableLore: Permite al jugador cancelar la misión a través de su Menú de misiones. - createQuestLore: Debes definir un nombre de misión. - createQuestName: '§lCrear misión' - customConfirmMessage: '§eEditar mensaje de confirmación de búsqueda' - customConfirmMessageLore: Mensaje mostrado en la interfaz de usuario de confirmación cuando un jugador está a punto de comenzar la misión. - customDescription: '§eEditar descripción de la misión' - customDescriptionLore: Descripción mostrada a continuación el nombre de la misión en GUIs. - customMaterial: '§eEditar material del objeto de la misión' - customMaterialLore: Artículo representativo de esta misión en el Menú de Misiones. - defaultValue: '§8(valor predeterminado)' - editQuestName: '§lEditar misión' - editRequirements: '§eEditar requisitos' - editRequirementsLore: Todos los requisitos deben aplicarse al jugador antes de que pueda comenzar la misión. - endMessage: '§eEditar mensaje final' - endMessageLore: Mensaje que se enviará al jugador al final de la misión. - endSound: '§eEditar sonido final' - endSoundLore: Sonido que se reproducirá al final de la misión. - failOnDeath: Fracaso al morir - failOnDeathLore: '¿Se cancelará la misión cuando el jugador muera?' - firework: '§dFuego artificial de finalización' - fireworkLore: Fuegos artificiales lanzados cuando el jugador termine la misión - fireworkLoreDrop: Arrastra aquí tu fuego artificial personalizado - hideNoRequirementsItem: Ocultar cuando no se cumplan los requisitos - hideNoRequirementsItemLore: Si está activado, la misión no se mostrará en el menú de misiones cuando no se cumplan los requisitos. - hologramLaunch: '§eEditar "launch" item del holograma' - hologramLaunchLore: El Holograma se muestra sobre la cabeza de Starter NPC cuando el jugador puede comenzar la misión. - hologramLaunchNo: '§eEditar "launch unavailable" holograma no disponible"' - hologramLaunchNoLore: El Holograma se muestra sobre la cabeza de Starter NPC cuando el jugador NO puede iniciar la misión. - hologramText: '§eTexto del holograma' - hologramTextLore: Texto mostrado en el holograma sobre la cabeza del NPC de inicio. - keepDatas: Conservar datos de los jugadores - keepDatasLore: 'Forzar el plugin para preservar los datos de los jugadores, aunque las etapas han sido editadas. §c§lADVERTENCIA §c- habilitar esta opción puede dañar los datos de tus jugadores.' - loreReset: '§e§lTodos los avances de los jugadores serán reiniciados' - multipleTime: - itemLore: '¿Puede hacerse la misión varias veces?' - itemName: Alternar repetible - name: Últimos detalles de la misión - optionValue: '§8Valor: §7{value}' - questName: '§a§lEditar nombre de misión' - questNameLore: Debe establecer un nombre para completar la creación de misión. - questPool: '§eHerramienta de Misión' - questPoolLore: Adjuntar esta misión a un grupo de misiones - removeItemsReward: '§eEliminar items del inventario' - requiredParameter: '§7Parámetro requerido' - requirements: '{amount} requisito(s)' - rewards: '{amount} recompensa(s)' - rewardsLore: Acciones realizadas cuando termina la misión. - scoreboardItem: Habilitar el scoreboard - scoreboardItemLore: Si está desactivado, la misión no será rastreada a través del marcador. - selectStarterNPC: '§e§lSelecciona el NPC iniciador' - selectStarterNPCLore: Al hacer clic en el PNJ seleccionado comenzará la misión. - selectStarterNPCPool: '§c⚠ Un grupo de misiones está seleccionado' - setCheckpointReward: '§eEditar recompensas de puntos de control' - setItemsRewards: '§eEditar objetos de recompensa' - setMoneyReward: '§eEditar recompensa de dinero' - setPermReward: '§eEditar permisos' - setRewardStopQuest: '§cDetener la misión' - setRewardsRandom: '§dRecompensas aleatorias' - setRewardsWithRequirements: '§eRecompensas con requerimientos' - setTitleReward: '§eEditar recompensa del título' - setWaitReward: '§eEditar recompensa "esperar"' - setXPRewards: '§eEditar experiencia de recompensa' - startDialog: '§eEditar diálogo de inicio' - startDialogLore: Diálogo que se reproducira antes de que las misiones comiencen cuando los jugadores hagan clic en el Inicio NPC. - startMessage: '§eEditar mensaje de inicio' - startMessageLore: Mensaje que se enviará al jugador al comienzo de la misión. - startRewards: '§6Recompensas de inicio' - startRewardsLore: Acciones realizadas cuando comienza la misión. - startableFromGUI: Empezable desde GUI - startableFromGUILore: Permite al jugador comenzar la misión desde el Menú de Misiones. - timer: '§bReiniciar temporizador' - timerLore: Tiempo antes de que el jugador pueda volver a empezar la misión. - visibility: Visibilidad de la misión - visibilityLore: Elige en qué pestañas del menú se mostrará la misión, y si la misión es visible en los mapas dinámicos. - editTitle: - fadeIn: '§aDuración del Fade-in' - fadeOut: '§aDuración del Fade-out' - name: Editar título - stay: '§bDuración' - subtitle: '§eSubtítulo' - title: '§6Título' - entityType: - name: Elija el tipo de entidad - equipmentSlots: - name: Ranuras de equipamiento - factionsList.name: Lista de facciones - factionsRequired.name: Facciones requeridas - itemComparisons: - bukkit: Comparación nativa de Bukkit - bukkitLore: Utiliza el sistema predeterminado de comparación de artículos de Bukkit. Compara material, durabilidad, etiquetas... - customBukkit: Comparación nativa de bukkit - NO NBT - customBukkitLore: Utiliza el sistema de comparación de artículos por defecto de Bukkit, pero elimina las etiquetas NBT. Compara material, durabilidad... - enchants: Encantamientos de los articulos - enchantsLore: Comparar los encantamientos de los articulos - itemLore: Descripcion del objeto - itemLoreLore: Comparar descripcion de los artículos - itemName: Nombre del artículo - itemNameLore: Comparar nombres de artículos - material: Material del artículo - materialLore: Compara el material del objeto (i.e. piedra, espada de hierro...) - name: Comparaciones de artículos - repairCost: Coste de reparación - repairCostLore: Compara el coste de reparación de armaduras y espadas - itemCreator: - isQuestItem: '§bObjeto de misión:' - itemFlags: Alternar variables de elementos - itemLore: '§bDescripcion del objeto' - itemName: '§bNombre del objeto' - itemType: '§bTipo de artículo' - name: Creador de objetos - itemSelect: - name: Elegir elemento - itemsSelect: - name: Editar elementos - none: '§aMueve un elemento aquí o haz click para abrir el editor de objetos.' - listAllQuests: - name: Misiones - listBook: - noQuests: No se han creado misiones previamente. - questMultiple: Varias veces - questName: Nombre - questRewards: Recompensas - questStages: Etapas - questStarter: Interruptor - requirements: Requisitos - listPlayerQuests: - name: 'Misiones de {player_name}' - listQuests: - canRedo: '§3§oPuedes reiniciar esta misión!' - finished: Misiones finalizadas - inProgress: Misiones en progreso - loreCancelClick: '§cCancela la misión' - loreDialogsHistoryClick: '§7Ver los diálogos' - loreStart: '§a§oClic para comenzar la misión.' - loreStartUnavailable: '§c§oNo cumples los requisitos para empezar la misión.' - notStarted: Misiones no comenzadas - timeToWaitRedo: '§3§oPuedes reiniciar esta misión en {time_left}.' - timesFinished: '§3Mision Finalizada {times_finished} veces.' - mobSelect: - boss: '§6Selecciona un Boss' - bukkitEntityType: '§eSeleccionar tipo de entidad' - epicBoss: '§6Selecciona un Epic Boss' - mythicMob: '§6Selecciona un mob mítico' - name: Seleccionar tipo de mob - mobs: - name: Seleccionar mobs - none: '§aClic para añadir un Mob.' - setLevel: Nivel mínimo - npcCreate: - move: - itemLore: '§aCambiar la ubicación del NPC.' - itemName: '§eMover' - moveItem: '§a§lValidar lugar' - name: Crear NPC - setName: '§eEditar nombre NPC' - setSkin: '§eEdit NPC skin' - setType: '§eEditar tipo NPC' - npcSelect: - createStageNPC: '&eCrea un NPC' - name: '¿Seleccionar o crear?' - selectStageNPC: '§eSeleccionar NPC existente' - particleEffect: - color: '§bColor de partícula' - name: Crear efecto de partículas - shape: '§dForma de partícula' - type: '§eTipo de partícula' - particleList: - colored: Partícula de color - name: Lista de partículas - permission: - name: Elegir permiso - perm: '§aPermiso' - remove: Quitar permiso - removeLore: '§7El permiso será retirado de\n§7en lugar de dado.' - world: '§aMundo' - worldGlobal: '§b§lGlobal' - permissionList: - name: Lista de permisos - removed: '§eDesactivado: §6{permission_removed}' - world: '§eMundo: §6{permission_world}' - poolCreation: - avoidDuplicates: Evitar duplicados - avoidDuplicatesLore: '§8> §7Intenta evitar hacer\n la misma misión una y otra vez.' - hologramText: '§eHolograma personalizado grupal' - maxQuests: '§aMximas misiones' - name: Creación del conjunto de misiones - questsPerLaunch: '§aMisiones iniciadas por lanzamiento' - redoAllowed: Está permitido rehacer - requirements: '§bRequerimientos para iniciar una misión' - time: '§bEstablecer tiempo entre misiones' - poolsList.name: Grupos de misiones - poolsManage: - choose: '§e> §6§oElige este grupo §e<' - create: '§aCrear conjunto de misiones' - edit: '§e> §6§oEditar el conjunto... §e<' - itemName: '§aGrupo #{pool}' - name: Grupos de Misiones - poolAvoidDuplicates: '§8Evitar duplicados: §7{pool_duplicates}' - poolHologram: '§8Texto del Holograma: §7{pool_hologram}' - poolMaxQuests: '§8Misiones máximas: §7{pool_max_quests}' - poolQuestsList: '§7{pool_quests_amount} §8Misión(s): §7{pool_quests}' - poolQuestsPerLaunch: '§8Misiones dadas por lanzamiento: §7{pool_quests_per_launch}' - poolRedo: '§8Puede rehacer misiones completadas: §7{pool_redo}' - poolTime: '§8Tiempo entre misiones: §7{pool_time}' - requirements: - name: Requerimientos - rewards: - commands: 'Comandos: {amount}' - name: Recompensas - random: - minMax: Editar mínimo y máximo - rewards: Editar recompensas - rewardsWithRequirements: - name: Recompensas con requisitos - search: '§e§lBuscar' - stageEnding: - command: '§eEditar comando ejecutado' - locationTeleport: '§eEditar lugar de teletransportación' - stages: - branchesPage: '§dRamas de las etapas' - descriptionTextItem: '§eEditar descripción' - endingItem: '§eEditar recompensas finales' - laterPage: '§ePágina anterior' - name: Crear etapas - newBranch: '§eIr a una nueva rama' - nextPage: '§eSiguiente página' - previousBranch: '§eRegresa a la rama anterior' - regularPage: '§aEtapas regulares' - validationRequirements: '§eRequisitos de validación' - validationRequirementsLore: Todos los requisitos deben coincidir con el jugador que intenta completar la etapa. Si no, la etapa no se puede completar. - validate: '§b§lValidar' - visibility: - finished: 'Pestaña de menú: "Finalizado"' - inProgress: 'Pestaña de menú: "En progreso"' - maps: Mapas (como dynmap o BlueMap) - name: Visibilidad de la misión - notStarted: 'Pestaña de menú: "No iniciado"' -misc: - amount: '§eCantidad: {amount}' - amounts: - comparisons: '{comparisons_amount} comparación(es)' - dialogLines: '{lines_amount} línea(s)' - items: '{items_amount} objeto(s)' - permissions: '{permissions_amount} permiso(s)' - and: "y" - bucket: - lava: Balde de lava - milk: Balde de leche - snow: Cubo de nieve - water: Balde de agua - click: - left: Clic izquierdo - middle: Clic central - right: Click derecho - shift-left: Mayús-Clic izquierdo - shift-right: Mayús-Clic derecho - comparison: - different: diferente a {number} - equals: igual a {number} - greater: estrictamente mayor que {number} - greaterOrEquals: mayor que {number} - less: estrictamente menos de {number} - lessOrEquals: menos de {number} - disabled: Desactivado - enabled: Activado - entityType: '§eTipo de entidad: {entity_type}' - entityTypeAny: '§eCualquier entidad' - format: - prefix: '§6<§e§lMisiones§r§6> §r' - hologramText: '§8§lNPC de la misión' - 'no': 'No' - notSet: '§cno colocado' - or: o - poolHologramText: '§e¡Nueva misión disponible!' - questItemLore: '§e§oObjeto de la misión' - removeRaw: Eliminar - requirement: - class: '§bClase(s) requerida' - combatLevel: '§bNivel de combate requerido' - equipment: '§eEquipamiento requerido' - experienceLevel: '§bNivel de experiencia requerida' - faction: '§bFacción(es) requerida(s)' - jobLevel: '§bNivel de trabajo requerido' - logicalOr: '§dLógica O (requerimientos)' - mcMMOSkillLevel: '§dNivel de habilidad requerida' - money: '§dDinero requerido' - permissions: '§3Permiso(s) requeridos' - placeholder: '§bValor de placeholder requerido' - quest: '§aMisión requerida' - region: '§dRequiere una Region' - scoreboard: '§dPuntuación requerida' - skillAPILevel: '§bSkillAPI nivel requerido' - reset: Reiniciar - stageType: - Bucket: Rellenar cubo - Craft: Fabrica objetos - Enchant: Encantar objetos - Fish: Captura de peces - Melt: Cocinar objetos - breedAnimals: Reproducir Animales - chat: Escribir en el chat - dealDamage: Inflige daño. - die: Morir - eatDrink: Comer o beber - interact: Interactuar con el bloque - items: Traer elementos - location: Buscar ubicación - mine: Romper bloques - mobs: Mata mobs - npc: Buscar NPC - placeBlocks: Colocar bloques - playTime: Tiempo de juego - region: Buscar región - tameAnimals: Domar animales - time: - days: '{days_amount} días' - hours: '{hours_amount} horas' - lessThanAMinute: menos de un minuto - minutes: '{minutes_amount} minutos' - weeks: '{weeks_amount} semanas' - unknown: desconocido - 'yes': 'Si' msg: + quest: + finished: + base: '§a¡Felicitaciones! ¡Has finalizado la misión §e{quest_name}§a!' + obtain: '§a¡Obtuviste {rewards}!' + started: '§a¡Has comenzado la misión §r§e{quest_name}§o§6!' + created: '§a¡Felicitaciones! ¡Has creado la misión §e{quest}§a el cual incluye {quest_branches} rama(s)!' + edited: '§a¡Felicitaciones! ¡Has editado la misión §e{quest}§a el cual incluye ahora {quest_branches} rama(s)!' + createCancelled: '§c¡La creación o edición a sido cancelada por otro plugin!' + cancelling: '§cProceso de creación de la misión cancelada.' + editCancelling: '§cProceso de edición de misión cancelada.' + invalidID: '§cLa misión con la id {quest_id} no existe.' + invalidPoolID: '§cEl grupo {pool_id} no existe.' + alreadyStarted: '§cYa has comenzado la misión!' + notStarted: '§cActualmente no estás haciendo esta misión.' + quests: + maxLaunched: '§cNo puedes tener mas de {quests_max_amount} Misiones al mismo tiempo...' + updated: '§7Misión §e{quest_name}§7 actualizada.' + checkpoint: El punto de control de tarea ha sido alcanzado + failed: Has fallado en la búsquedast {quest_name} + pools: + noTime: '§cDebes esperar {time_left} antes de hacer otra misión.' + allCompleted: '§7¡Has completado todas las misiones!' + noAvailable: '§7No hay más misiones disponibles...' + maxQuests: '§cNo puedes tener más de {pool_max_quests} mision(es) al mismo tiempo...' + questItem: + drop: '§c¡No puedes soltar un objeto de misión!' + craft: '§c¡No puedes usar un objeto de misión para fabricar!' + eat: '§c¡No puedes comer un objeto de misión!' + stageMobs: + listMobs: '§aDebes matar {mobs}.' + writeNPCText: '§aEscribe el dialogo que se le dirá al jugador por el NPC: (Escribe "help" para recibir ayuda.)' + writeRegionName: '§aEscribe el nombre de la región requerida para este paso:' + writeXPGain: '§aEscribe la cantidad de puntos de experiencia que el jugador obtendrá: (Último valor: {xp_amount})' + writeMobAmount: '§aEscribe la cantidad de mobs a matar:' + writeMobName: '§aEscribe el nombre personalizado del mob para matar:' + writeChatMessage: '§aEscribe el mensaje requerido: (Añade "\{DIAGONAL}al principio si quieres utilizar un comando.)' + writeMessage: '§aEscribe el mensaje que se enviará al jugador' + writeStartMessage: '§aEscribe el mensaje que será enviado al iniciar la misión, "null" si quieres el predeterminado o "none" si no quieres ninguno' + writeEndSound: '§aEscribe el nombre del sonido que se reproducirá al jugador al final de la misión, "null" si quieres el predeterminado o "none" si no quieres ninguno:' + writeDescriptionText: '§aEscribe el texto que describe el objetivo de la etapa:' + writeStageText: '§aEscribe el texto que será enviado al jugador al comienzo del paso:' + moveToTeleportPoint: '§aIr a la ubicación de teletransporte deseada.' + writeNpcName: '§aEscribe el nombre del NPC:' + writeNpcSkinName: '§aEscribe el nombre de la skin del NPC:' + writeQuestName: '§aEscribe el nombre de tu misión:' + writeHologramText: '§aEscribe el texto del holograma: (Escribe "none" si no quieres un holograma y "null" si quieres el texto por defecto.)' + writeQuestTimer: '§aEscriba el tiempo requerido (en minutos) antes de reiniciar la misión: (Escriba "null" si desea el temporizador predeterminado.)' + writeConfirmMessage: '§aEscribe el mensaje de confirmación que se muestra cuando un jugador está a punto de iniciar la misión: (Escribe "null" si quieres el mensaje por defecto.)' + writeQuestDescription: '§aEscribe la descripción de la misión, mostrado en la GUI de misiones del jugador.' + writeQuestMaterial: '§aEscribe el material del item de la misión.' + requirements: + quest: '§cDebes haber terminado la misión §e{quest_name}§c!' + level: '§c¡Tu nivel debe ser {long_level}!' + job: '§c¡Tu nivel para el trabajo §e{job_name}§c debe ser {long_level}!' + skill: '§cTu nivel para la habilidad §e{skill_name}§c debe ser {long_level}!' + combatLevel: '§cTu nivel de combate debe ser {long_level}!' + money: '§cDebes tener {money}!' + waitTime: '§cDebes esperar {time_left} para poder reiniciar esta misión!' + experience: + edited: '§aHas cambiado la ganancia de la experiencia de {old_xp_amount} a {xp_amount} puntos.' + selectNPCToKill: '§aSelecciona el NPC para matar.' + regionDoesntExists: '§cEsta región no existe. (Tienes que estar en el mismo mundo.)' + npcDoesntExist: '§cEl NPC con la id {npc_id} no existe.' + number: + negative: '§cDebes introducir un número positivo!' + zero: '§cDebes introducir un número distinto de 0!' + invalid: '§c{input} no es un número válido.' + notInBounds: '§cTu número debe estar entre {min} y {max}.' + errorOccurred: '§cHa ocurrido un error, ¡contacta con un administrador! §4§lError: {error}' + indexOutOfBounds: '§cEl número {index} está fuera de límites! Debe estar entre {min} y {max}.' + invalidBlockData: '§cLos datos del bloque {block_data} no son válidos o son incompatibles con el bloque {block_material}.' + invalidBlockTag: '§cEtiqueta de bloque {block_tag} no disponible.' bringBackObjects: Tráeme de nuevo {items}. + inventoryFull: '§cTu inventario está lleno, el objeto ha sido abandonado en el suelo.' + versionRequired: 'Versión requerida: §l{version}' + restartServer: '§7Reinicia tu servidor para ver las modificaciones.' + dialogs: + skipped: '§8§o Diálogo omitido.' + tooFar: '§7§oEstás demasiado lejos de {npc_name}...' command: - adminModeEntered: '&aEntraste en el modo Admin.' - adminModeLeft: '&aSaliste del modo Admin.' - backupCreated: '&6Creaste correctamente copias de seguridad de misiones e información.' - backupPlayersFailed: '§cLa creación de la copia de seguridad para toda la información de los jugadores ha fallado.' - backupQuestsFailed: '§cLa creación de la copia de seguridad para todas las misiones ha fallado.' - cancelQuest: '§6Cancelaste la misión {quest}.' - cancelQuestUnavailable: '&cLa misión {quest} no puede ser cancelada.' + downloadTranslations: + syntax: '§cDebes especificar un idioma para descargar. Ejemplo: "/quests downloadTranslations en_US".' + notFound: '§cIdioma {lang} no encontrado para la versión {version}.' + exists: '§cEl archivo {file_name} ya existe. Añade "-overwrite" a tu comando para sobrescribirlo. (/quests downloadTranslations -overwrite)' + downloaded: '§a¡El idioma {lang} ha sido descargado! §7Ahora debes editar el archivo "/plugins/BeautyQuests/config.yml" para cambiar el valor de §ominecraftTranslationsFile§7 con {lang}, y luego reiniciar el servidor.' checkpoint: noCheckpoint: '§cNo se ha encontrado ningún punto de control para la misión {quest}.' questNotStarted: '§cNo estás haciendo esta misión.' - downloadTranslations: - downloaded: '§a¡El idioma {lang} ha sido descargado! §7Ahora debes editar el archivo "/plugins/BeautyQuests/config.yml" para cambiar el valor de §ominecraftTranslationsFile§7 con {lang}, y luego reiniciar el servidor.' - exists: '§cEl archivo {file_name} ya existe. Añade "-overwrite" a tu comando para sobrescribirlo. (/quests downloadTranslations -overwrite)' - notFound: '§cIdioma {lang} no encontrado para la versión {version}.' - syntax: '§cDebes especificar un idioma para descargar. Ejemplo: "/quests downloadTranslations en_US".' - help: - adminMode: '§6/{label} adminMode: §eActiva el Modo de administración. (Útil para mostrar mensajes de poco registro.)' - create: '§6/{label} create: §eCrea una misión.' - downloadTranslations: '§6/{label} descargaTraducciones : §eDescargas un archivo de traducción de vaina' - edit: '§6/{label} edit: §eEditar una misión.' - header: '§6§lBeautyQuests — Ayuda' - list: '§6/{label} list: §eVer la lista de misiones. (Sólo para versiones soportadas.)' - reload: '§6/{label} reload: §eGuarda y recarga todas las configuraciones y archivos. (§cdeprecado§e)' - remove: '§6/{label} remove : §eElimina una misión con un id especificado o haz clic en el NPC cuando no se haya definido.' - resetPlayer: '§6/{label} restablecido jugador : §eElimina toda la información sobre un jugador.' - resetPlayerQuest: '§6/{label} restablecida la Misión de Jugador [id]: §eElimina información de una misión para un jugador.' - save: '§6/{label} save: §eHacer un guardado manual.' - seePlayer: '§6/{label} seePlayer : §eVer la informacion sobre un jugador' - setFirework: '§6/{label} setFirework: §eEdita el fuego artificial por defecto al finalizar.' - setItem: '§6/{label} setItem : §eGuarda el elemento del holograma.' - start: '§6/{label} start [id]: §eForzar el inicio de una mision' - startDialog: '§6/{label} startDialog : §eComienza el diálogo pendiente para una etapa del NPC o el diálogo de inicio para una misión.' - version: '§6/{label} version: §eVer la versión actual del plugin.' + setStage: + branchDoesntExist: '§cLa rama con el id {branch_id} no existe.' + doesntExist: '§cLa etapa con el id {stage_id} no existe.' + next: '§aLa etapa ha sido omitida.' + nextUnavailable: '§cLa opción "skip" no está disponible cuando el jugador está al final de una rama.' + set: '§aFase {stage_id} lanzada.' + startDialog: + impossible: '§cNo es posible iniciar el diálogo ahora.' + noDialog: '§cEl jugador no tiene un diálogo pendiente.' + alreadyIn: '§cEl jugador ya está reproduciendo un diálogo.' + success: '§aEmpezó el diálogo para el jugador {player} en la misión {quest}!' invalidCommand: simple: '§cEste comando no existe, escribe §ehelp§c.' itemChanged: '§aEl elemento ha sido editado. Los cambios afectarán después de un reinicio.' itemRemoved: '§aEl elemento holograma ha sido eliminado.' - leaveAll: '§aHas forzado el final de {success} misión(s). Errores: {errors}' removed: '§aLa misión {quest_name} se ha eliminado correctamente.' + leaveAll: '§aHas forzado el final de {success} misión(s). Errores: {errors}' resetPlayer: player: '§6Todas las informaciones de tu misión(s) {quest_amount} han sido eliminadas por {deleter_name}.' remover: '§6{quest_amount} información(es) de misiones (y {quest_pool} pool) de {player} ha sido eliminada.' - resetPlayerPool: - full: '§aHas reiniciado la {pool} información del grupo en {player}.' - timer: '§aHas reiniciado el {pool} contador del grupo en {player}.' resetPlayerQuest: player: '§6Toda la información sobre la misión {quest} fue borrada por {deleter_name}.' remover: '§6{player} información de {quest} ha sido eliminado.' resetQuest: '§6Removida información de misiones de {player_amount} jugadores.' - scoreboard: - hidden: '§6El marcador del jugador {player_name} ha sido ocultado.' - lineInexistant: '§cLa línea {line_id} no existe.' - lineRemoved: '§6Has eliminado con éxito la línea {line_id}.' - lineReset: '§6Has restablecido con éxito la línea {line_id}.' - lineSet: '§6Has editado con éxito la línea {line_id}.' - own: - hidden: Su marcador ahora está oculto. - shown: Su marcador se muestra de nuevo - resetAll: '§6Has restablecido el marcador del jugador {player_name} con éxito.' - shown: '§6El marcador del jugador {player_name} ha sido mostrado.' - setStage: - branchDoesntExist: '§cLa rama con el id {branch_id} no existe.' - doesntExist: '§cLa etapa con el id {stage_id} no existe.' - next: '§aLa etapa ha sido omitida.' - nextUnavailable: '§cLa opción "skip" no está disponible cuando el jugador está al final de una rama.' - set: '§aFase {stage_id} lanzada.' - startDialog: - alreadyIn: '§cEl jugador ya está reproduciendo un diálogo.' - impossible: '§cNo es posible iniciar el diálogo ahora.' - noDialog: '§cEl jugador no tiene un diálogo pendiente.' - success: '§aEmpezó el diálogo para el jugador {player} en la misión {quest}!' - startQuest: '§6Obligaste a empezar la misión {quest} (UUID de Jugador: {player}).' startQuestNoRequirements: '§cEl jugador no cumple con los requisitos para la misión {quest}... Añade "-overrideRequirements" al final de tu comando para evitar la comprobación de requisitos.' - dialogs: - skipped: '§8§o Diálogo omitido.' - tooFar: '§7§oEstás demasiado lejos de {npc_name}...' + cancelQuest: '§6Cancelaste la misión {quest}.' + cancelQuestUnavailable: '&cLa misión {quest} no puede ser cancelada.' + backupCreated: '&6Creaste correctamente copias de seguridad de misiones e información.' + backupPlayersFailed: '§cLa creación de la copia de seguridad para toda la información de los jugadores ha fallado.' + backupQuestsFailed: '§cLa creación de la copia de seguridad para todas las misiones ha fallado.' + adminModeEntered: '&aEntraste en el modo Admin.' + adminModeLeft: '&aSaliste del modo Admin.' + resetPlayerPool: + timer: '§aHas reiniciado el {pool} contador del grupo en {player}.' + full: '§aHas reiniciado la {pool} información del grupo en {player}.' + scoreboard: + lineSet: '§6Has editado con éxito la línea {line_id}.' + lineReset: '§6Has restablecido con éxito la línea {line_id}.' + lineRemoved: '§6Has eliminado con éxito la línea {line_id}.' + lineInexistant: '§cLa línea {line_id} no existe.' + resetAll: '§6Has restablecido el marcador del jugador {player_name} con éxito.' + hidden: '§6El marcador del jugador {player_name} ha sido ocultado.' + shown: '§6El marcador del jugador {player_name} ha sido mostrado.' + own: + hidden: Su marcador ahora está oculto. + shown: Su marcador se muestra de nuevo + help: + header: '§6§lBeautyQuests — Ayuda' + create: '§6/{label} create: §eCrea una misión.' + edit: '§6/{label} edit: §eEditar una misión.' + remove: '§6/{label} remove : §eElimina una misión con un id especificado o haz clic en el NPC cuando no se haya definido.' + startDialog: '§6/{label} startDialog : §eComienza el diálogo pendiente para una etapa del NPC o el diálogo de inicio para una misión.' + resetPlayer: '§6/{label} restablecido jugador : §eElimina toda la información sobre un jugador.' + resetPlayerQuest: '§6/{label} restablecida la Misión de Jugador [id]: §eElimina información de una misión para un jugador.' + seePlayer: '§6/{label} seePlayer : §eVer la informacion sobre un jugador' + reload: '§6/{label} reload: §eGuarda y recarga todas las configuraciones y archivos. (§cdeprecado§e)' + start: '§6/{label} start [id]: §eForzar el inicio de una mision' + setItem: '§6/{label} setItem : §eGuarda el elemento del holograma.' + setFirework: '§6/{label} setFirework: §eEdita el fuego artificial por defecto al finalizar.' + adminMode: '§6/{label} adminMode: §eActiva el Modo de administración. (Útil para mostrar mensajes de poco registro.)' + version: '§6/{label} version: §eVer la versión actual del plugin.' + downloadTranslations: '§6/{label} descargaTraducciones : §eDescargas un archivo de traducción de vaina' + save: '§6/{label} save: §eHacer un guardado manual.' + list: '§6/{label} list: §eVer la lista de misiones. (Sólo para versiones soportadas.)' + typeCancel: '§aEscribe "cancel" para volver al último texto.' editor: - advancedSpawnersMob: 'Escribe el nombre del spawner personalizado para matar:' - already: '§cYa estás en el editor.' - availableElements: 'Elementos disponibles: §e{available_elements}' blockAmount: '§aEscribe la cantidad de bloques:' - blockData: '§aEscribe los datos de bloque (datos de bloques disponibles: {available_datas}):' blockName: '§aEscribe el nombre del bloque:' + blockData: '§aEscribe los datos de bloque (datos de bloques disponibles: {available_datas}):' blockTag: '§aEscribe la etiqueta de bloque (etiquetas disponibles: §7{available_tags}§a):' - chat: '§2♣§d§kii§a§lSkyblock§d§kii§2♣ §2Estás actualmente en modo editor. Escribe "/quests exitEditor" para forzar la salida del editor. (No se recomienda, considere usar comandos como "close" o "cancelar" para volver al inventario anterior.)' - color: 'Introduzca un color en formato hexadecimal (#XXXXX) o formato RGB (RED GRE BLU).' - colorNamed: Introduzca el nombre de un color. - comparisonTypeDefault: '§aElige el tipo de comparación que quieres entre {available}. La comparación predeterminada es: §e§l{default}§r§a. Escribe §onull§r§a para usarlo.' - dialog: - cleared: '§a{amount} mensaje(s) removido.' - edited: '§aMensaje "§7{msg}§a" editado.' - help: - addSound: '§6addSound : §eAñade un sonido a un mensaje' - clear: '§6clear: §eBorra todos los mensajes.' - close: '&6close: &eGuardas y validas los mensajes.' - edit: '§6edit : §eEditar un mensaje.' - header: '§6§lBeautyQuests — Ayuda del editor de diálogo' - list: '§6list: §eVer todos los mensajes.' - nothing: '§6noSender : §eAgrega un mensaje sin remitente.' - nothingInsert: '§6nothingInsert : §eInserta un mensaje sin ningún prefijo.' - npc: '§6npc : §eAgrega un mensaje dicho por el NPC.' - npcInsert: '§6npcInsert : §eInsertar un mensaje dicho por el NPC.' - npcName: '§6Nombre del npc [custom NPC name]: §eEstablecido (o restablecido a default) nombre personalizado del NPC en el diálogo' - player: '§6player : §eAgrega un mensaje dicho por el jugador.' - playerInsert: '§6playerInsert : §eInsertar un mensaje dicho por el jugador' - remove: '§6remove : §eRemover un mensaje.' - setTime: '§6setTime