├── _config.yml ├── core ├── .gitignore └── src │ └── main │ ├── java │ └── fr │ │ └── skytasul │ │ └── quests │ │ ├── utils │ │ ├── ThrowingConsumer.java │ │ ├── compatibility │ │ │ ├── Paper.java │ │ │ ├── InternalIntegrations.java │ │ │ └── BQBackwardCompat.java │ │ ├── DebugUtils.java │ │ └── nms │ │ │ └── NullNMS.java │ │ ├── options │ │ ├── OptionAutoQuest.java │ │ ├── OptionBypassLimit.java │ │ ├── OptionHideNoRequirements.java │ │ ├── OptionScoreboardEnabled.java │ │ ├── OptionStartRewards.java │ │ ├── OptionEndSound.java │ │ ├── OptionCancellable.java │ │ ├── OptionStartMessage.java │ │ ├── OptionName.java │ │ ├── OptionEndMessage.java │ │ ├── OptionHologramLaunch.java │ │ ├── OptionHologramLaunchNo.java │ │ ├── OptionConfirmMessage.java │ │ ├── OptionFailOnDeath.java │ │ ├── OptionHologramText.java │ │ ├── OptionCancelRewards.java │ │ ├── OptionStartable.java │ │ └── OptionRepeatable.java │ │ ├── players │ │ └── AbstractPlayerQuesterImplementation.java │ │ ├── blocks │ │ ├── BQBlockMaterial.java │ │ ├── BQBlockData.java │ │ └── BQBlockTag.java │ │ ├── structure │ │ └── EndingStageImplementation.java │ │ ├── rewards │ │ ├── QuestStopReward.java │ │ └── TitleReward.java │ │ ├── scoreboards │ │ └── ScoreboardLine.java │ │ ├── commands │ │ └── parameters │ │ │ ├── BqNpcParameter.java │ │ │ ├── QuestParameter.java │ │ │ └── QuestPoolParameter.java │ │ ├── npcs │ │ ├── dialogs │ │ │ └── ChatMessageSender.java │ │ └── BQNPCClickEvent.java │ │ ├── editor │ │ ├── parsers │ │ │ └── MaterialParser.java │ │ ├── DefaultEditorFactory.java │ │ └── SelectNPC.java │ │ ├── gui │ │ ├── mobs │ │ │ └── MobSelectionGUI.java │ │ ├── items │ │ │ └── ItemComparisonGUI.java │ │ ├── particles │ │ │ └── ParticleListGUI.java │ │ ├── misc │ │ │ └── BucketTypeGUI.java │ │ └── DefaultItemFactory.java │ │ ├── questers │ │ └── AbstractQuesterPoolDataImplementation.java │ │ └── requirements │ │ └── LevelRequirement.java │ └── resources │ ├── hikari.properties │ └── scoreboard.yml ├── .gitignore ├── api └── src │ ├── main │ └── java │ │ └── fr │ │ └── skytasul │ │ └── quests │ │ ├── api │ │ ├── gui │ │ │ ├── close │ │ │ │ ├── StandardCloseBehavior.java │ │ │ │ ├── CloseBehavior.java │ │ │ │ ├── OpenCloseBehavior.java │ │ │ │ └── DelayCloseBehavior.java │ │ │ ├── layout │ │ │ │ ├── LayoutedClickHandler.java │ │ │ │ └── LayoutedClickEvent.java │ │ │ ├── ItemFactory.java │ │ │ ├── GuiManager.java │ │ │ ├── templates │ │ │ │ ├── StaticPagedGUI.java │ │ │ │ ├── ConfirmGUI.java │ │ │ │ └── ChooseGUI.java │ │ │ ├── AbstractGui.java │ │ │ ├── GuiClickEvent.java │ │ │ └── Gui.java │ │ ├── objects │ │ │ └── QuestObjectLocation.java │ │ ├── commands │ │ │ ├── QuesterSelector.java │ │ │ ├── OutsideEditor.java │ │ │ └── CommandsManager.java │ │ ├── mobs │ │ │ ├── MobStacker.java │ │ │ └── LeveledMobFactory.java │ │ ├── utils │ │ │ ├── progress │ │ │ │ ├── ProgressBarConfig.java │ │ │ │ ├── HasProgress.java │ │ │ │ └── itemdescription │ │ │ │ │ └── ItemsDescriptionConfiguration.java │ │ │ ├── messaging │ │ │ │ ├── HasPlaceholders.java │ │ │ │ ├── MessageType.java │ │ │ │ ├── MessageProcessor.java │ │ │ │ └── DefaultErrors.java │ │ │ ├── MissingDependencyException.java │ │ │ ├── AutoRegistered.java │ │ │ ├── QuestVisibilityLocation.java │ │ │ ├── MinecraftVersion.java │ │ │ └── PlayerListCategory.java │ │ ├── options │ │ │ ├── description │ │ │ │ ├── DescriptionSource.java │ │ │ │ ├── QuestDescription.java │ │ │ │ └── QuestDescriptionProvider.java │ │ │ ├── OptionSet.java │ │ │ ├── QuestOptionRewards.java │ │ │ ├── QuestOptionCreator.java │ │ │ └── QuestOptionBoolean.java │ │ ├── requirements │ │ │ ├── Actionnable.java │ │ │ └── RequirementCreator.java │ │ ├── stages │ │ │ ├── creation │ │ │ │ ├── StageGuiClickHandler.java │ │ │ │ ├── StageCreationContext.java │ │ │ │ ├── StageGuiClickEvent.java │ │ │ │ └── StageGuiLine.java │ │ │ ├── options │ │ │ │ ├── StageOptionAutoRegister.java │ │ │ │ ├── StageQuesterStrategy.java │ │ │ │ └── StageOptionCreator.java │ │ │ ├── StageHandler.java │ │ │ ├── types │ │ │ │ └── Dialogable.java │ │ │ ├── StageDescriptionPlaceholdersContext.java │ │ │ └── StageIndex.java │ │ ├── blocks │ │ │ ├── BQBlockType.java │ │ │ ├── BQBlockOptions.java │ │ │ └── BQBlocksManager.java │ │ ├── editors │ │ │ ├── parsers │ │ │ │ ├── AbstractParser.java │ │ │ │ ├── WorldParser.java │ │ │ │ ├── ScoreboardObjectiveParser.java │ │ │ │ ├── PatternParser.java │ │ │ │ ├── EnumParser.java │ │ │ │ └── CollectionParser.java │ │ │ ├── EditorFactory.java │ │ │ ├── EditorManager.java │ │ │ ├── InventoryClear.java │ │ │ └── WaitBlockClick.java │ │ ├── npcs │ │ │ ├── NpcClickType.java │ │ │ ├── BqInternalNpc.java │ │ │ ├── dialogs │ │ │ │ ├── MessageSender.java │ │ │ │ └── events │ │ │ │ │ ├── DialogSendEvent.java │ │ │ │ │ └── DialogSendMessageEvent.java │ │ │ ├── BqNpc.java │ │ │ ├── BqNpcManager.java │ │ │ └── BqInternalNpcFactory.java │ │ ├── quests │ │ │ ├── branches │ │ │ │ ├── EndingStage.java │ │ │ │ └── QuestBranchesManager.java │ │ │ ├── events │ │ │ │ ├── QuestRemoveEvent.java │ │ │ │ ├── questers │ │ │ │ │ ├── AbstractQuesterQuestEvent.java │ │ │ │ │ ├── QuesterQuestFinishEvent.java │ │ │ │ │ ├── QuesterQuestLaunchEvent.java │ │ │ │ │ ├── QuesterQuestResetEvent.java │ │ │ │ │ ├── QuesterQuestPreLaunchEvent.java │ │ │ │ │ └── QuesterSetStageEvent.java │ │ │ │ ├── AbstractQuestEvent.java │ │ │ │ └── QuestCreateEvent.java │ │ │ ├── creation │ │ │ │ ├── QuestCreationGui.java │ │ │ │ └── QuestCreationGuiClickEvent.java │ │ │ ├── quester │ │ │ │ └── QuestQuesterStrategyCreator.java │ │ │ └── QuestsManager.java │ │ ├── data │ │ │ ├── DataSavingException.java │ │ │ └── DataLoadingException.java │ │ ├── players │ │ │ ├── PlayerQuester.java │ │ │ └── PlayerManager.java │ │ ├── events │ │ │ └── internal │ │ │ │ ├── BeautyQuestsLoadedEvent.java │ │ │ │ ├── BQBlockBreakEvent.java │ │ │ │ ├── BQCraftEvent.java │ │ │ │ └── BQMobDeathEvent.java │ │ ├── questers │ │ │ ├── events │ │ │ │ ├── AbstractQuesterEvent.java │ │ │ │ ├── QuesterResetEvent.java │ │ │ │ ├── QuesterLeaveEvent.java │ │ │ │ └── QuesterJoinEvent.java │ │ │ ├── data │ │ │ │ └── QuesterPoolData.java │ │ │ ├── QuesterProvider.java │ │ │ └── QuesterManager.java │ │ ├── pools │ │ │ └── QuestPoolsManager.java │ │ ├── QuestsHandler.java │ │ ├── rewards │ │ │ ├── RewardCreator.java │ │ │ ├── RewardGiveContext.java │ │ │ └── AbstractReward.java │ │ ├── serializable │ │ │ └── SerializableCreator.java │ │ ├── AbstractHolograms.java │ │ ├── QuestsPlugin.java │ │ ├── AbstractMapIntegration.java │ │ └── comparison │ │ │ └── ItemComparison.java │ │ └── QuestsAPIProvider.java │ └── test │ ├── java │ └── fr │ │ └── skytasul │ │ └── quests │ │ └── api │ │ └── utils │ │ └── ChatColorUtilsTest.java │ └── resources │ └── word_wrap.csv ├── dist └── all-jar.xml ├── integrations └── src │ └── main │ └── java │ └── fr │ └── skytasul │ └── quests │ └── integrations │ ├── mobs │ ├── BQWildStacker.java │ ├── EpicBosses.java │ └── BQStackMob.java │ ├── BQTokenEnchant.java │ ├── worldguard │ ├── WorldGuardExitEvent.java │ └── WorldGuardEntryEvent.java │ ├── BQUltimateTimber.java │ ├── placeholders │ └── PapiMessageProcessor.java │ ├── BQMMOItems.java │ ├── BQItemsAdder.java │ ├── IntegrationsConfiguration.java │ ├── fabled │ └── FabledLevelRequirement.java │ ├── vault │ └── permission │ │ ├── PermissionListGUI.java │ │ └── Permission.java │ └── mcmmo │ └── McCombatLevelRequirement.java ├── paper └── src │ ├── main │ └── java │ │ └── fr │ │ └── skytasul │ │ └── quests │ │ └── utils │ │ └── compatibility │ │ └── PaperImplementation.java │ └── test │ └── java │ └── fr │ └── skytasul │ └── quests │ └── test │ └── TestUtils.java ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── v1_18_R2 └── src │ └── main │ └── java │ └── fr │ └── skytasul │ └── quests │ └── utils │ └── nms │ └── v1_18_R2.java ├── v1_19_R1 └── src │ └── main │ └── java │ └── fr │ └── skytasul │ └── quests │ └── utils │ └── nms │ └── v1_19_R1.java ├── LICENSE.md ├── v1_17_R1 └── src │ └── main │ └── java │ └── fr │ └── skytasul │ └── quests │ └── utils │ └── nms │ └── v1_17_R1.java ├── v1_18_R1 └── src │ └── main │ └── java │ └── fr │ └── skytasul │ └── quests │ └── utils │ └── nms │ └── v1_18_R1.java ├── v1_19_R2 └── src │ └── main │ └── java │ └── fr │ └── skytasul │ └── quests │ └── utils │ └── nms │ └── v1_19_R2.java ├── v1_19_R3 └── src │ └── main │ └── java │ └── fr │ └── skytasul │ └── quests │ └── utils │ └── nms │ └── v1_19_R3.java ├── v1_20_R1 └── src │ └── main │ └── java │ └── fr │ └── skytasul │ └── quests │ └── utils │ └── nms │ └── v1_20_R1.java ├── v1_20_R2 └── src │ └── main │ └── java │ └── fr │ └── skytasul │ └── quests │ └── utils │ └── nms │ └── v1_20_R2.java └── v1_20_R3 └── src └── main └── java └── fr └── skytasul └── quests └── utils └── nms └── v1_20_R3.java /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /core/.gitignore: -------------------------------------------------------------------------------- 1 | /dependency-reduced-pom.xml 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /doc/ 3 | .classpath 4 | .project 5 | *.jardesc 6 | target/ 7 | .settings/ 8 | /integrations/jars/ 9 | .flattened-pom.xml -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/close/StandardCloseBehavior.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui.close; 2 | 3 | public enum StandardCloseBehavior implements CloseBehavior { 4 | 5 | REOPEN, CONFIRM, REMOVE, NOTHING; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/objects/QuestObjectLocation.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.objects; 2 | 3 | public enum QuestObjectLocation { 4 | 5 | QUEST, STAGE, CHECKPOINT, DIALOG, POOL, CANCELLING, OTHER; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/utils/ThrowingConsumer.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils; 2 | 3 | @FunctionalInterface 4 | public interface ThrowingConsumer { 5 | 6 | public void accept(T object) throws E; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/commands/QuesterSelector.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.commands; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import java.util.List; 5 | 6 | public interface QuesterSelector extends List { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/mobs/MobStacker.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.mobs; 2 | 3 | import org.bukkit.entity.Entity; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public interface MobStacker { 7 | 8 | int getEntityStackSize(@NotNull Entity entity); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/progress/ProgressBarConfig.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils.progress; 2 | 3 | public interface ProgressBarConfig { 4 | 5 | boolean areBossBarsEnabled(); 6 | 7 | String getBossBarFormat(); 8 | 9 | int getBossBarTimeout(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/messaging/HasPlaceholders.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils.messaging; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | public interface HasPlaceholders { 6 | 7 | @NotNull 8 | PlaceholderRegistry getPlaceholdersRegistry(); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/messaging/MessageType.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils.messaging; 2 | 3 | public interface MessageType { 4 | 5 | public enum DefaultMessageType implements MessageType { 6 | 7 | PREFIXED, UNPREFIXED, OFF; 8 | 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/options/description/DescriptionSource.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.options.description; 2 | 3 | /** 4 | * Where do the description request come from 5 | */ 6 | public enum DescriptionSource { 7 | 8 | SCOREBOARD, MENU, PLACEHOLDER, FORCESPLIT, FORCELINE; 9 | 10 | } -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/requirements/Actionnable.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.requirements; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public interface Actionnable { 7 | 8 | public void trigger(@NotNull Player p); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/creation/StageGuiClickHandler.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages.creation; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | @FunctionalInterface 6 | public interface StageGuiClickHandler { 7 | 8 | void onClick(@NotNull StageGuiClickEvent event); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/mobs/LeveledMobFactory.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.mobs; 2 | 3 | import org.bukkit.entity.Entity; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public interface LeveledMobFactory extends MobFactory { 7 | 8 | double getMobLevel(@NotNull T type, @NotNull Entity entity); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/blocks/BQBlockType.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.blocks; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | public interface BQBlockType { 6 | 7 | @NotNull 8 | BQBlock deserialize(@NotNull String string, @NotNull BQBlockOptions serializedOptions) 9 | throws IllegalArgumentException; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/layout/LayoutedClickHandler.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui.layout; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | public interface LayoutedClickHandler { 6 | 7 | public static final LayoutedClickHandler EMPTY = event -> {}; 8 | 9 | void click(@NotNull LayoutedClickEvent event); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/progress/HasProgress.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils.progress; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public interface HasProgress { 7 | 8 | long getRemainingAmount(@NotNull Quester quester); 9 | 10 | long getTotalAmount(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/editors/parsers/AbstractParser.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.editors.parsers; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | public abstract interface AbstractParser { 6 | 7 | public abstract T parse(Player p, String msg) throws Throwable; 8 | 9 | public default void sendIndication(Player p) {} 10 | 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/npcs/NpcClickType.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.npcs; 2 | 3 | public enum NpcClickType { 4 | RIGHT, SHIFT_RIGHT, LEFT, SHIFT_LEFT; 5 | 6 | public static NpcClickType of(boolean left, boolean shift) { 7 | if (left) { 8 | return shift ? SHIFT_LEFT : LEFT; 9 | }else { 10 | return shift ? SHIFT_RIGHT : RIGHT; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/utils/compatibility/Paper.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.compatibility; 2 | 3 | import org.bukkit.event.entity.PlayerDeathEvent; 4 | import org.bukkit.inventory.ItemStack; 5 | import java.util.function.Predicate; 6 | 7 | public interface Paper { 8 | 9 | public void keepDeathItems(PlayerDeathEvent event, Predicate predicate); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/MissingDependencyException.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils; 2 | 3 | public class MissingDependencyException extends RuntimeException{ 4 | 5 | private static final long serialVersionUID = 8636504175650105867L; 6 | 7 | public MissingDependencyException(String depend){ 8 | super("Missing dependency: " + depend); 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/close/CloseBehavior.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui.close; 2 | 3 | /** 4 | * Represents the behavior that a closing GUI must take. 5 | *

6 | * This class is effectively sealed: its only subclasses are {@link StandardCloseBehavior}, 7 | * {@link OpenCloseBehavior} and {@link DelayCloseBehavior}. 8 | */ 9 | public interface CloseBehavior { 10 | } 11 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/commands/OutsideEditor.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.commands; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention (RUNTIME) 9 | @Target (METHOD) 10 | public @interface OutsideEditor {} 11 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/options/description/QuestDescription.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.options.description; 2 | 3 | public interface QuestDescription { 4 | 5 | public boolean showRewards(); 6 | 7 | public String getRewardsFormat(); 8 | 9 | public boolean showRequirements(); 10 | 11 | public String getRequirementsValid(); 12 | 13 | public String getRequirementsInvalid(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/branches/EndingStage.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.branches; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | import fr.skytasul.quests.api.stages.StageController; 6 | 7 | public interface EndingStage { 8 | 9 | public @NotNull StageController getStage(); 10 | 11 | public @Nullable QuestBranch getBranch(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/data/DataSavingException.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.data; 2 | 3 | public class DataSavingException extends Exception { 4 | 5 | private static final long serialVersionUID = 6381359339423992538L; 6 | 7 | public DataSavingException(String message) { 8 | super(message); 9 | } 10 | 11 | public DataSavingException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/resources/hikari.properties: -------------------------------------------------------------------------------- 1 | dataSource.cachePrepStmts=true 2 | dataSource.prepStmtCacheSize=250 3 | dataSource.prepStmtCacheSqlLimit=2048 4 | dataSource.useServerPrepStmts=true 5 | dataSource.useLocalSessionState=true 6 | dataSource.rewriteBatchedStatements=true 7 | dataSource.cacheResultSetMetadata=true 8 | dataSource.cacheServerConfiguration=true 9 | dataSource.elideSetAutoCommits=true 10 | dataSource.maintainTimeStats=false 11 | dataSource.autoReconnect=true -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/players/PlayerQuester.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.players; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import org.bukkit.OfflinePlayer; 5 | import org.bukkit.entity.Player; 6 | import org.jetbrains.annotations.NotNull; 7 | import java.util.Optional; 8 | 9 | public interface PlayerQuester extends Quester { 10 | 11 | public @NotNull Optional getPlayer(); 12 | 13 | public @NotNull OfflinePlayer getOfflinePlayer(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionAutoQuest.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import fr.skytasul.quests.api.options.QuestOptionBoolean; 5 | 6 | public class OptionAutoQuest extends QuestOptionBoolean { 7 | 8 | @Override 9 | public String getName() { 10 | return Lang.auto.toString(); 11 | } 12 | 13 | @Override 14 | public String getDescription() { 15 | return Lang.autoLore.toString(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/events/QuestRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.events; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import fr.skytasul.quests.api.quests.Quest; 5 | 6 | /** 7 | * Called when a quest is removed
8 | * May be called in a quest editing 9 | */ 10 | public class QuestRemoveEvent extends AbstractQuestEvent{ 11 | 12 | public QuestRemoveEvent(@NotNull Quest quest) { 13 | super(quest); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/creation/QuestCreationGui.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.creation; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import fr.skytasul.quests.api.gui.Gui; 5 | import fr.skytasul.quests.api.options.OptionSet; 6 | import fr.skytasul.quests.api.options.QuestOption; 7 | 8 | public interface QuestCreationGui extends Gui { 9 | 10 | void updateOptionItem(@NotNull QuestOption option); 11 | 12 | @NotNull 13 | OptionSet getOptionSet(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/options/StageOptionAutoRegister.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages.options; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import fr.skytasul.quests.api.stages.AbstractStage; 5 | import fr.skytasul.quests.api.stages.StageType; 6 | 7 | public interface StageOptionAutoRegister { 8 | 9 | boolean appliesTo(@NotNull StageType type); 10 | 11 | StageOptionCreator createOptionCreator(@NotNull StageType type); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/editors/parsers/WorldParser.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.editors.parsers; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Player; 6 | 7 | public class WorldParser implements AbstractParser { 8 | 9 | public World parse(Player p, String msg) throws Throwable { 10 | World world = Bukkit.getWorld(msg); 11 | if (world == null) p.sendMessage("§cThis world does not exist."); 12 | return world; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionBypassLimit.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import fr.skytasul.quests.api.options.QuestOptionBoolean; 5 | 6 | public class OptionBypassLimit extends QuestOptionBoolean { 7 | 8 | @Override 9 | public String getName() { 10 | return Lang.bypass.toString(); 11 | } 12 | 13 | @Override 14 | public String getDescription() { 15 | return Lang.bypassLore.toString(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/data/DataLoadingException.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.data; 2 | 3 | public class DataLoadingException extends Exception { 4 | 5 | private static final long serialVersionUID = -3697128675441649649L; 6 | 7 | public DataLoadingException(String message) { 8 | super(message); 9 | } 10 | 11 | public DataLoadingException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public DataLoadingException(Throwable cause) { 16 | super(cause); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/events/internal/BeautyQuestsLoadedEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.events.internal; 2 | 3 | import org.bukkit.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | 6 | public class BeautyQuestsLoadedEvent extends Event { 7 | 8 | @Override 9 | public HandlerList getHandlers() { 10 | return handlers; 11 | } 12 | 13 | public static HandlerList getHandlerList() { 14 | return handlers; 15 | } 16 | 17 | private static final HandlerList handlers = new HandlerList(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/ItemFactory.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui; 2 | 3 | import org.bukkit.inventory.ItemStack; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public interface ItemFactory { 7 | 8 | public @NotNull ItemStack getPreviousPage(); 9 | 10 | public @NotNull ItemStack getNextPage(); 11 | 12 | public @NotNull ItemStack getCancel(); 13 | 14 | public @NotNull ItemStack getDone(); 15 | 16 | public @NotNull ItemStack getNotDone(); 17 | 18 | public @NotNull ItemStack getNone(); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/close/OpenCloseBehavior.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui.close; 2 | 3 | import java.util.Objects; 4 | import org.jetbrains.annotations.NotNull; 5 | import fr.skytasul.quests.api.gui.Gui; 6 | 7 | public class OpenCloseBehavior implements CloseBehavior { 8 | 9 | private final @NotNull Gui other; 10 | 11 | public OpenCloseBehavior(@NotNull Gui other) { 12 | this.other = Objects.requireNonNull(other); 13 | } 14 | 15 | public @NotNull Gui getOther() { 16 | return other; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionHideNoRequirements.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import fr.skytasul.quests.api.options.QuestOptionBoolean; 5 | 6 | public class OptionHideNoRequirements extends QuestOptionBoolean { 7 | 8 | @Override 9 | public String getName() { 10 | return Lang.hideNoRequirements.toString(); 11 | } 12 | 13 | @Override 14 | public String getDescription() { 15 | return Lang.hideNoRequirementsLore.toString(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionScoreboardEnabled.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import fr.skytasul.quests.api.options.QuestOptionBoolean; 5 | 6 | public class OptionScoreboardEnabled extends QuestOptionBoolean { 7 | 8 | @Override 9 | public String getName() { 10 | return Lang.scoreboard.toString(); 11 | } 12 | 13 | @Override 14 | public String getDescription() { 15 | return Lang.scoreboardLore.toString(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/commands/CommandsManager.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.commands; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | import revxrsal.commands.Lamp; 6 | import revxrsal.commands.bukkit.actor.BukkitCommandActor; 7 | import revxrsal.commands.orphan.OrphanCommand; 8 | 9 | public interface CommandsManager { 10 | 11 | @NotNull 12 | Lamp getHandler(); 13 | 14 | void registerCommands(@Nullable String subpath, @NotNull OrphanCommand @NotNull... commands); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/questers/events/AbstractQuesterEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.questers.events; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import org.bukkit.event.Event; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public abstract class AbstractQuesterEvent extends Event { 8 | 9 | protected final @NotNull Quester quester; 10 | 11 | protected AbstractQuesterEvent(@NotNull Quester quester) { 12 | this.quester = quester; 13 | } 14 | 15 | public @NotNull Quester getQuester() { 16 | return quester; 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/messaging/MessageProcessor.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils.messaging; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | public interface MessageProcessor { 7 | 8 | default @Nullable PlaceholderRegistry processPlaceholders(@Nullable PlaceholderRegistry placeholders, 9 | @NotNull PlaceholdersContext context) { 10 | return placeholders; 11 | } 12 | 13 | default @NotNull String processString(@NotNull String string, @NotNull PlaceholdersContext context) { 14 | return string; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/blocks/BQBlockOptions.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.blocks; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | public class BQBlockOptions { 7 | 8 | private final @NotNull BQBlockType type; 9 | private final @Nullable String customName; 10 | 11 | public BQBlockOptions(BQBlockType type, String customName) { 12 | this.type = type; 13 | this.customName = customName; 14 | } 15 | 16 | public @NotNull BQBlockType getType() { 17 | return type; 18 | } 19 | 20 | public @Nullable String getCustomName() { 21 | return customName; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/creation/StageCreationContext.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages.creation; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import fr.skytasul.quests.api.stages.AbstractStage; 5 | import fr.skytasul.quests.api.stages.StageType; 6 | 7 | public interface StageCreationContext { 8 | 9 | @NotNull 10 | StageGuiLine getLine(); 11 | 12 | @NotNull 13 | StageType getType(); 14 | 15 | boolean isEndingStage(); 16 | 17 | @NotNull 18 | StageCreation getCreation(); 19 | 20 | void remove(); 21 | 22 | void reopenGui(); 23 | 24 | void removeAndReopenGui(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /dist/all-jar.xml: -------------------------------------------------------------------------------- 1 | 5 | all-jar 6 | 7 | jar 8 | 9 | false 10 | 11 | 12 | 13 | true 14 | false 15 | 16 | 17 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/close/DelayCloseBehavior.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui.close; 2 | 3 | import java.util.Objects; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | /** 7 | * This close behavior will remove the player from the GUI system and execute the runnable on the 8 | * next tick. 9 | */ 10 | public class DelayCloseBehavior implements CloseBehavior { 11 | 12 | private final @NotNull Runnable delayed; 13 | 14 | public DelayCloseBehavior(@NotNull Runnable delayed) { 15 | this.delayed = Objects.requireNonNull(delayed); 16 | } 17 | 18 | public @NotNull Runnable getDelayed() { 19 | return delayed; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/AutoRegistered.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils; 2 | 3 | import static java.lang.annotation.ElementType.TYPE; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | import java.lang.annotation.Inherited; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.Target; 8 | import org.bukkit.event.Listener; 9 | 10 | /** 11 | * Marks classes that will be automatically registered as event listener if they implement the 12 | * {@link Listener} interface. 13 | * 14 | * @author SkytAsul 15 | */ 16 | @Retention(RUNTIME) 17 | @Target(TYPE) 18 | @Inherited 19 | public @interface AutoRegistered { 20 | } 21 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/mobs/BQWildStacker.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations.mobs; 2 | 3 | import com.bgsoftware.wildstacker.api.WildStackerAPI; 4 | import fr.skytasul.quests.api.QuestsAPI; 5 | import org.bukkit.entity.LivingEntity; 6 | import org.bukkit.entity.Player; 7 | 8 | public class BQWildStacker { 9 | 10 | private BQWildStacker() {} 11 | 12 | public static void initialize() { 13 | QuestsAPI.getAPI().registerMobStacker(entity -> { 14 | if (entity instanceof LivingEntity && !(entity instanceof Player)) 15 | return WildStackerAPI.getEntityAmount((LivingEntity) entity); 16 | return 1; 17 | }); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/editors/EditorFactory.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.editors; 2 | 3 | import java.util.function.Consumer; 4 | import org.bukkit.entity.Player; 5 | import org.jetbrains.annotations.NotNull; 6 | import com.cryptomorin.xseries.XMaterial; 7 | import fr.skytasul.quests.api.editors.parsers.AbstractParser; 8 | import fr.skytasul.quests.api.npcs.BqNpc; 9 | 10 | public interface EditorFactory { 11 | 12 | public @NotNull AbstractParser getMaterialParser(boolean item, boolean block); 13 | 14 | public @NotNull Editor createNpcSelection(@NotNull Player player, @NotNull Runnable cancel, 15 | @NotNull Consumer callback); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/editors/EditorManager.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.editors; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public interface EditorManager { 7 | 8 | public T start(@NotNull T editor); 9 | 10 | public default void stop(@NotNull Editor editor) { 11 | leave(editor.getPlayer()); 12 | } 13 | 14 | public void leave(@NotNull Player player); 15 | 16 | public void leaveAll(); 17 | 18 | public boolean isInEditor(@NotNull Player player); 19 | 20 | public @NotNull EditorFactory getFactory(); 21 | 22 | public void setFactory(@NotNull EditorFactory factory); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/questers/events/QuesterResetEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.questers.events; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public class QuesterResetEvent extends AbstractQuesterEvent { 8 | 9 | public QuesterResetEvent(@NotNull Quester quester) { 10 | super(quester); 11 | } 12 | 13 | @Override 14 | public HandlerList getHandlers() { 15 | return handlers; 16 | } 17 | 18 | public static HandlerList getHandlerList() { 19 | return handlers; 20 | } 21 | 22 | private static final HandlerList handlers = new HandlerList(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/utils/DebugUtils.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils; 2 | 3 | import java.util.StringJoiner; 4 | 5 | public class DebugUtils { 6 | 7 | private DebugUtils() {} 8 | 9 | public static String stackTraces(int from, int to){ 10 | StringJoiner joiner = new StringJoiner(" -> "); 11 | StackTraceElement[] stack = Thread.currentThread().getStackTrace(); 12 | for (int i = from + 1; i <= to && i < stack.length; i++) { 13 | joiner.add(stack[from].getClassName().replace("fr.skytasul.quests", "f.s.q") + "." + stack[from].getMethodName() 14 | + " " + stack[from].getLineNumber()); 15 | } 16 | return joiner.toString(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/editors/parsers/ScoreboardObjectiveParser.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.editors.parsers; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.scoreboard.Objective; 6 | import fr.skytasul.quests.api.localization.Lang; 7 | 8 | public class ScoreboardObjectiveParser implements AbstractParser { 9 | 10 | @Override 11 | public Objective parse(Player p, String msg) throws Throwable { 12 | Objective objective = Bukkit.getScoreboardManager().getMainScoreboard().getObjective(msg); 13 | if (objective == null) Lang.SCOREBOARD_OBJECTIVE_NOT_FOUND.send(p); 14 | return objective; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/QuestVisibilityLocation.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | 6 | public enum QuestVisibilityLocation { 7 | 8 | TAB_NOT_STARTED(Lang.visibility_notStarted.toString()), 9 | TAB_IN_PROGRESS(Lang.visibility_inProgress.toString()), 10 | TAB_FINISHED(Lang.visibility_finished.toString()), 11 | MAPS(Lang.visibility_maps.toString()); 12 | 13 | private final @NotNull String name; 14 | 15 | private QuestVisibilityLocation(@NotNull String name) { 16 | this.name = name; 17 | } 18 | 19 | public @NotNull String getName() { 20 | return name; 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionStartRewards.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | import fr.skytasul.quests.api.options.QuestOptionRewards; 6 | 7 | public class OptionStartRewards extends QuestOptionRewards { 8 | 9 | @Override 10 | public XMaterial getItemMaterial() { 11 | return XMaterial.CARROT_ON_A_STICK; 12 | } 13 | 14 | @Override 15 | public String getItemName() { 16 | return Lang.startRewards.toString(); 17 | } 18 | 19 | @Override 20 | public String getItemDescription() { 21 | return Lang.startRewardsLore.toString(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/utils/compatibility/InternalIntegrations.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.compatibility; 2 | 3 | import fr.skytasul.quests.BeautyQuests; 4 | import fr.skytasul.quests.api.utils.IntegrationManager.BQDependency; 5 | 6 | public final class InternalIntegrations { 7 | 8 | public static final BQDependency PlayerBlockTracker = new BQDependency("PlayerBlockTracker"); 9 | public static final BQDependency AccountsHook = new BQDependency("AccountsHook"); 10 | 11 | static { 12 | BeautyQuests.getInstance().getIntegrationManager().addDependency(PlayerBlockTracker); 13 | BeautyQuests.getInstance().getIntegrationManager().addDependency(AccountsHook); 14 | } 15 | 16 | private InternalIntegrations() {} 17 | 18 | } 19 | -------------------------------------------------------------------------------- /paper/src/main/java/fr/skytasul/quests/utils/compatibility/PaperImplementation.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.compatibility; 2 | 3 | import org.bukkit.event.entity.PlayerDeathEvent; 4 | import org.bukkit.inventory.ItemStack; 5 | import java.util.Iterator; 6 | import java.util.function.Predicate; 7 | 8 | public class PaperImplementation implements Paper { 9 | 10 | @Override 11 | public void keepDeathItems(PlayerDeathEvent event, Predicate predicate) { 12 | for (Iterator iterator = event.getDrops().iterator(); iterator.hasNext();) { 13 | ItemStack item = iterator.next(); 14 | if (predicate.test(item)) { 15 | iterator.remove(); 16 | event.getItemsToKeep().add(item); 17 | } 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/events/questers/AbstractQuesterQuestEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.events.questers; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import fr.skytasul.quests.api.questers.events.AbstractQuesterEvent; 5 | import fr.skytasul.quests.api.quests.Quest; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | public abstract class AbstractQuesterQuestEvent extends AbstractQuesterEvent { 9 | 10 | protected final @NotNull Quest quest; 11 | 12 | protected AbstractQuesterQuestEvent(@NotNull Quester acc, @NotNull Quest quest) { 13 | super(acc); 14 | this.quest = quest; 15 | } 16 | 17 | public @NotNull Quest getQuest() { 18 | return quest; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/BQTokenEnchant.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations; 2 | 3 | import com.vk2gpz.tokenenchant.event.TEBlockExplodeEvent; 4 | import fr.skytasul.quests.api.events.internal.BQBlockBreakEvent; 5 | import org.bukkit.Bukkit; 6 | import org.bukkit.event.EventHandler; 7 | import org.bukkit.event.EventPriority; 8 | import org.bukkit.event.Listener; 9 | 10 | public class BQTokenEnchant implements Listener { 11 | 12 | @EventHandler (priority = EventPriority.MONITOR) 13 | public void onTEBlockExplode(TEBlockExplodeEvent e) { 14 | if (e.isCancelled()) return; 15 | if (e.getPlayer() == null) return; 16 | Bukkit.getPluginManager().callEvent(new BQBlockBreakEvent(e.getPlayer(), e.blockList())); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/players/AbstractPlayerQuesterImplementation.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.players; 2 | 3 | import fr.skytasul.quests.api.players.PlayerQuester; 4 | import fr.skytasul.quests.api.questers.data.QuesterData; 5 | import fr.skytasul.quests.api.players.PlayerManager; 6 | import fr.skytasul.quests.questers.AbstractQuesterImplementation; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | // TODO extract common things from implementations 10 | public abstract class AbstractPlayerQuesterImplementation extends AbstractQuesterImplementation implements PlayerQuester { 11 | 12 | protected AbstractPlayerQuesterImplementation(@NotNull PlayerManager provider, 13 | @NotNull QuesterData dataHandler) { 14 | super(provider, dataHandler); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /paper/src/test/java/fr/skytasul/quests/test/TestUtils.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.test; 2 | 3 | import fr.skytasul.quests.BeautyQuests; 4 | import fr.skytasul.quests.api.events.internal.BeautyQuestsLoadedEvent; 5 | import org.bukkit.event.Event; 6 | import org.mockbukkit.mockbukkit.MockBukkit; 7 | 8 | public class TestUtils { 9 | 10 | public static EventWaiter waitForEvent(Class eventClass) { 11 | return new EventWaiter<>(eventClass); 12 | } 13 | 14 | public static BeautyQuests loadPlugin() { 15 | MockBukkit.getOrCreateMock(); 16 | var loadedWaiter = new EventWaiter<>(BeautyQuestsLoadedEvent.class); 17 | var plugin = MockBukkit.load(BeautyQuests.class, Boolean.TRUE); 18 | loadedWaiter.assertFired(10); 19 | return plugin; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/options/StageQuesterStrategy.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages.options; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import org.bukkit.entity.Player; 5 | import org.jetbrains.annotations.NotNull; 6 | import java.util.Collection; 7 | 8 | public interface StageQuesterStrategy { 9 | 10 | /** 11 | * Get questers for which the stage should be updated when the player does the action associated 12 | * with the stage. 13 | * 14 | * @param player player that did the action 15 | * @return a collection containing the questers that should progress at the same time as the 16 | * player's quester 17 | */ 18 | @NotNull 19 | Collection getAdditionalQuesters(@NotNull Player player); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionEndSound.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | import fr.skytasul.quests.api.options.QuestOptionString; 6 | import org.bukkit.entity.Player; 7 | 8 | public class OptionEndSound extends QuestOptionString { 9 | 10 | @Override 11 | public void sendIndication(Player p) { 12 | Lang.WRITE_END_SOUND.send(p); 13 | } 14 | 15 | @Override 16 | public XMaterial getItemMaterial() { 17 | return XMaterial.JUKEBOX; 18 | } 19 | 20 | @Override 21 | public String getItemName() { 22 | return Lang.endSound.toString(); 23 | } 24 | 25 | @Override 26 | public String getItemDescription() { 27 | return Lang.endSoundLore.toString(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/options/description/QuestDescriptionProvider.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.options.description; 2 | 3 | import java.util.Comparator; 4 | import java.util.List; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | public interface QuestDescriptionProvider { 9 | 10 | public static final Comparator COMPARATOR = Comparator.comparingDouble(QuestDescriptionProvider::getDescriptionPriority); 11 | 12 | @Nullable 13 | List<@Nullable String> provideDescription(@NotNull QuestDescriptionContext context); 14 | 15 | @NotNull 16 | String getDescriptionId(); 17 | 18 | double getDescriptionPriority(); 19 | 20 | default boolean prefixDescriptionWithNewLine() { 21 | return true; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: skytasul 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionCancellable.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import fr.skytasul.quests.api.QuestsConfiguration; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | import fr.skytasul.quests.api.options.OptionSet; 6 | import fr.skytasul.quests.api.options.QuestOptionBoolean; 7 | 8 | public class OptionCancellable extends QuestOptionBoolean { 9 | 10 | @Override 11 | public boolean shouldDisplay(OptionSet options) { 12 | return QuestsConfiguration.getConfig().getQuestsMenuConfig().allowPlayerCancelQuest(); 13 | } 14 | 15 | @Override 16 | public String getName() { 17 | return Lang.cancellable.toString(); 18 | } 19 | 20 | @Override 21 | public String getDescription() { 22 | return Lang.cancellableLore.toString(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionStartMessage.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | import fr.skytasul.quests.api.options.QuestOptionString; 6 | import org.bukkit.entity.Player; 7 | 8 | public class OptionStartMessage extends QuestOptionString { 9 | 10 | @Override 11 | public void sendIndication(Player p) { 12 | Lang.WRITE_START_MESSAGE.send(p); 13 | } 14 | 15 | @Override 16 | public XMaterial getItemMaterial() { 17 | return XMaterial.PAPER; 18 | } 19 | 20 | @Override 21 | public String getItemName() { 22 | return Lang.startMessage.toString(); 23 | } 24 | 25 | @Override 26 | public String getItemDescription() { 27 | return Lang.startMessageLore.toString(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/questers/data/QuesterPoolData.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.questers.data; 2 | 3 | import fr.skytasul.quests.api.pools.QuestPool; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | import org.jetbrains.annotations.UnmodifiableView; 7 | import java.util.Set; 8 | import java.util.concurrent.CompletableFuture; 9 | 10 | public interface QuesterPoolData { 11 | 12 | int getPoolId(); 13 | 14 | @Nullable 15 | QuestPool getPool(); 16 | 17 | long getLastGive(); 18 | 19 | void setLastGive(long lastGive); 20 | 21 | @NotNull 22 | @UnmodifiableView 23 | Set<@NotNull Integer> getCompletedQuests(); 24 | 25 | void setCompletedQuests(@NotNull Set completedQuests); 26 | 27 | @NotNull 28 | CompletableFuture remove(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionName.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | import fr.skytasul.quests.api.options.QuestOptionString; 6 | import org.bukkit.entity.Player; 7 | 8 | public class OptionName extends QuestOptionString { 9 | 10 | @Override 11 | public void sendIndication(Player p) { 12 | Lang.QUEST_NAME.send(p); 13 | } 14 | 15 | @Override 16 | public XMaterial getItemMaterial() { 17 | return XMaterial.NAME_TAG; 18 | } 19 | 20 | @Override 21 | public String getItemName() { 22 | return Lang.questName.toString(); 23 | } 24 | 25 | @Override 26 | public String getItemDescription() { 27 | return Lang.questNameLore.toString(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionEndMessage.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | import fr.skytasul.quests.api.options.QuestOptionString; 6 | import org.bukkit.entity.Player; 7 | 8 | public class OptionEndMessage extends QuestOptionString { 9 | 10 | @Override 11 | public void sendIndication(Player p) { 12 | Lang.WRITE_END_MESSAGE.send(p); 13 | } 14 | 15 | @Override 16 | public XMaterial getItemMaterial() { 17 | return XMaterial.PAPER; 18 | } 19 | 20 | @Override 21 | public String getItemName() { 22 | return Lang.endMessage.toString(); 23 | } 24 | 25 | @Override 26 | public String getItemDescription() { 27 | return Lang.endMessageLore.toString(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for BeautyQuests. 4 | labels: feature request 5 | 6 | --- 7 | 8 | **Is your feature request related to a problem?** 9 | A clear and concise description of what the problem is. E.g. "I'm always frustrated when [...]" 10 | 11 | **Describe a possible solution** 12 | A clear and concise description of what you want should be added. 13 | 14 | **Describe alternatives you've considered (optional)** 15 | A clear and concise description of any alternative solutions or features you've considered. 16 | 17 | **Additional context (optional)** 18 | Add any other context or screenshots about the feature request here. 19 | 20 | 21 | (FR: Si vous êtes plus facilement compréhensible en français, écrivez dans cette langue car il s'agit de ma langue natale) -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/GuiManager.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | public interface GuiManager { 8 | 9 | void open(@NotNull Player player, @NotNull Gui inventory); 10 | 11 | void closeAndExit(@NotNull Player player); 12 | 13 | void closeWithoutExit(@NotNull Player player); 14 | 15 | void closeAll(); 16 | 17 | boolean hasGuiOpened(@NotNull Player player); 18 | 19 | @Nullable 20 | Gui getOpenedGui(@NotNull Player player); 21 | 22 | public @NotNull GuiFactory getFactory(); 23 | 24 | public void setFactory(@NotNull GuiFactory factory); 25 | 26 | public @NotNull ItemFactory getItemFactory(); 27 | 28 | public void setItemFactory(@NotNull ItemFactory factory); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/options/OptionSet.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.options; 2 | 3 | import fr.skytasul.quests.api.QuestsAPI; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | @SuppressWarnings ("rawtypes") 8 | public interface OptionSet extends Iterable { 9 | 10 | > @NotNull T getOption(@NotNull Class optionClass); 11 | 12 | boolean hasOption(@NotNull Class> clazz); 13 | 14 | default @Nullable D getOptionValueOrDef(@NotNull Class> clazz) { 15 | for (QuestOption option : this) { 16 | if (clazz.isInstance(option)) 17 | return (D) option.getValue(); 18 | } 19 | return QuestsAPI.getAPI().getQuestOption(clazz).orElseThrow().defaultValue; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/editors/parsers/PatternParser.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.editors.parsers; 2 | 3 | import java.util.regex.Pattern; 4 | import java.util.regex.PatternSyntaxException; 5 | import org.bukkit.entity.Player; 6 | import fr.skytasul.quests.api.localization.Lang; 7 | import fr.skytasul.quests.api.utils.messaging.PlaceholderRegistry; 8 | 9 | public class PatternParser implements AbstractParser { 10 | 11 | public static final PatternParser PARSER = new PatternParser(); 12 | 13 | private PatternParser() {} 14 | 15 | @Override 16 | public Pattern parse(Player p, String msg) throws Throwable { 17 | try { 18 | return Pattern.compile(msg); 19 | }catch (PatternSyntaxException ex) { 20 | Lang.INVALID_PATTERN.send(p, PlaceholderRegistry.of("input", msg)); 21 | return null; 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/pools/QuestPoolsManager.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.pools; 2 | 3 | import java.util.Collection; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | import org.jetbrains.annotations.UnmodifiableView; 7 | import fr.skytasul.quests.api.requirements.RequirementList; 8 | 9 | public interface QuestPoolsManager { 10 | 11 | public @NotNull QuestPool createPool(@Nullable QuestPool editing, @Nullable String npcID, @Nullable String hologram, 12 | int maxQuests, int questsPerLaunch, boolean redoAllowed, long timeDiff, boolean avoidDuplicates, 13 | @NotNull RequirementList requirements); 14 | 15 | public void removePool(int id); 16 | 17 | public @Nullable QuestPool getPool(int id); 18 | 19 | public @NotNull @UnmodifiableView Collection getPools(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/utils/compatibility/BQBackwardCompat.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.compatibility; 2 | 3 | import fr.skytasul.quests.api.QuestsAPI; 4 | import fr.skytasul.quests.api.stages.StageType; 5 | import org.bukkit.configuration.ConfigurationSection; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | import java.util.Optional; 9 | 10 | public class BQBackwardCompat { 11 | 12 | public static @NotNull Optional> loadStageFromConfig(@Nullable String stageType, 13 | @NotNull ConfigurationSection config) { 14 | 15 | if ("INTERACT".equals(stageType)) { 16 | stageType = config.contains("location") ? "INTERACT_LOCATION" : "INTERACT_BLOCK"; 17 | return QuestsAPI.getAPI().getStages().getType(stageType); 18 | } 19 | 20 | return Optional.empty(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/utils/nms/NullNMS.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.nms; 2 | 3 | import fr.skytasul.quests.utils.ReflectUtils; 4 | import org.bukkit.inventory.meta.ItemMeta; 5 | 6 | public class NullNMS extends NMS { 7 | 8 | @Override 9 | public boolean equalsWithoutNBT(ItemMeta meta1, ItemMeta meta2) throws ReflectiveOperationException { 10 | return meta1.equals(meta2); 11 | } 12 | 13 | public ReflectUtils getReflect(){ 14 | throw new UnsupportedOperationException("Your version is not compatible."); 15 | } 16 | 17 | public Object getIChatBaseComponent(String text){ 18 | throw new UnsupportedOperationException("Your version is not compatible."); 19 | } 20 | 21 | public Object getEnumChatFormat(int value){ 22 | throw new UnsupportedOperationException("Your version is not compatible."); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/events/AbstractQuestEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.events; 2 | 3 | import org.bukkit.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | import fr.skytasul.quests.api.quests.Quest; 7 | 8 | public abstract class AbstractQuestEvent extends Event { 9 | 10 | protected final @NotNull Quest quest; 11 | 12 | protected AbstractQuestEvent(@NotNull Quest quest) { 13 | this.quest = quest; 14 | } 15 | 16 | public @NotNull Quest getQuest() { 17 | return quest; 18 | } 19 | 20 | @Override 21 | public HandlerList getHandlers(){ 22 | return handlers; 23 | } 24 | 25 | public static HandlerList getHandlerList() { 26 | return handlers; 27 | } 28 | 29 | private static final HandlerList handlers = new HandlerList(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/events/questers/QuesterQuestFinishEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.events.questers; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import fr.skytasul.quests.api.quests.Quest; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Called when a player finish a quest 10 | */ 11 | public class QuesterQuestFinishEvent extends AbstractQuesterQuestEvent{ 12 | 13 | public QuesterQuestFinishEvent(@NotNull Quester who, @NotNull Quest quest) { 14 | super(who, quest); 15 | } 16 | 17 | @Override 18 | public HandlerList getHandlers() { 19 | return handlers; 20 | } 21 | 22 | public static HandlerList getHandlerList() { 23 | return handlers; 24 | } 25 | 26 | private static final HandlerList handlers = new HandlerList(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/events/questers/QuesterQuestLaunchEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.events.questers; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import fr.skytasul.quests.api.quests.Quest; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Called when a player starts a quest 10 | */ 11 | public class QuesterQuestLaunchEvent extends AbstractQuesterQuestEvent { 12 | 13 | public QuesterQuestLaunchEvent(@NotNull Quester quester, @NotNull Quest quest) { 14 | super(quester, quest); 15 | } 16 | 17 | @Override 18 | public HandlerList getHandlers() { 19 | return handlers; 20 | } 21 | 22 | public static HandlerList getHandlerList() { 23 | return handlers; 24 | } 25 | 26 | private static final HandlerList handlers = new HandlerList(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/blocks/BQBlockMaterial.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.blocks; 2 | 3 | import com.cryptomorin.xseries.XBlock; 4 | import com.cryptomorin.xseries.XMaterial; 5 | import fr.skytasul.quests.api.blocks.BQBlock; 6 | import fr.skytasul.quests.api.blocks.BQBlockOptions; 7 | import org.bukkit.block.Block; 8 | 9 | public class BQBlockMaterial extends BQBlock { 10 | 11 | private final XMaterial material; 12 | 13 | public BQBlockMaterial(BQBlockOptions options, XMaterial material) { 14 | super(options); 15 | this.material = material; 16 | } 17 | 18 | @Override 19 | public XMaterial retrieveMaterial() { 20 | return material; 21 | } 22 | 23 | @Override 24 | public boolean applies(Block block) { 25 | return XBlock.isSimilar(block, material); 26 | } 27 | 28 | @Override 29 | public String getDataString() { 30 | return material.name(); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/QuestsAPIProvider.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests; 2 | 3 | import fr.skytasul.quests.api.QuestsAPI; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | import java.util.Objects; 7 | 8 | public final class QuestsAPIProvider { 9 | 10 | private static @Nullable QuestsAPI instance; 11 | 12 | private QuestsAPIProvider() {} 13 | 14 | public static @NotNull QuestsAPI getAPI() { 15 | if (instance == null) 16 | throw new IllegalStateException("BeautyQuests API is not yet initialized"); 17 | return instance; 18 | } 19 | 20 | static void initializeAPI(@NotNull QuestsAPI api) { 21 | if (instance != null) 22 | throw new IllegalStateException("BeautyQuests API has already been set"); 23 | instance = Objects.requireNonNull(api); 24 | } 25 | 26 | static void removeAPI() { 27 | instance = null; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/events/questers/QuesterQuestResetEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.events.questers; 2 | 3 | import org.bukkit.event.HandlerList; 4 | import org.jetbrains.annotations.NotNull; 5 | import fr.skytasul.quests.api.questers.Quester; 6 | import fr.skytasul.quests.api.quests.Quest; 7 | 8 | /** 9 | * Called when the stage of a player is cancelled 10 | */ 11 | public class QuesterQuestResetEvent extends AbstractQuesterQuestEvent { 12 | 13 | public QuesterQuestResetEvent(@NotNull Quester account, @NotNull Quest quest) { 14 | super(account, quest); 15 | } 16 | 17 | @Override 18 | public HandlerList getHandlers() { 19 | return handlers; 20 | } 21 | 22 | public static HandlerList getHandlerList() { 23 | return handlers; 24 | } 25 | 26 | private static final HandlerList handlers = new HandlerList(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/npcs/BqInternalNpc.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.npcs; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.entity.Entity; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | public interface BqInternalNpc { 9 | 10 | public String getInternalId(); 11 | 12 | public abstract @NotNull String getName(); 13 | 14 | public abstract boolean isSpawned(); 15 | 16 | public abstract @Nullable Entity getEntity(); 17 | 18 | public abstract @Nullable Location getLocation(); 19 | 20 | /** 21 | * Sets the "paused" state of the NPC navigation 22 | * 23 | * @param paused should the navigation be paused 24 | * @return true if the navigation was paused before this call, false 25 | * otherwise 26 | */ 27 | public abstract boolean setNavigationPaused(boolean paused); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/MinecraftVersion.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils; 2 | 3 | import org.bukkit.Bukkit; 4 | 5 | public final class MinecraftVersion { 6 | 7 | public static final String VERSION_STRING; 8 | public static final int MAJOR; 9 | public static final int MINOR; 10 | 11 | static { 12 | // e.g. Bukkit.getBukkitVersion() -> 1.17.1-R0.1-SNAPSHOT 13 | VERSION_STRING = Bukkit.getBukkitVersion().split("-R")[0]; 14 | String[] versions = VERSION_STRING.split("\\."); 15 | MAJOR = Integer.parseInt(versions[1]); 16 | MINOR = versions.length <= 2 ? 0 : Integer.parseInt(versions[2]); 17 | } 18 | 19 | private MinecraftVersion() {} 20 | 21 | public static boolean isHigherThan(int major, int minor) { 22 | if (MAJOR > major) 23 | return true; 24 | 25 | if (MAJOR == major && MINOR >= minor) 26 | return true; 27 | 28 | return false; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/blocks/BQBlockData.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.blocks; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.blocks.BQBlock; 5 | import fr.skytasul.quests.api.blocks.BQBlockOptions; 6 | import org.bukkit.block.Block; 7 | import org.bukkit.block.data.BlockData; 8 | 9 | public class BQBlockData extends BQBlock { 10 | 11 | private final BlockData data; 12 | 13 | public BQBlockData(BQBlockOptions options, BlockData data) { 14 | super(options); 15 | this.data = data; 16 | } 17 | 18 | @Override 19 | public boolean applies(Block block) { 20 | return block.getBlockData().matches(data); 21 | } 22 | 23 | @Override 24 | public XMaterial retrieveMaterial() { 25 | return XMaterial.matchXMaterial(data.getMaterial()); 26 | } 27 | 28 | @Override 29 | public String getDataString() { 30 | return data.getAsString(true); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/progress/itemdescription/ItemsDescriptionConfiguration.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils.progress.itemdescription; 2 | 3 | import java.util.Set; 4 | import org.jetbrains.annotations.NotNull; 5 | import fr.skytasul.quests.api.options.description.DescriptionSource; 6 | 7 | public interface ItemsDescriptionConfiguration { 8 | 9 | @NotNull 10 | String getSingleItemFormat(); 11 | 12 | @NotNull 13 | String getMultipleItemsFormat(); 14 | 15 | String getSplitPrefix(); 16 | 17 | boolean isAloneSplitInlined(); 18 | 19 | Set getSplitSources(); 20 | 21 | default boolean isSourceSplit(@NotNull DescriptionSource source) { 22 | if (source == DescriptionSource.FORCESPLIT) 23 | return true; 24 | if (source == DescriptionSource.FORCELINE) 25 | return false; 26 | return getSplitSources().contains(source); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug report for BeautyQuests. 4 | labels: bug 5 | 6 | --- 7 | 8 | **Describe the bug** 9 | A clear and concise description of what the bug is and how it occurs. 10 | 11 | **Reproduction** 12 | Steps to reproduce the behavior. (If not already explained above.) 13 | 14 | **Screenshots, error messages** 15 | If applicable, add screenshots to help explain your problem. 16 | Are there error messages in the console or in the chat? 17 | 18 | **Software** 19 | BeautyQuests version: 20 | Game version: 21 | Server version: 22 | Server type (e.i. PaperSpigot): 23 | Are you using a protocol hack (like ViaVersion)? 24 | 25 | **Additional context (optional)** 26 | Add any other context about the problem here. 27 | 28 | 29 | (FR: Si vous êtes plus facilement compréhensible en français, écrivez dans cette langue car il s'agit de ma langue natale) -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/StageHandler.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import org.bukkit.entity.Player; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public interface StageHandler { 8 | 9 | default void stageStart(@NotNull Quester quester, @NotNull StageController stage) {} 10 | 11 | default void stageEnd(@NotNull Quester quester, @NotNull StageController stage) {} 12 | 13 | default void stageJoin(@NotNull Player p, @NotNull Quester quester, @NotNull StageController stage) {} 14 | 15 | default void stageLeave(@NotNull Player p, @NotNull Quester quester, @NotNull StageController stage) {} 16 | 17 | default void stageLoad(@NotNull StageController stage) {} 18 | 19 | default void stageUnload(@NotNull StageController stage) {} 20 | 21 | default void stageUpdated(@NotNull Quester quester, @NotNull StageController stage) {} 22 | 23 | } -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/questers/events/QuesterLeaveEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.questers.events; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | public class QuesterLeaveEvent extends AbstractQuesterEvent { 9 | 10 | private final @NotNull Player player; 11 | 12 | public QuesterLeaveEvent(@NotNull Quester quester, @NotNull Player player) { 13 | super(quester); 14 | this.player = player; 15 | } 16 | 17 | public @NotNull Player getPlayer() { 18 | return player; 19 | } 20 | 21 | @Override 22 | public HandlerList getHandlers() { 23 | return handlers; 24 | } 25 | 26 | public static HandlerList getHandlerList() { 27 | return handlers; 28 | } 29 | 30 | private static final HandlerList handlers = new HandlerList(); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/questers/QuesterProvider.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.questers; 2 | 3 | import net.kyori.adventure.key.Keyed; 4 | import org.bukkit.entity.Player; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.UnmodifiableView; 7 | import java.util.Collection; 8 | import java.util.Optional; 9 | 10 | public interface QuesterProvider extends Keyed { 11 | 12 | @NotNull 13 | default Optional getQuesterName(@NotNull String identifier) { 14 | return Optional.empty(); 15 | } 16 | 17 | @NotNull 18 | @UnmodifiableView 19 | Collection getPlayerQuesters(@NotNull Player player); 20 | 21 | @NotNull 22 | @UnmodifiableView 23 | Collection getLoadedQuesters(); 24 | 25 | /** 26 | * Called when everything is setup. 27 | * 28 | * @param questerManager 29 | */ 30 | default void load(@NotNull QuesterManager questerManager) {} 31 | 32 | } 33 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/quester/QuestQuesterStrategyCreator.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.quester; 2 | 3 | import fr.skytasul.quests.api.serializable.SerializableCreator; 4 | import org.jetbrains.annotations.NotNull; 5 | import java.util.function.Supplier; 6 | 7 | public class QuestQuesterStrategyCreator extends SerializableCreator { 8 | 9 | private final @NotNull String name, description; 10 | 11 | public QuestQuesterStrategyCreator(@NotNull String id, @NotNull Class clazz, 12 | Supplier<@NotNull QuestQuesterStrategy> newObjectSupplier, @NotNull String name, @NotNull String description) { 13 | super(id, clazz, newObjectSupplier); 14 | this.name = name; 15 | this.description = description; 16 | } 17 | 18 | public @NotNull String getName() { 19 | return name; 20 | } 21 | 22 | public @NotNull String getDescription() { 23 | return description; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/WorldGuardExitEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations.worldguard; 2 | 3 | import com.sk89q.worldguard.protection.regions.ProtectedRegion; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.bukkit.event.player.PlayerEvent; 7 | import java.util.Set; 8 | 9 | public class WorldGuardExitEvent extends PlayerEvent { 10 | 11 | private final Set exited; 12 | 13 | WorldGuardExitEvent(Player who, Set exited) { 14 | super(who); 15 | this.exited = exited; 16 | } 17 | 18 | public Set getRegionsExited() { 19 | return exited; 20 | } 21 | 22 | @Override 23 | public HandlerList getHandlers() { 24 | return handlers; 25 | } 26 | 27 | public static HandlerList getHandlerList() { 28 | return handlers; 29 | } 30 | 31 | private static final HandlerList handlers = new HandlerList(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/npcs/dialogs/MessageSender.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.npcs.dialogs; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public interface MessageSender { 7 | 8 | /** 9 | * Displays a message to a player. If there was already a message being displayed for this dialog, 10 | * then this should stop displaying it. 11 | * 12 | * @param player Player to display the message to 13 | * @param dialog Dialog from which the message is 14 | * @param message Message to display 15 | */ 16 | void displayMessage(@NotNull Player player, @NotNull DialogRunner dialog, @NotNull Message message); 17 | 18 | /** 19 | * Stop displaying the messages from a dialog. 20 | * 21 | * @param player Player who received the messages 22 | * @param dialog Dialog from which the messages were 23 | */ 24 | void stopDisplayingMessages(@NotNull Player player, @NotNull DialogRunner dialog); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/types/Dialogable.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages.types; 2 | 3 | import fr.skytasul.quests.api.npcs.BqNpc; 4 | import fr.skytasul.quests.api.npcs.dialogs.Dialog; 5 | import fr.skytasul.quests.api.npcs.dialogs.DialogRunner; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | 9 | public interface Dialogable { 10 | 11 | @Nullable 12 | Dialog getDialog(); 13 | 14 | @Nullable 15 | DialogRunner getDialogRunner(); 16 | 17 | @Nullable 18 | BqNpc getNPC(); 19 | 20 | default boolean hasDialog() { 21 | return getNPC() != null && getDialog() != null && !getDialog().getMessages().isEmpty(); 22 | } 23 | 24 | default @NotNull String getNpcName() { 25 | if (getNPC() == null) 26 | return "§c§lunknown NPC"; 27 | if (getDialog() != null && getDialog().getNpcName() != null) 28 | return getDialog().getNpcName(); 29 | return getNPC().getNpc().getName(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/structure/EndingStageImplementation.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.structure; 2 | 3 | import fr.skytasul.quests.api.quests.branches.EndingStage; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | import java.util.Objects; 7 | 8 | public class EndingStageImplementation implements EndingStage { 9 | 10 | private final @NotNull StageControllerImplementation stage; 11 | private final @Nullable QuestBranchImplementation branch; 12 | 13 | public EndingStageImplementation(@NotNull StageControllerImplementation stage, 14 | @Nullable QuestBranchImplementation branch) { 15 | this.stage = Objects.requireNonNull(stage); 16 | this.branch = branch; 17 | } 18 | 19 | @Override 20 | public @NotNull StageControllerImplementation getStage() { 21 | return stage; 22 | } 23 | 24 | @Override 25 | public @Nullable QuestBranchImplementation getBranch() { 26 | return branch; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/worldguard/WorldGuardEntryEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations.worldguard; 2 | 3 | import com.sk89q.worldguard.protection.regions.ProtectedRegion; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.bukkit.event.player.PlayerEvent; 7 | import java.util.Set; 8 | 9 | public class WorldGuardEntryEvent extends PlayerEvent { 10 | 11 | private final Set entered; 12 | 13 | WorldGuardEntryEvent(Player who, Set entered) { 14 | super(who); 15 | this.entered = entered; 16 | } 17 | 18 | public Set getRegionsEntered() { 19 | return entered; 20 | } 21 | 22 | @Override 23 | public HandlerList getHandlers() { 24 | return handlers; 25 | } 26 | 27 | public static HandlerList getHandlerList() { 28 | return handlers; 29 | } 30 | 31 | private static final HandlerList handlers = new HandlerList(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/BQUltimateTimber.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations; 2 | 3 | import com.craftaro.ultimatetimber.events.TreeFellEvent; 4 | import com.craftaro.ultimatetimber.tree.ITreeBlock; 5 | import fr.skytasul.quests.api.events.internal.BQBlockBreakEvent; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.block.Block; 8 | import org.bukkit.event.EventHandler; 9 | import org.bukkit.event.EventPriority; 10 | import org.bukkit.event.Listener; 11 | import java.util.stream.Collectors; 12 | 13 | public class BQUltimateTimber implements Listener { 14 | 15 | @EventHandler (priority = EventPriority.MONITOR) 16 | public void onTreeFell(TreeFellEvent e) { 17 | Bukkit.getPluginManager().callEvent(new BQBlockBreakEvent(e.getPlayer(), 18 | e.getDetectedTree() 19 | .getDetectedTreeBlocks() 20 | .getLogBlocks() 21 | .stream() 22 | .map(ITreeBlock::getBlock) 23 | .collect(Collectors.toList()))); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/options/StageOptionCreator.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages.options; 2 | 3 | import java.util.function.Supplier; 4 | import org.jetbrains.annotations.NotNull; 5 | import fr.skytasul.quests.api.serializable.SerializableCreator; 6 | import fr.skytasul.quests.api.stages.AbstractStage; 7 | 8 | public class StageOptionCreator extends SerializableCreator> { 9 | 10 | public StageOptionCreator(@NotNull String id, @NotNull Class> clazz, 11 | @NotNull Supplier<@NotNull StageOption> newObjectSupplier) { 12 | super(id, clazz, newObjectSupplier); 13 | } 14 | 15 | public static > StageOptionCreator create(@NotNull String id, 16 | @NotNull Class optionClass, @NotNull Supplier<@NotNull O> supplier) { 17 | return new StageOptionCreator<>(id, optionClass, (@NotNull Supplier<@NotNull StageOption>) supplier); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/editors/InventoryClear.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.editors; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | public abstract class InventoryClear extends Editor{ 7 | 8 | private ItemStack[] contents = new ItemStack[0]; 9 | private int heldItemSlot; 10 | 11 | public InventoryClear(Player p, Runnable cancel) { 12 | super(p, cancel); 13 | } 14 | 15 | @Override 16 | public void begin(){ 17 | super.begin(); 18 | contents = player.getInventory().getContents(); 19 | heldItemSlot = player.getInventory().getHeldItemSlot(); 20 | player.getInventory().setContents(new ItemStack[0]); 21 | } 22 | 23 | @Override 24 | public void end(){ 25 | super.end(); 26 | player.getInventory().setContents(contents); 27 | player.getInventory().setHeldItemSlot(heldItemSlot); 28 | } 29 | 30 | @Override 31 | protected String cancelWord() { 32 | return "cancel"; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/creation/QuestCreationGuiClickEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.creation; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.inventory.ClickType; 5 | import org.bukkit.inventory.ItemStack; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | import fr.skytasul.quests.api.gui.GuiClickEvent; 9 | 10 | public class QuestCreationGuiClickEvent extends GuiClickEvent { 11 | 12 | public QuestCreationGuiClickEvent(@NotNull Player player, @NotNull QuestCreationGui gui, @Nullable ItemStack clicked, 13 | @Nullable ItemStack cursor, int slot, @NotNull ClickType click) { 14 | super(player, gui, clicked, cursor, slot, click); 15 | } 16 | 17 | @Override 18 | public void setCancelled(boolean cancelled) { 19 | throw new UnsupportedOperationException(); 20 | } 21 | 22 | @Override 23 | public @NotNull QuestCreationGui getGui() { 24 | return (@NotNull QuestCreationGui) super.getGui(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/QuestsHandler.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import fr.skytasul.quests.api.quests.Quest; 5 | import fr.skytasul.quests.api.stages.StageHandler; 6 | 7 | public interface QuestsHandler extends StageHandler { 8 | 9 | public default void load() {} 10 | 11 | public default void unload() {} 12 | 13 | public default void questCreate(Quest quest) {} 14 | 15 | public default void questRemove(Quest quest) {} 16 | 17 | public default void questLoaded(Quest quest) {} 18 | 19 | public default void questUnload(Quest quest) {} 20 | 21 | public default void questEdit(Quest newQuest, Quest oldQuest, boolean keepDatas) {} 22 | 23 | public default void questStart(Quester quester, Quest quest) {} 24 | 25 | public default void questFinish(Quester quester, Quest quest) {} 26 | 27 | public default void questReset(Quester quester, Quest quest) {} 28 | 29 | public default void questUpdated(Quester quester, Quest quest) {} 30 | 31 | } 32 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/placeholders/PapiMessageProcessor.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations.placeholders; 2 | 3 | import fr.skytasul.quests.api.utils.messaging.MessageProcessor; 4 | import fr.skytasul.quests.api.utils.messaging.PlaceholdersContext; 5 | import me.clip.placeholderapi.PlaceholderAPI; 6 | import net.kyori.adventure.identity.Identity; 7 | import org.bukkit.Bukkit; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | public class PapiMessageProcessor implements MessageProcessor { 11 | 12 | @Override 13 | public @NotNull String processString(@NotNull String string, @NotNull PlaceholdersContext context) { 14 | if (context.replacePluginPlaceholders() && context.getAudience() != null) { 15 | var playerOpt = context.getAudience().get(Identity.UUID).map(Bukkit::getOfflinePlayer); 16 | if (playerOpt.isPresent() && playerOpt.get().hasPlayedBefore()) 17 | return PlaceholderAPI.setPlaceholders(playerOpt.get(), string); 18 | } 19 | 20 | return string; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/npcs/BqNpc.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.npcs; 2 | 3 | import java.util.Set; 4 | import java.util.function.Predicate; 5 | import org.bukkit.entity.Player; 6 | import fr.skytasul.quests.api.pools.QuestPool; 7 | import fr.skytasul.quests.api.quests.Quest; 8 | import fr.skytasul.quests.api.stages.types.Locatable; 9 | import fr.skytasul.quests.api.utils.messaging.HasPlaceholders; 10 | 11 | public interface BqNpc extends Locatable.Located.LocatedEntity, HasPlaceholders { 12 | 13 | String getId(); 14 | 15 | BqInternalNpc getNpc(); 16 | 17 | Set getQuests(); 18 | 19 | boolean hasQuestStarted(Player p); 20 | 21 | Set getPools(); 22 | 23 | void hideForPlayer(Player p, Object holder); 24 | 25 | void removeHiddenForPlayer(Player p, Object holder); 26 | 27 | boolean canGiveSomething(Player p); 28 | 29 | void addStartablePredicate(Predicate predicate, Object holder); 30 | 31 | void removeStartablePredicate(Object holder); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/rewards/QuestStopReward.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.rewards; 2 | 3 | import fr.skytasul.quests.api.QuestsPlugin; 4 | import fr.skytasul.quests.api.objects.QuestObjectClickEvent; 5 | import fr.skytasul.quests.api.rewards.AbstractReward; 6 | import fr.skytasul.quests.api.rewards.RewardGiveContext; 7 | 8 | public class QuestStopReward extends AbstractReward { 9 | 10 | public QuestStopReward() {} 11 | 12 | public QuestStopReward(String customDescription) { 13 | super(customDescription); 14 | } 15 | 16 | @Override 17 | public void itemClick(QuestObjectClickEvent event) {} 18 | 19 | @Override 20 | public void give(RewardGiveContext context) { 21 | if (getAttachedQuest() == null) { 22 | QuestsPlugin.getPlugin().getLoggerExpanded().debug("No attached quest for " + debugName()); 23 | } else { 24 | getAttachedQuest().cancelQuester(context.getQuester()); 25 | context.interruptBranch(); 26 | } 27 | } 28 | 29 | @Override 30 | public AbstractReward clone() { 31 | return new QuestStopReward(getCustomDescription()); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/questers/events/QuesterJoinEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.questers.events; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | public class QuesterJoinEvent extends AbstractQuesterEvent { 9 | 10 | private final Player player; 11 | private final boolean firstJoin; 12 | 13 | public QuesterJoinEvent(@NotNull Quester quester, @NotNull Player player, boolean firstJoin) { 14 | super(quester); 15 | this.player = player; 16 | this.firstJoin = firstJoin; 17 | } 18 | 19 | public @NotNull Player getPlayer() { 20 | return player; 21 | } 22 | 23 | public boolean isFirstJoin() { 24 | return firstJoin; 25 | } 26 | 27 | @Override 28 | public HandlerList getHandlers() { 29 | return handlers; 30 | } 31 | 32 | public static HandlerList getHandlerList() { 33 | return handlers; 34 | } 35 | 36 | private static final HandlerList handlers = new HandlerList(); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/editors/parsers/EnumParser.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.editors.parsers; 2 | 3 | import java.util.Arrays; 4 | import java.util.function.Predicate; 5 | import java.util.regex.Pattern; 6 | import java.util.stream.Collectors; 7 | 8 | public class EnumParser> extends CollectionParser { 9 | 10 | private static final Pattern FORMAT = Pattern.compile("[ _]"); 11 | 12 | public EnumParser(Class enumClass) { 13 | super(Arrays.asList(enumClass.getEnumConstants()), constant -> processConstantName(constant.name())); 14 | } 15 | 16 | public EnumParser(Class enumClass, Predicate filter) { 17 | super(Arrays.stream(enumClass.getEnumConstants()).filter(filter).collect(Collectors.toList()), constant -> processConstantName(constant.name())); 18 | } 19 | 20 | @Override 21 | protected String processName(String msg) { 22 | return processConstantName(msg); 23 | } 24 | 25 | static String processConstantName(String key) { 26 | return FORMAT.matcher(key.toLowerCase()).replaceAll(""); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/events/internal/BQBlockBreakEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.events.internal; 2 | 3 | import java.util.List; 4 | import org.apache.commons.lang.Validate; 5 | import org.bukkit.block.Block; 6 | import org.bukkit.entity.Player; 7 | import org.bukkit.event.HandlerList; 8 | import org.bukkit.event.player.PlayerEvent; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class BQBlockBreakEvent extends PlayerEvent { 12 | 13 | private final @NotNull List<@NotNull Block> blocks; 14 | 15 | public BQBlockBreakEvent(@NotNull Player player, @NotNull List<@NotNull Block> blocks) { 16 | super(player); 17 | Validate.notNull(player); 18 | Validate.notNull(blocks); 19 | this.blocks = blocks; 20 | } 21 | 22 | public @NotNull List<@NotNull Block> getBlocks() { 23 | return blocks; 24 | } 25 | 26 | @Override 27 | public HandlerList getHandlers() { 28 | return handlers; 29 | } 30 | 31 | public static HandlerList getHandlerList() { 32 | return handlers; 33 | } 34 | 35 | private static final HandlerList handlers = new HandlerList(); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/requirements/RequirementCreator.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.requirements; 2 | 3 | import java.util.function.Supplier; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.jetbrains.annotations.NotNull; 6 | import fr.skytasul.quests.api.objects.QuestObjectCreator; 7 | import fr.skytasul.quests.api.objects.QuestObjectLocation; 8 | 9 | public class RequirementCreator extends QuestObjectCreator { 10 | 11 | public RequirementCreator(@NotNull String id, @NotNull Class clazz, @NotNull ItemStack is, 12 | @NotNull Supplier<@NotNull AbstractRequirement> newObjectSupplier) { 13 | super(id, clazz, is, newObjectSupplier); 14 | } 15 | 16 | public RequirementCreator(@NotNull String id, @NotNull Class clazz, @NotNull ItemStack is, 17 | @NotNull Supplier<@NotNull AbstractRequirement> newObjectSupplier, boolean multiple, 18 | @NotNull QuestObjectLocation @NotNull... allowedLocations) { 19 | super(id, clazz, is, newObjectSupplier, multiple, allowedLocations); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/branches/QuestBranchesManager.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.branches; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import fr.skytasul.quests.api.quests.Quest; 5 | import fr.skytasul.quests.api.stages.StageController; 6 | import fr.skytasul.quests.api.stages.StageIndex; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | import org.jetbrains.annotations.UnmodifiableView; 10 | import java.util.Collection; 11 | 12 | public interface QuestBranchesManager { 13 | 14 | @NotNull 15 | Quest getQuest(); 16 | 17 | public int getId(@NotNull QuestBranch branch); 18 | 19 | public @UnmodifiableView @NotNull Collection<@NotNull QuestBranch> getBranches(); 20 | 21 | public @Nullable QuestBranch getBranch(int id); 22 | 23 | public @Nullable QuestBranch getPlayerBranch(@NotNull Quester acc); 24 | 25 | public boolean hasBranchStarted(@NotNull Quester acc, @NotNull QuestBranch branch); 26 | 27 | public @NotNull StageController getStageFromIndex(@NotNull StageIndex index) throws IllegalArgumentException; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionHologramLaunch.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.QuestsAPI; 5 | import fr.skytasul.quests.api.localization.Lang; 6 | import fr.skytasul.quests.api.options.OptionSet; 7 | import fr.skytasul.quests.api.options.QuestOptionItem; 8 | 9 | public class OptionHologramLaunch extends QuestOptionItem { 10 | 11 | public OptionHologramLaunch() { 12 | super(OptionStarterNPC.class); 13 | } 14 | 15 | @Override 16 | public XMaterial getDefaultMaterial() { 17 | return XMaterial.RED_STAINED_GLASS_PANE; 18 | } 19 | 20 | @Override 21 | public String getItemName() { 22 | return Lang.hologramLaunch.toString(); 23 | } 24 | 25 | @Override 26 | public String getItemDescription() { 27 | return Lang.hologramLaunchLore.toString(); 28 | } 29 | 30 | @Override 31 | public boolean shouldDisplay(OptionSet options) { 32 | return QuestsAPI.getAPI().hasHologramsManager() && options.getOption(OptionStarterNPC.class).getValue() != null; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /v1_18_R2/src/main/java/fr/skytasul/quests/utils/nms/v1_18_R2.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.nms; 2 | 3 | import net.kyori.adventure.key.Key; 4 | import java.util.List; 5 | import org.bukkit.Material; 6 | import net.minecraft.core.Registry; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.level.block.Block; 9 | import net.minecraft.world.level.block.state.BlockState; 10 | import net.minecraft.world.level.block.state.StateDefinition; 11 | import net.minecraft.world.level.block.state.properties.Property; 12 | 13 | public class v1_18_R2 extends NMS{ 14 | 15 | @Override 16 | public List getAvailableBlockProperties(Material material) { 17 | Block block = Registry.BLOCK.get(new ResourceLocation(material.getKey().getKey())); 18 | StateDefinition stateList = block.getStateDefinition(); 19 | return stateList.getProperties().stream().map(Property::getName).toList(); 20 | } 21 | 22 | @Override 23 | public List getAvailableBlockTags() { 24 | return Registry.BLOCK.getTags().map(x -> Key.key(x.getFirst().location().toString())).toList(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /v1_19_R1/src/main/java/fr/skytasul/quests/utils/nms/v1_19_R1.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.nms; 2 | 3 | import net.kyori.adventure.key.Key; 4 | import java.util.List; 5 | import org.bukkit.Material; 6 | import net.minecraft.core.Registry; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.world.level.block.Block; 9 | import net.minecraft.world.level.block.state.BlockState; 10 | import net.minecraft.world.level.block.state.StateDefinition; 11 | import net.minecraft.world.level.block.state.properties.Property; 12 | 13 | public class v1_19_R1 extends NMS{ 14 | 15 | @Override 16 | public List getAvailableBlockProperties(Material material) { 17 | Block block = Registry.BLOCK.get(new ResourceLocation(material.getKey().getKey())); 18 | StateDefinition stateList = block.getStateDefinition(); 19 | return stateList.getProperties().stream().map(Property::getName).toList(); 20 | } 21 | 22 | @Override 23 | public List getAvailableBlockTags() { 24 | return Registry.BLOCK.getTags().map(x -> Key.key(x.getFirst().location().toString())).toList(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionHologramLaunchNo.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.QuestsAPI; 5 | import fr.skytasul.quests.api.localization.Lang; 6 | import fr.skytasul.quests.api.options.OptionSet; 7 | import fr.skytasul.quests.api.options.QuestOptionItem; 8 | 9 | public class OptionHologramLaunchNo extends QuestOptionItem { 10 | 11 | public OptionHologramLaunchNo() { 12 | super(OptionStarterNPC.class); 13 | } 14 | 15 | @Override 16 | public XMaterial getDefaultMaterial() { 17 | return XMaterial.RED_STAINED_GLASS_PANE; 18 | } 19 | 20 | @Override 21 | public String getItemName() { 22 | return Lang.hologramLaunchNo.toString(); 23 | } 24 | 25 | @Override 26 | public String getItemDescription() { 27 | return Lang.hologramLaunchNoLore.toString(); 28 | } 29 | 30 | @Override 31 | public boolean shouldDisplay(OptionSet options) { 32 | return QuestsAPI.getAPI().hasHologramsManager() && options.getOption(OptionStarterNPC.class).getValue() != null; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 SkytAsul 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/blocks/BQBlocksManager.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.blocks; 2 | 3 | import java.util.Collection; 4 | import java.util.Spliterator; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | import com.cryptomorin.xseries.XMaterial; 8 | import fr.skytasul.quests.api.stages.types.Locatable; 9 | 10 | public interface BQBlocksManager { 11 | 12 | public static final String HEADER_SEPARATOR = ":"; 13 | public static final String CUSTOM_NAME_FOOTER = "|customname:"; 14 | 15 | public @NotNull BQBlock deserialize(@NotNull String string) throws IllegalArgumentException; 16 | 17 | public void registerBlockType(@NotNull String header, @NotNull BQBlockType type); 18 | 19 | public @Nullable String getHeader(@NotNull BQBlockType type); 20 | 21 | public @NotNull Spliterator getNearbyBlocks( 22 | @NotNull Locatable.MultipleLocatable.NearbyFetcher fetcher, 23 | @NotNull Collection types); 24 | 25 | public @NotNull BQBlock createSimple(@NotNull XMaterial material, @Nullable String customName); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionConfirmMessage.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.QuestsConfiguration; 5 | import fr.skytasul.quests.api.localization.Lang; 6 | import fr.skytasul.quests.api.options.OptionSet; 7 | import fr.skytasul.quests.api.options.QuestOptionString; 8 | import org.bukkit.entity.Player; 9 | 10 | public class OptionConfirmMessage extends QuestOptionString { 11 | 12 | @Override 13 | public void sendIndication(Player p) { 14 | Lang.CONFIRM_MESSAGE.send(p); 15 | } 16 | 17 | @Override 18 | public XMaterial getItemMaterial() { 19 | return XMaterial.FEATHER; 20 | } 21 | 22 | @Override 23 | public String getItemName() { 24 | return Lang.customConfirmMessage.toString(); 25 | } 26 | 27 | @Override 28 | public String getItemDescription() { 29 | return Lang.customConfirmMessageLore.toString(); 30 | } 31 | 32 | @Override 33 | public boolean shouldDisplay(OptionSet options) { 34 | return QuestsConfiguration.getConfig().getQuestsConfig().questConfirmGUI(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionFailOnDeath.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import fr.skytasul.quests.api.options.QuestOptionBoolean; 5 | import fr.skytasul.quests.api.players.PlayerManager; 6 | import fr.skytasul.quests.api.questers.Quester; 7 | import org.bukkit.event.EventHandler; 8 | import org.bukkit.event.Listener; 9 | import org.bukkit.event.entity.PlayerDeathEvent; 10 | 11 | public class OptionFailOnDeath extends QuestOptionBoolean implements Listener { 12 | 13 | @Override 14 | public String getName() { 15 | return Lang.failOnDeath.toString(); 16 | } 17 | 18 | @Override 19 | public String getDescription() { 20 | return Lang.failOnDeathLore.toString(); 21 | } 22 | 23 | @EventHandler 24 | public void onDeath(PlayerDeathEvent e) { 25 | Quester acc = PlayerManager.getPlayerAccount(e.getEntity()); 26 | if (acc == null) return; 27 | if (getAttachedQuest().hasStarted(acc)) { 28 | getAttachedQuest().cancelQuester(acc); 29 | Lang.QUEST_FAILED.send(e.getEntity(), getAttachedQuest()); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/mobs/EpicBosses.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations.mobs; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.event.Listener; 5 | 6 | public class EpicBosses implements Listener { 7 | 8 | public static boolean bossExists(String name){ 9 | throw new RuntimeException("EpicBosses compatibility temporarily disabled"); 10 | //return CustomBosses.get().getBossEntityContainer().exists(name); 11 | } 12 | 13 | public static EntityType getBossEntityType(String name){ 14 | throw new RuntimeException("EpicBosses compatibility temporarily disabled"); 15 | //return EntityFinder.get(CustomBosses.get().getBossEntityContainer().getData().get(name).getEntityStats().get(0).getMainStats().getEntityType().split(":")[0]).getEntityType(); 16 | } 17 | 18 | /*@EventHandler 19 | public void onBossDeath(BossDeathEvent e){ 20 | LivingEntity en = e.getActiveBossHolder().getLivingEntity(); 21 | if (en.getKiller() == null) return; 22 | Bukkit.getPluginManager().callEvent(new CompatMobDeathEvent(e.getActiveBossHolder().getName(), en.getKiller(), en)); 23 | }*/ 24 | 25 | } -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/options/QuestOptionRewards.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.options; 2 | 3 | import java.util.Collection; 4 | import java.util.Map; 5 | import fr.skytasul.quests.api.QuestsAPI; 6 | import fr.skytasul.quests.api.objects.QuestObjectsRegistry; 7 | import fr.skytasul.quests.api.rewards.AbstractReward; 8 | import fr.skytasul.quests.api.rewards.RewardCreator; 9 | import fr.skytasul.quests.api.rewards.RewardList; 10 | 11 | public abstract class QuestOptionRewards extends QuestOptionObject { 12 | 13 | @Override 14 | protected AbstractReward deserialize(Map map) { 15 | return AbstractReward.deserialize(map); 16 | } 17 | 18 | @Override 19 | protected String getSizeString() { 20 | return getValue().getSizeString(); 21 | } 22 | 23 | @Override 24 | protected QuestObjectsRegistry getObjectsRegistry() { 25 | return QuestsAPI.getAPI().getRewards(); 26 | } 27 | 28 | @Override 29 | protected RewardList instanciate(Collection objects) { 30 | return new RewardList(objects); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /v1_17_R1/src/main/java/fr/skytasul/quests/utils/nms/v1_17_R1.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.nms; 2 | 3 | import net.kyori.adventure.key.Key; 4 | import java.util.List; 5 | import org.bukkit.Material; 6 | import net.minecraft.core.Registry; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.tags.BlockTags; 9 | import net.minecraft.world.level.block.Block; 10 | import net.minecraft.world.level.block.state.BlockState; 11 | import net.minecraft.world.level.block.state.StateDefinition; 12 | import net.minecraft.world.level.block.state.properties.Property; 13 | 14 | public class v1_17_R1 extends NMS{ 15 | 16 | @Override 17 | public List getAvailableBlockProperties(Material material) { 18 | Block block = Registry.BLOCK.get(new ResourceLocation(material.getKey().getKey())); 19 | StateDefinition stateList = block.getStateDefinition(); 20 | return stateList.getProperties().stream().map(Property::getName).toList(); 21 | } 22 | 23 | @Override 24 | public List getAvailableBlockTags() { 25 | return BlockTags.getAllTags().getAllTags().keySet().stream().map(location -> Key.key(location.toString())).toList(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /v1_18_R1/src/main/java/fr/skytasul/quests/utils/nms/v1_18_R1.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.nms; 2 | 3 | import net.kyori.adventure.key.Key; 4 | import java.util.List; 5 | import org.bukkit.Material; 6 | import net.minecraft.core.Registry; 7 | import net.minecraft.resources.ResourceLocation; 8 | import net.minecraft.tags.BlockTags; 9 | import net.minecraft.world.level.block.Block; 10 | import net.minecraft.world.level.block.state.BlockState; 11 | import net.minecraft.world.level.block.state.StateDefinition; 12 | import net.minecraft.world.level.block.state.properties.Property; 13 | 14 | public class v1_18_R1 extends NMS{ 15 | 16 | @Override 17 | public List getAvailableBlockProperties(Material material) { 18 | Block block = Registry.BLOCK.get(new ResourceLocation(material.getKey().getKey())); 19 | StateDefinition stateList = block.getStateDefinition(); 20 | return stateList.getProperties().stream().map(Property::getName).toList(); 21 | } 22 | 23 | @Override 24 | public List getAvailableBlockTags() { 25 | return BlockTags.getAllTags().getAllTags().keySet().stream().map(location -> Key.key(location.toString())).toList(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/options/QuestOptionCreator.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.options; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | import java.util.Arrays; 6 | import java.util.function.Supplier; 7 | 8 | public class QuestOptionCreator> { 9 | 10 | public final String id; 11 | public final int preferedSlot; 12 | public final Class optionClass; 13 | public final Supplier optionSupplier; 14 | public final String[] oldNames; 15 | public final D defaultValue; 16 | 17 | public QuestOptionCreator(@NotNull String id, int preferedSlot, @NotNull Class optionClass, 18 | @NotNull Supplier<@NotNull T> optionSupplier, @Nullable D defaultValue, @NotNull String @NotNull... oldNames) { 19 | this.id = id; 20 | this.preferedSlot = preferedSlot; 21 | this.optionClass = optionClass; 22 | this.optionSupplier = optionSupplier; 23 | this.oldNames = oldNames; 24 | this.defaultValue = defaultValue; 25 | } 26 | 27 | public boolean applies(@NotNull String key) { 28 | return id.equals(key) || Arrays.stream(oldNames).anyMatch(key::equals); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/messaging/DefaultErrors.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils.messaging; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import net.kyori.adventure.audience.Audience; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | public class DefaultErrors { 9 | 10 | private DefaultErrors() {} 11 | 12 | public static void sendInvalidNumber(@NotNull Audience audience, @Nullable String input) { 13 | Lang.NUMBER_INVALID.send(audience, PlaceholderRegistry.of("input", input)); 14 | } 15 | 16 | public static void sendOutOfBounds(@NotNull Audience audience, Number index, Number min, Number max) { 17 | Lang.OUT_OF_BOUNDS.send(audience, PlaceholderRegistry.of("index", index, "min", min, "max", max)); 18 | } 19 | 20 | public static void sendOutOfBounds(@NotNull Audience audience, Number min, Number max) { 21 | Lang.NUMBER_NOT_IN_BOUNDS.send(audience, PlaceholderRegistry.of("min", min, "max", max)); 22 | } 23 | 24 | public static void sendGeneric(@NotNull Audience audience, @Nullable String error) { 25 | Lang.ERROR_OCCURED.send(audience, PlaceholderRegistry.of("error", error)); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/events/questers/QuesterQuestPreLaunchEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.events.questers; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import fr.skytasul.quests.api.quests.Quest; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.HandlerList; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | /** 10 | * Called before a player starts a quest 11 | */ 12 | public class QuesterQuestPreLaunchEvent extends AbstractQuesterQuestEvent implements Cancellable{ 13 | 14 | private boolean cancel = false; 15 | 16 | public QuesterQuestPreLaunchEvent(@NotNull Quester quester, @NotNull Quest quest) { 17 | super(quester, quest); 18 | } 19 | 20 | @Override 21 | public boolean isCancelled(){ 22 | return cancel; 23 | } 24 | 25 | @Override 26 | public void setCancelled(boolean paramBoolean){ 27 | this.cancel = paramBoolean; 28 | } 29 | 30 | @Override 31 | public HandlerList getHandlers() { 32 | return handlers; 33 | } 34 | 35 | public static HandlerList getHandlerList() { 36 | return handlers; 37 | } 38 | 39 | private static final HandlerList handlers = new HandlerList(); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/questers/QuesterManager.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.questers; 2 | 3 | import fr.skytasul.quests.api.data.SavableData; 4 | import fr.skytasul.quests.api.questers.data.QuesterDataManager; 5 | import net.kyori.adventure.key.Key; 6 | import org.bukkit.entity.Player; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.UnmodifiableView; 9 | import java.util.Collection; 10 | 11 | public interface QuesterManager { 12 | 13 | void registerQuesterProvider(@NotNull QuesterProvider provider); 14 | 15 | @NotNull 16 | @UnmodifiableView 17 | Collection getQuesterProviders(); 18 | 19 | @NotNull 20 | QuesterProvider getQuesterProvider(@NotNull Key key) throws IllegalArgumentException; 21 | 22 | void addSavableData(@NotNull SavableData data); 23 | 24 | @NotNull 25 | Collection<@NotNull SavableData> getSavableData(); 26 | 27 | @NotNull 28 | @UnmodifiableView 29 | Collection getPlayerQuesters(@NotNull Player player); 30 | 31 | @NotNull 32 | @UnmodifiableView 33 | Collection getLoadedQuesters(); 34 | 35 | void saveAll(); 36 | 37 | @NotNull 38 | QuesterDataManager getDataManager(); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/rewards/RewardCreator.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.rewards; 2 | 3 | import java.util.function.Supplier; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.jetbrains.annotations.NotNull; 6 | import fr.skytasul.quests.api.objects.QuestObjectCreator; 7 | import fr.skytasul.quests.api.objects.QuestObjectLocation; 8 | 9 | public class RewardCreator extends QuestObjectCreator { 10 | 11 | private boolean async = false; 12 | 13 | public RewardCreator(@NotNull String id, @NotNull Class clazz, @NotNull ItemStack is, 14 | @NotNull Supplier newObjectSupplier) { 15 | super(id, clazz, is, newObjectSupplier); 16 | } 17 | 18 | public RewardCreator(@NotNull String id, @NotNull Class clazz, @NotNull ItemStack is, 19 | @NotNull Supplier newObjectSupplier, boolean multiple, 20 | @NotNull QuestObjectLocation @NotNull... allowedLocations) { 21 | super(id, clazz, is, newObjectSupplier, multiple, allowedLocations); 22 | } 23 | 24 | public boolean canBeAsync() { 25 | return async; 26 | } 27 | 28 | public @NotNull RewardCreator setCanBeAsync(boolean async) { 29 | this.async = async; 30 | return this; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/layout/LayoutedClickEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui.layout; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.inventory.ClickType; 5 | import org.bukkit.inventory.ItemStack; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | import fr.skytasul.quests.api.gui.GuiClickEvent; 9 | 10 | public class LayoutedClickEvent extends GuiClickEvent { 11 | 12 | private @NotNull LayoutedGUI gui; 13 | 14 | public LayoutedClickEvent(@NotNull Player player, @NotNull LayoutedGUI gui, @Nullable ItemStack clicked, 15 | @Nullable ItemStack cursor, int slot, @NotNull ClickType click) { 16 | super(player, gui, clicked, cursor, slot, click); 17 | this.gui = gui; 18 | } 19 | 20 | @Override 21 | public void setCancelled(boolean cancelled) { 22 | throw new UnsupportedOperationException(); 23 | } 24 | 25 | @Override 26 | public @NotNull LayoutedGUI getGui() { 27 | return gui; 28 | } 29 | 30 | public void refreshItem() { 31 | gui.refresh(getSlot()); 32 | } 33 | 34 | public void refreshItemReopen() { 35 | gui.refresh(getSlot()); 36 | gui.reopen(getPlayer()); 37 | } 38 | 39 | public void refreshGuiReopen() { 40 | gui.reopen(getPlayer(), true); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/serializable/SerializableCreator.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.serializable; 2 | 3 | import java.util.function.Supplier; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class SerializableCreator { 7 | 8 | private final @NotNull String id; 9 | private final @NotNull Class clazz; 10 | private final @NotNull Supplier<@NotNull T> newObjectSupplier; 11 | 12 | /** 13 | * Creates a new creator for the serializable object of type <T> 14 | * 15 | * @param id unique string id for the serializable object type 16 | * @param clazz class of the serializable object type 17 | * @param newObjectSupplier function used to instanciate a serializable object 18 | */ 19 | public SerializableCreator(@NotNull String id, @NotNull Class clazz, 20 | Supplier<@NotNull T> newObjectSupplier) { 21 | this.id = id; 22 | this.clazz = clazz; 23 | this.newObjectSupplier = newObjectSupplier; 24 | } 25 | 26 | public @NotNull String getID() { 27 | return id; 28 | } 29 | 30 | public @NotNull Class getSerializableClass() { 31 | return clazz; 32 | } 33 | 34 | public @NotNull T newObject() { 35 | return newObjectSupplier.get(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/creation/StageGuiClickEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages.creation; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.inventory.ClickType; 5 | import org.bukkit.inventory.ItemStack; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | public class StageGuiClickEvent { 9 | 10 | private final @NotNull Player player; 11 | private final @NotNull ItemStack clicked; 12 | private final @NotNull ClickType click; 13 | private final @NotNull StageCreationContext context; 14 | 15 | public StageGuiClickEvent(@NotNull Player player, @NotNull ItemStack clicked, @NotNull ClickType click, 16 | @NotNull StageCreationContext context) { 17 | this.player = player; 18 | this.clicked = clicked; 19 | this.click = click; 20 | this.context = context; 21 | } 22 | 23 | public @NotNull Player getPlayer() { 24 | return player; 25 | } 26 | 27 | public @NotNull ItemStack getClicked() { 28 | return clicked; 29 | } 30 | 31 | public @NotNull ClickType getClick() { 32 | return click; 33 | } 34 | 35 | public void reopen() { 36 | context.reopenGui(); 37 | } 38 | 39 | public void remove() { 40 | context.remove(); 41 | } 42 | 43 | public void removeAndReopen() { 44 | context.removeAndReopenGui(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/QuestsManager.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | import org.jetbrains.annotations.UnmodifiableView; 7 | import java.io.File; 8 | import java.util.List; 9 | 10 | public interface QuestsManager { 11 | 12 | @NotNull 13 | File getSaveFolder(); 14 | 15 | @NotNull 16 | @UnmodifiableView 17 | List<@NotNull ? extends Quest> getQuests(); 18 | 19 | @Nullable 20 | Quest getQuest(int id); 21 | 22 | void addQuest(@NotNull Quest quest); 23 | 24 | @NotNull 25 | List<@NotNull ? extends Quest> getQuestsStarted(Quester acc); 26 | 27 | @NotNull 28 | List<@NotNull ? extends Quest> getQuestsStarted(@NotNull Quester acc, boolean hide, 29 | boolean withoutScoreboard); 30 | 31 | @NotNull 32 | List<@NotNull ? extends Quest> getQuestsFinished(@NotNull Quester acc, boolean hide); 33 | 34 | @NotNull 35 | List<@NotNull ? extends Quest> getQuestsNotStarted(@NotNull Quester acc, boolean hide, 36 | boolean clickableAndRedoable); 37 | 38 | void updateQuestsStarted(@NotNull Quester acc, boolean withoutScoreboard, @NotNull List<@NotNull Quest> list); 39 | 40 | int getStartedSize(@NotNull Quester acc); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/BQMMOItems.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations; 2 | 3 | import fr.skytasul.quests.api.QuestsAPI; 4 | import fr.skytasul.quests.api.comparison.ItemComparison; 5 | import fr.skytasul.quests.api.localization.Lang; 6 | import net.Indyuce.mmoitems.MMOItems; 7 | import net.Indyuce.mmoitems.api.Type; 8 | import org.bukkit.inventory.ItemStack; 9 | 10 | public final class BQMMOItems { 11 | 12 | private BQMMOItems() {} 13 | 14 | private static final ItemComparison COMPARISON = new ItemComparison( 15 | "mmoItems", 16 | Lang.comparisonMmoItems.toString(), 17 | Lang.comparisonMmoItemsLore.toString(), 18 | BQMMOItems::compareMmoItems); 19 | 20 | public static void initialize() { 21 | QuestsAPI.getAPI().registerItemComparison(COMPARISON); 22 | } 23 | 24 | public static void unload() { 25 | QuestsAPI.getAPI().unregisterItemComparison(COMPARISON); 26 | } 27 | 28 | private static boolean compareMmoItems(ItemStack item1, ItemStack item2) { 29 | Type type1 = MMOItems.getType(item1); 30 | Type type2 = MMOItems.getType(item2); 31 | if (type1 == null || !type1.equals(type2)) { 32 | return false; 33 | } 34 | 35 | String id1 = MMOItems.getID(item1); 36 | String id2 = MMOItems.getID(item2); 37 | return id1 != null && id1.equals(id2); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/events/questers/QuesterSetStageEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.events.questers; 2 | 3 | import org.bukkit.event.HandlerList; 4 | import org.jetbrains.annotations.NotNull; 5 | import fr.skytasul.quests.api.questers.Quester; 6 | import fr.skytasul.quests.api.quests.Quest; 7 | import fr.skytasul.quests.api.quests.branches.QuestBranchesManager; 8 | import fr.skytasul.quests.api.stages.StageController; 9 | 10 | /** 11 | * Called when a player finish a stage 12 | */ 13 | public class QuesterSetStageEvent extends AbstractQuesterQuestEvent { 14 | 15 | private final @NotNull StageController stage; 16 | 17 | public QuesterSetStageEvent(@NotNull Quester account, @NotNull Quest quest, @NotNull StageController stage) { 18 | super(account, quest); 19 | this.stage = stage; 20 | } 21 | 22 | public @NotNull StageController getStage() { 23 | return stage; 24 | } 25 | 26 | public QuestBranchesManager getStageManager() { 27 | return quest.getBranchesManager(); 28 | } 29 | 30 | @Override 31 | public HandlerList getHandlers() { 32 | return handlers; 33 | } 34 | 35 | public static HandlerList getHandlerList() { 36 | return handlers; 37 | } 38 | 39 | private static final HandlerList handlers = new HandlerList(); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/npcs/dialogs/events/DialogSendEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.npcs.dialogs.events; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.Cancellable; 5 | import org.bukkit.event.HandlerList; 6 | import org.bukkit.event.player.PlayerEvent; 7 | import org.jetbrains.annotations.NotNull; 8 | import fr.skytasul.quests.api.npcs.dialogs.DialogRunner; 9 | 10 | public class DialogSendEvent extends PlayerEvent implements Cancellable { 11 | 12 | private boolean cancelled = false; 13 | 14 | private final @NotNull DialogRunner dialog; 15 | 16 | public DialogSendEvent(@NotNull Player who, @NotNull DialogRunner dialog) { 17 | super(who); 18 | this.dialog = dialog; 19 | } 20 | 21 | @Override 22 | public boolean isCancelled() { 23 | return cancelled; 24 | } 25 | 26 | @Override 27 | public void setCancelled(boolean cancelled) { 28 | this.cancelled = cancelled; 29 | } 30 | 31 | public @NotNull DialogRunner getDialog() { 32 | return dialog; 33 | } 34 | 35 | @Override 36 | public HandlerList getHandlers() { 37 | return handlers; 38 | } 39 | 40 | public static HandlerList getHandlerList() { 41 | return handlers; 42 | } 43 | 44 | private static final HandlerList handlers = new HandlerList(); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/scoreboards/ScoreboardLine.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.scoreboards; 2 | 3 | import fr.skytasul.quests.api.utils.ChatColorUtils; 4 | import net.md_5.bungee.api.ChatColor; 5 | import org.apache.commons.lang.Validate; 6 | import java.util.Map; 7 | 8 | public class ScoreboardLine { 9 | 10 | private String value; 11 | private int refresh = 0; 12 | private int length = 0; 13 | 14 | public ScoreboardLine(String value) { 15 | Validate.notNull(value); 16 | this.value = ChatColor.translateAlternateColorCodes('&', 17 | ChatColorUtils.translateHexColorCodes(value 18 | .replace("{questName}", "{quest_name}") 19 | .replace("{questDescription}", "{quest_advancement}"))); 20 | } 21 | 22 | public String getValue() { 23 | return value; 24 | } 25 | 26 | public int getRefreshTime() { 27 | return refresh; 28 | } 29 | 30 | public int getMaxLength() { 31 | return length; 32 | } 33 | 34 | public static ScoreboardLine deserialize(Map map) { 35 | ScoreboardLine line = new ScoreboardLine((String) map.get("value")); 36 | 37 | if (map.containsKey("refresh")) 38 | line.refresh = (int) map.get("refresh"); 39 | if (map.containsKey("length")) 40 | line.length = (int) map.get("length"); 41 | 42 | return line; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/commands/parameters/BqNpcParameter.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.commands.parameters; 2 | 3 | import fr.skytasul.quests.BeautyQuests; 4 | import fr.skytasul.quests.api.QuestsPlugin; 5 | import fr.skytasul.quests.api.localization.Lang; 6 | import fr.skytasul.quests.api.npcs.BqNpc; 7 | import org.jetbrains.annotations.NotNull; 8 | import revxrsal.commands.autocomplete.SuggestionProvider; 9 | import revxrsal.commands.command.CommandActor; 10 | import revxrsal.commands.exception.CommandErrorException; 11 | import revxrsal.commands.node.ExecutionContext; 12 | import revxrsal.commands.parameter.ParameterType; 13 | import revxrsal.commands.stream.MutableStringStream; 14 | 15 | public class BqNpcParameter implements ParameterType { 16 | 17 | @Override 18 | public BqNpc parse(@NotNull MutableStringStream input, @NotNull ExecutionContext<@NotNull CommandActor> context) { 19 | String id = input.readString(); 20 | BqNpc npc = QuestsPlugin.getPlugin().getNpcManager().getById(id); 21 | if (npc == null) 22 | throw new CommandErrorException(Lang.NPC_DOESNT_EXIST.quickFormat("npc_id", id)); 23 | return npc; 24 | } 25 | 26 | @Override 27 | public @NotNull SuggestionProvider<@NotNull CommandActor> defaultSuggestions() { 28 | return __ -> BeautyQuests.getInstance().getNpcManager().getAvailableIds(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/npcs/dialogs/ChatMessageSender.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.npcs.dialogs; 2 | 3 | import fr.skytasul.quests.api.npcs.dialogs.DialogRunner; 4 | import fr.skytasul.quests.api.npcs.dialogs.Message; 5 | import fr.skytasul.quests.api.npcs.dialogs.MessageSender; 6 | import fr.skytasul.quests.api.utils.messaging.MessageType; 7 | import fr.skytasul.quests.api.utils.messaging.MessageUtils; 8 | import fr.skytasul.quests.api.utils.messaging.PlaceholdersContext; 9 | import org.bukkit.entity.Player; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | /** 13 | * A simple message sender that displays the message in chat. 14 | */ 15 | public class ChatMessageSender implements MessageSender { 16 | 17 | @Override 18 | public void displayMessage(@NotNull Player player, @NotNull DialogRunner dialog, @NotNull Message message) { 19 | String sent = message.formatMessage(player, dialog.getNpc(), dialog.getDialog().getNPCName(dialog.getNpc()), 20 | dialog.getDialog().getMessages().indexOf(message), dialog.getDialog().getMessages().size()); 21 | 22 | MessageUtils.sendRawMessage(player, sent, null, 23 | PlaceholdersContext.of(player, false, MessageType.DefaultMessageType.UNPREFIXED)); 24 | } 25 | 26 | @Override 27 | public void stopDisplayingMessages(@NotNull Player player, @NotNull DialogRunner dialog) { 28 | // intentionnally do nothing 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/editor/parsers/MaterialParser.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.editor.parsers; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.editors.parsers.AbstractParser; 5 | import fr.skytasul.quests.api.localization.Lang; 6 | import org.bukkit.Material; 7 | import org.bukkit.entity.Player; 8 | 9 | public class MaterialParser implements AbstractParser { 10 | 11 | private boolean item, block; 12 | 13 | public MaterialParser(boolean item, boolean block) { 14 | this.item = item; 15 | this.block = block; 16 | } 17 | 18 | @Override 19 | public XMaterial parse(Player p, String msg) throws Throwable { 20 | XMaterial tmp = XMaterial.matchXMaterial(msg).orElse(null); 21 | if (tmp == null){ 22 | Material mat = Material.matchMaterial(msg); 23 | if (mat != null) tmp = XMaterial.matchXMaterial(mat); 24 | if (tmp == null) { 25 | if (block) { 26 | Lang.UNKNOWN_BLOCK_TYPE.send(p); 27 | }else Lang.UNKNOWN_ITEM_TYPE.send(p); 28 | return null; 29 | } 30 | } 31 | if (item) { 32 | if (!tmp.get().isItem()) { 33 | Lang.INVALID_ITEM_TYPE.send(p); 34 | return null; 35 | } 36 | }else if (block) { 37 | if (!tmp.get().isBlock()) { 38 | Lang.INVALID_BLOCK_TYPE.send(p); 39 | return null; 40 | } 41 | } 42 | return tmp; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/options/QuestOptionBoolean.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.options; 2 | 3 | import org.bukkit.configuration.ConfigurationSection; 4 | import org.bukkit.inventory.ItemStack; 5 | import fr.skytasul.quests.api.gui.ItemUtils; 6 | import fr.skytasul.quests.api.quests.creation.QuestCreationGuiClickEvent; 7 | 8 | public abstract class QuestOptionBoolean extends QuestOption { 9 | 10 | public QuestOptionBoolean(Class>... requiredQuestOptions) { 11 | super(requiredQuestOptions); 12 | } 13 | 14 | @Override 15 | public Object save() { 16 | return getValue(); 17 | } 18 | 19 | @Override 20 | public void load(ConfigurationSection config, String key) { 21 | setValue(config.getBoolean(key)); 22 | } 23 | 24 | @Override 25 | public Boolean cloneValue(Boolean value) { 26 | return value; 27 | } 28 | 29 | public abstract String getName(); 30 | 31 | public String getDescription() { 32 | return null; 33 | } 34 | 35 | @Override 36 | public ItemStack getItemStack(OptionSet options) { 37 | return ItemUtils.itemSwitch(getName(), getValue(), formatDescription(getDescription())); 38 | } 39 | 40 | @Override 41 | public void click(QuestCreationGuiClickEvent event) { 42 | setValue(!getValue()); 43 | ItemUtils.setSwitch(event.getClicked(), getValue()); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionHologramText.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.QuestsConfigurationImplementation; 5 | import fr.skytasul.quests.api.QuestsAPI; 6 | import fr.skytasul.quests.api.localization.Lang; 7 | import fr.skytasul.quests.api.options.OptionSet; 8 | import fr.skytasul.quests.api.options.QuestOptionString; 9 | import org.bukkit.entity.Player; 10 | 11 | public class OptionHologramText extends QuestOptionString { 12 | 13 | public OptionHologramText() { 14 | super(OptionStarterNPC.class); 15 | } 16 | 17 | @Override 18 | public void sendIndication(Player p) { 19 | Lang.HOLOGRAM_TEXT.send(p); 20 | } 21 | 22 | @Override 23 | public XMaterial getItemMaterial() { 24 | return XMaterial.PAINTING; 25 | } 26 | 27 | @Override 28 | public String getItemName() { 29 | return Lang.hologramText.toString(); 30 | } 31 | 32 | @Override 33 | public String getItemDescription() { 34 | return Lang.hologramTextLore.toString(); 35 | } 36 | 37 | @Override 38 | public boolean shouldDisplay(OptionSet options) { 39 | return !QuestsConfigurationImplementation.getConfiguration().isTextHologramDisabled() 40 | && QuestsAPI.getAPI().hasHologramsManager() && options.getOption(OptionStarterNPC.class).getValue() != null; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/commands/parameters/QuestParameter.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.commands.parameters; 2 | 3 | import fr.skytasul.quests.api.QuestsAPI; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | import fr.skytasul.quests.api.quests.Quest; 6 | import org.jetbrains.annotations.NotNull; 7 | import revxrsal.commands.autocomplete.SuggestionProvider; 8 | import revxrsal.commands.command.CommandActor; 9 | import revxrsal.commands.exception.CommandErrorException; 10 | import revxrsal.commands.node.ExecutionContext; 11 | import revxrsal.commands.parameter.ParameterType; 12 | import revxrsal.commands.stream.MutableStringStream; 13 | 14 | public class QuestParameter implements ParameterType { 15 | 16 | @Override 17 | public Quest parse(@NotNull MutableStringStream input, @NotNull ExecutionContext<@NotNull CommandActor> context) { 18 | int id = input.readInt(); 19 | Quest quest = QuestsAPI.getAPI().getQuestsManager().getQuest(id); 20 | if (quest == null) 21 | throw new CommandErrorException(Lang.QUEST_INVALID.quickFormat("quest_id", id)); 22 | return quest; 23 | } 24 | 25 | @Override 26 | public @NotNull SuggestionProvider<@NotNull CommandActor> defaultSuggestions() { 27 | return context -> QuestsAPI.getAPI().getQuestsManager().getQuests() 28 | .stream() 29 | .map(quest -> Integer.toString(quest.getId())) 30 | .toList(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/editors/parsers/CollectionParser.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.editors.parsers; 2 | 3 | import java.util.Collection; 4 | import java.util.Map; 5 | import java.util.function.Function; 6 | import java.util.stream.Collectors; 7 | import org.bukkit.entity.Player; 8 | import fr.skytasul.quests.api.localization.Lang; 9 | import fr.skytasul.quests.api.utils.messaging.PlaceholderRegistry; 10 | 11 | public class CollectionParser implements AbstractParser { 12 | 13 | protected Map names; 14 | protected String namesString; 15 | 16 | public CollectionParser(Collection collection, Function namer) { 17 | names = collection.stream().collect(Collectors.toMap(namer, Function.identity())); 18 | namesString = String.join(", ", names.keySet()); 19 | } 20 | 21 | @Override 22 | public T parse(Player p, String msg) throws Throwable { 23 | T obj = names.get(processName(msg)); 24 | if (obj == null) 25 | Lang.NO_SUCH_ELEMENT.send(p, PlaceholderRegistry.of("available_elements", namesString)); 26 | return obj; 27 | } 28 | 29 | protected String processName(String msg) { 30 | return msg; 31 | } 32 | 33 | @Override 34 | public void sendIndication(Player p) { 35 | Lang.AVAILABLE_ELEMENTS.send(p, PlaceholderRegistry.of("available_elements", namesString)); 36 | } 37 | 38 | public String getNames() { 39 | return namesString; 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/BQItemsAdder.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations; 2 | 3 | import dev.lone.itemsadder.api.CustomStack; 4 | import fr.skytasul.quests.api.QuestsAPI; 5 | import fr.skytasul.quests.api.comparison.ItemComparison; 6 | import fr.skytasul.quests.api.localization.Lang; 7 | import org.bukkit.inventory.ItemStack; 8 | 9 | public final class BQItemsAdder { 10 | 11 | private BQItemsAdder() {} 12 | 13 | private static final ItemComparison COMPARISON = new ItemComparison("items_adder", Lang.comparisonItemsAdder.toString(), 14 | Lang.comparisonItemsAdderLore.toString(), BQItemsAdder::compareItems).setHasPriority(); 15 | 16 | public static void initialize() { 17 | QuestsAPI.getAPI().registerItemComparison(COMPARISON); 18 | } 19 | 20 | public static void unload() { 21 | QuestsAPI.getAPI().unregisterItemComparison(COMPARISON); 22 | } 23 | 24 | public static boolean compareItems(ItemStack item1, ItemStack item2) { 25 | CustomStack custom1 = CustomStack.byItemStack(item1); 26 | CustomStack custom2 = CustomStack.byItemStack(item2); 27 | 28 | if ((custom1 == null) != (custom2 == null)) 29 | return false; // tests if 1 item is null and the other is not null => not the same items 30 | 31 | if (custom1 == null) 32 | return true; // means both items are null => same items 33 | 34 | return custom1.matchNamespacedID(custom2); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/gui/mobs/MobSelectionGUI.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.gui.mobs; 2 | 3 | import fr.skytasul.quests.api.gui.close.CloseBehavior; 4 | import fr.skytasul.quests.api.gui.close.DelayCloseBehavior; 5 | import fr.skytasul.quests.api.gui.templates.PagedGUI; 6 | import fr.skytasul.quests.api.localization.Lang; 7 | import fr.skytasul.quests.api.mobs.MobFactory; 8 | import fr.skytasul.quests.mobs.Mob; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.entity.Player; 11 | import org.bukkit.event.inventory.ClickType; 12 | import org.bukkit.inventory.ItemStack; 13 | import java.util.function.Consumer; 14 | 15 | public class MobSelectionGUI extends PagedGUI> { 16 | 17 | private Consumer> end; 18 | 19 | public MobSelectionGUI(Consumer> end) { 20 | super(Lang.INVENTORY_MOBSELECT.toString(), DyeColor.LIME, MobFactory.factories); 21 | this.end = end; 22 | } 23 | 24 | @Override 25 | public ItemStack getItemStack(MobFactory object) { 26 | return object.getFactoryItem(); 27 | } 28 | 29 | @Override 30 | public void click(MobFactory existing, ItemStack item, ClickType clickType) { 31 | existing.itemClick(player, mobData -> { 32 | end.accept(mobData == null ? null : new Mob(existing, mobData)); 33 | }); 34 | } 35 | 36 | @Override 37 | public CloseBehavior onClose(Player p) { 38 | return new DelayCloseBehavior(() -> end.accept(null)); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/npcs/BQNPCClickEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.npcs; 2 | 3 | import fr.skytasul.quests.api.npcs.BqNpc; 4 | import fr.skytasul.quests.api.npcs.NpcClickType; 5 | import org.bukkit.entity.Player; 6 | import org.bukkit.event.Cancellable; 7 | import org.bukkit.event.HandlerList; 8 | import org.bukkit.event.player.PlayerEvent; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class BQNPCClickEvent extends PlayerEvent implements Cancellable { 12 | 13 | private final @NotNull BqNpc npc; 14 | private final @NotNull NpcClickType click; 15 | 16 | private boolean cancelled = false; 17 | 18 | public BQNPCClickEvent(@NotNull BqNpc npc, @NotNull Player p, @NotNull NpcClickType click) { 19 | super(p); 20 | this.npc = npc; 21 | this.click = click; 22 | } 23 | 24 | @Override 25 | public boolean isCancelled() { 26 | return cancelled; 27 | } 28 | 29 | @Override 30 | public void setCancelled(boolean cancelled) { 31 | this.cancelled = cancelled; 32 | } 33 | 34 | public @NotNull BqNpc getNPC() { 35 | return npc; 36 | } 37 | 38 | public @NotNull NpcClickType getClick() { 39 | return click; 40 | } 41 | 42 | @Override 43 | public HandlerList getHandlers() { 44 | return handlers; 45 | } 46 | 47 | public static HandlerList getHandlerList() { 48 | return handlers; 49 | } 50 | 51 | private static final HandlerList handlers = new HandlerList(); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/questers/AbstractQuesterPoolDataImplementation.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.questers; 2 | 3 | import fr.skytasul.quests.BeautyQuests; 4 | import fr.skytasul.quests.api.questers.data.QuesterPoolData; 5 | import fr.skytasul.quests.structure.pools.QuestPoolImplementation; 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | public abstract class AbstractQuesterPoolDataImplementation implements QuesterPoolData { 10 | 11 | protected final int poolId; 12 | 13 | protected long lastGive; 14 | protected Set completedQuests = new HashSet<>(); 15 | 16 | public AbstractQuesterPoolDataImplementation(int poolId) { 17 | this.poolId = poolId; 18 | } 19 | 20 | @Override 21 | public int getPoolId() { 22 | return poolId; 23 | } 24 | 25 | @Override 26 | public QuestPoolImplementation getPool() { 27 | return BeautyQuests.getInstance().getPoolsManager().getPool(poolId); 28 | } 29 | 30 | @Override 31 | public long getLastGive() { 32 | return lastGive; 33 | } 34 | 35 | @Override 36 | public void setLastGive(long lastGive) { 37 | this.lastGive = lastGive; 38 | } 39 | 40 | @Override 41 | public Set getCompletedQuests() { 42 | return completedQuests; 43 | } 44 | 45 | @Override 46 | public void setCompletedQuests(Set completedQuests) { 47 | this.completedQuests = completedQuests; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/AbstractHolograms.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api; 2 | 3 | import java.util.List; 4 | import org.bukkit.Location; 5 | import org.bukkit.entity.Player; 6 | import org.bukkit.inventory.ItemStack; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public abstract class AbstractHolograms { 11 | 12 | public abstract boolean supportPerPlayerVisibility(); 13 | 14 | public abstract boolean supportItems(); 15 | 16 | public abstract @NotNull BQHologram createHologram(@NotNull Location lc, boolean defaultVisible); 17 | 18 | public abstract class BQHologram { 19 | protected @NotNull T hologram; 20 | 21 | protected BQHologram(@NotNull T hologram) { 22 | this.hologram = hologram; 23 | } 24 | 25 | public void setPlayersVisible(@NotNull List players) { 26 | players.forEach(p -> setPlayerVisibility(p, true)); 27 | } 28 | 29 | public void setPlayerVisibility(@NotNull Player p, boolean visible) { 30 | throw new UnsupportedOperationException(); 31 | } 32 | 33 | public void appendItem(@NotNull ItemStack item) { 34 | throw new UnsupportedOperationException(); 35 | } 36 | 37 | public abstract void appendTextLine(@Nullable String text); 38 | 39 | public abstract void teleport(@NotNull Location lc); 40 | 41 | public abstract void delete(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/players/PlayerManager.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.players; 2 | 3 | import fr.skytasul.quests.api.QuestsPlugin; 4 | import fr.skytasul.quests.api.questers.QuesterManager; 5 | import fr.skytasul.quests.api.questers.QuesterProvider; 6 | import org.bukkit.entity.Player; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.UnknownNullability; 9 | import org.jetbrains.annotations.UnmodifiableView; 10 | import java.util.Collection; 11 | import java.util.List; 12 | 13 | public interface PlayerManager extends QuesterProvider { 14 | 15 | @Override 16 | @NotNull 17 | @UnmodifiableView 18 | Collection getLoadedQuesters(); 19 | 20 | @Override 21 | default @NotNull @UnmodifiableView Collection getPlayerQuesters(@NotNull Player player) { 22 | var quester = getQuester(player); 23 | return quester == null ? List.of() : List.of(quester); 24 | } 25 | 26 | public @UnknownNullability PlayerQuester getQuester(@NotNull Player p); 27 | 28 | /** 29 | * @deprecated use the non-static version {@link #getQuester(Player)}, or better, switch to using 30 | * the {@link QuesterManager} directly 31 | */ 32 | @Deprecated(forRemoval = true) 33 | public static @UnknownNullability PlayerQuester getPlayerAccount(@NotNull Player p) { 34 | return QuestsPlugin.getPlugin().getPlayersManager().getQuester(p); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/commands/parameters/QuestPoolParameter.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.commands.parameters; 2 | 3 | import fr.skytasul.quests.api.QuestsAPI; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | import fr.skytasul.quests.api.pools.QuestPool; 6 | import org.jetbrains.annotations.NotNull; 7 | import revxrsal.commands.autocomplete.SuggestionProvider; 8 | import revxrsal.commands.command.CommandActor; 9 | import revxrsal.commands.exception.CommandErrorException; 10 | import revxrsal.commands.node.ExecutionContext; 11 | import revxrsal.commands.parameter.ParameterType; 12 | import revxrsal.commands.stream.MutableStringStream; 13 | 14 | public class QuestPoolParameter implements ParameterType { 15 | 16 | @Override 17 | public QuestPool parse(@NotNull MutableStringStream input, @NotNull ExecutionContext<@NotNull CommandActor> context) { 18 | int id = input.readInt(); 19 | QuestPool QuestPool = QuestsAPI.getAPI().getPoolsManager().getPool(id); 20 | if (QuestPool == null) 21 | throw new CommandErrorException(Lang.POOL_INVALID.quickFormat("pool_id", id)); 22 | return QuestPool; 23 | } 24 | 25 | @Override 26 | public @NotNull SuggestionProvider<@NotNull CommandActor> defaultSuggestions() { 27 | return context -> QuestsAPI.getAPI().getPoolsManager().getPools() 28 | .stream() 29 | .map(QuestPool -> Integer.toString(QuestPool.getId())) 30 | .toList(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/gui/items/ItemComparisonGUI.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.gui.items; 2 | 3 | import fr.skytasul.quests.api.QuestsAPI; 4 | import fr.skytasul.quests.api.comparison.ItemComparison; 5 | import fr.skytasul.quests.api.comparison.ItemComparisonMap; 6 | import fr.skytasul.quests.api.gui.ItemUtils; 7 | import fr.skytasul.quests.api.gui.templates.PagedGUI; 8 | import fr.skytasul.quests.api.localization.Lang; 9 | import fr.skytasul.quests.api.options.QuestOption; 10 | import org.bukkit.DyeColor; 11 | import org.bukkit.event.inventory.ClickType; 12 | import org.bukkit.inventory.ItemStack; 13 | 14 | public class ItemComparisonGUI extends PagedGUI { 15 | 16 | private ItemComparisonMap comparisons; 17 | 18 | public ItemComparisonGUI(ItemComparisonMap comparisons, Runnable validate) { 19 | super(Lang.INVENTORY_ITEM_COMPARISONS.toString(), DyeColor.LIME, QuestsAPI.getAPI().getItemComparisons(), x -> validate.run(), 20 | null); 21 | this.comparisons = comparisons; 22 | } 23 | 24 | @Override 25 | public ItemStack getItemStack(ItemComparison object) { 26 | return ItemUtils.itemSwitch(object.getItemName(), comparisons.isEnabled(object), 27 | QuestOption.formatDescription(object.getItemDescription())); 28 | } 29 | 30 | @Override 31 | public void click(ItemComparison existing, ItemStack item, ClickType clickType) { 32 | ItemUtils.setSwitch(item, comparisons.toggle(existing)); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/gui/particles/ParticleListGUI.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.gui.particles; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.gui.ItemUtils; 5 | import fr.skytasul.quests.api.gui.templates.StaticPagedGUI; 6 | import fr.skytasul.quests.api.localization.Lang; 7 | import fr.skytasul.quests.api.options.QuestOption; 8 | import fr.skytasul.quests.utils.ParticleEffect; 9 | import org.bukkit.DyeColor; 10 | import org.bukkit.Particle; 11 | import org.bukkit.inventory.ItemStack; 12 | import java.util.Map; 13 | import java.util.function.Consumer; 14 | import java.util.function.Function; 15 | import java.util.stream.Collectors; 16 | 17 | public class ParticleListGUI extends StaticPagedGUI { 18 | 19 | private static final Map PARTICLES = ParticleEffectGUI.PARTICLES 20 | .stream().collect(Collectors.toMap(Function.identity(), particle -> { 21 | boolean colorable = ParticleEffect.canHaveColor(particle); 22 | String[] lore = colorable ? new String[] { QuestOption.formatDescription(Lang.particle_colored.toString()) } : new String[0]; 23 | return ItemUtils.item(colorable ? XMaterial.MAP : XMaterial.PAPER, "§e" + particle.name(), lore); 24 | })); 25 | 26 | public ParticleListGUI(Consumer end) { 27 | super(Lang.INVENTORY_PARTICLE_LIST.toString(), DyeColor.MAGENTA, PARTICLES, end, Particle::name); 28 | sortValuesByName(); 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/gui/misc/BucketTypeGUI.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.gui.misc; 2 | 3 | import fr.skytasul.quests.api.gui.ItemUtils; 4 | import fr.skytasul.quests.api.gui.close.CloseBehavior; 5 | import fr.skytasul.quests.api.gui.close.DelayCloseBehavior; 6 | import fr.skytasul.quests.api.gui.templates.ChooseGUI; 7 | import fr.skytasul.quests.api.localization.Lang; 8 | import fr.skytasul.quests.stages.StageBucket.BucketType; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.ItemStack; 11 | import java.util.Arrays; 12 | import java.util.function.Consumer; 13 | 14 | public class BucketTypeGUI extends ChooseGUI{ 15 | 16 | private Runnable cancel; 17 | private Consumer end; 18 | 19 | public BucketTypeGUI(Runnable cancel, Consumer end) { 20 | super(Arrays.asList(BucketType.getAvailable())); 21 | this.cancel = cancel; 22 | this.end = end; 23 | } 24 | 25 | @Override 26 | public String name(){ 27 | return Lang.INVENTORY_BUCKETS.toString(); 28 | } 29 | 30 | @Override 31 | public ItemStack getItemStack(BucketType object){ 32 | return ItemUtils.item(object.getMaterial(), object.getName()); 33 | } 34 | 35 | @Override 36 | public void finish(BucketType object){ 37 | end.accept(object); 38 | } 39 | 40 | @Override 41 | public CloseBehavior onClose(Player p) { 42 | return new DelayCloseBehavior(cancel); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/StageDescriptionPlaceholdersContext.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages; 2 | 3 | import fr.skytasul.quests.api.options.description.DescriptionSource; 4 | import fr.skytasul.quests.api.questers.Quester; 5 | import fr.skytasul.quests.api.utils.messaging.MessageType; 6 | import fr.skytasul.quests.api.utils.messaging.PlaceholdersContext.QuesterPlaceholdersContext; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public interface StageDescriptionPlaceholdersContext extends QuesterPlaceholdersContext { 11 | 12 | @NotNull 13 | DescriptionSource getDescriptionSource(); 14 | 15 | static @NotNull StageDescriptionPlaceholdersContext of(boolean replacePluginPlaceholders, @NotNull Quester quester, 16 | @NotNull DescriptionSource source, @Nullable MessageType messageType) { 17 | return new StageDescriptionPlaceholdersContext() { 18 | 19 | @Override 20 | public @NotNull Quester getQuester() { 21 | return quester; 22 | } 23 | 24 | @Override 25 | public boolean replacePluginPlaceholders() { 26 | return replacePluginPlaceholders; 27 | } 28 | 29 | @Override 30 | public @NotNull DescriptionSource getDescriptionSource() { 31 | return source; 32 | } 33 | 34 | @Override 35 | public @Nullable MessageType getMessageType() { 36 | return messageType; 37 | } 38 | }; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/StageIndex.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import java.util.regex.Matcher; 5 | import java.util.regex.Pattern; 6 | 7 | public sealed interface StageIndex { 8 | 9 | @Override 10 | @NotNull 11 | String toString(); 12 | 13 | static final Pattern FLOW_PATTERN = Pattern.compile("(\\d+):(E)?(\\d+)"); 14 | 15 | static @NotNull StageIndex fromString(@NotNull String string) throws IllegalArgumentException { 16 | Matcher matcher = FLOW_PATTERN.matcher(string); 17 | 18 | if (!matcher.matches()) 19 | throw new IllegalArgumentException("Invalid stage index string: " + string); 20 | 21 | int branchId = Integer.parseInt(matcher.group(1)); 22 | int stageId = Integer.parseInt(matcher.group(3)); 23 | if (matcher.group(2) != null) { 24 | // means it matched the E meaning it's an ending stage 25 | return new EndingStageIndex(branchId, stageId); 26 | } else { 27 | return new RegularStageIndex(branchId, stageId); 28 | } 29 | } 30 | 31 | record RegularStageIndex(int branch, int stageIndex) implements StageIndex { 32 | @Override 33 | public final String toString() { 34 | return "%d:%d".formatted(branch, stageIndex); 35 | } 36 | } 37 | 38 | record EndingStageIndex(int branch, int stageId) implements StageIndex { 39 | @Override 40 | public final String toString() { 41 | return "%d:E%d".formatted(branch, stageId); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/events/internal/BQCraftEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.events.internal; 2 | 3 | import com.cryptomorin.xseries.inventory.XInventoryView; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.bukkit.event.inventory.InventoryClickEvent; 7 | import org.bukkit.event.player.PlayerEvent; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class BQCraftEvent extends PlayerEvent { 12 | 13 | private final @NotNull InventoryClickEvent clickEvent; 14 | private final @NotNull ItemStack result; 15 | private final int maxCraftable; 16 | 17 | public BQCraftEvent(@NotNull InventoryClickEvent clickEvent, @NotNull ItemStack result, int maxCraftable) { 18 | super((Player) XInventoryView.of(clickEvent.getView()).getPlayer()); 19 | this.clickEvent = clickEvent; 20 | this.result = result; 21 | this.maxCraftable = maxCraftable; 22 | } 23 | 24 | public @NotNull InventoryClickEvent getClickEvent() { 25 | return clickEvent; 26 | } 27 | 28 | public @NotNull ItemStack getResult() { 29 | return result; 30 | } 31 | 32 | public int getMaxCraftable() { 33 | return maxCraftable; 34 | } 35 | 36 | @Override 37 | public HandlerList getHandlers() { 38 | return handlers; 39 | } 40 | 41 | public static HandlerList getHandlerList() { 42 | return handlers; 43 | } 44 | 45 | private static final HandlerList handlers = new HandlerList(); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/quests/events/QuestCreateEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.quests.events; 2 | 3 | import fr.skytasul.quests.api.quests.Quest; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.HandlerList; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | /** 11 | * Called when a quest is created 12 | */ 13 | public class QuestCreateEvent extends AbstractQuestEvent implements Cancellable { 14 | 15 | private final boolean edited; 16 | private final @Nullable Player creator; 17 | 18 | private boolean cancel; 19 | 20 | public QuestCreateEvent(@NotNull Quest quest, boolean edited, @Nullable Player creator) { 21 | super(quest); 22 | this.edited = edited; 23 | this.creator = creator; 24 | } 25 | 26 | @Override 27 | public boolean isCancelled(){ 28 | return cancel; 29 | } 30 | 31 | @Override 32 | public void setCancelled(boolean paramBoolean){ 33 | this.cancel = paramBoolean; 34 | } 35 | 36 | public boolean isEdited(){ 37 | return edited; 38 | } 39 | 40 | public @Nullable Player getCreator() { 41 | return creator; 42 | } 43 | 44 | @Override 45 | public HandlerList getHandlers() { 46 | return handlers; 47 | } 48 | 49 | public static HandlerList getHandlerList() { 50 | return handlers; 51 | } 52 | 53 | private static final HandlerList handlers = new HandlerList(); 54 | 55 | } 56 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/events/internal/BQMobDeathEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.events.internal; 2 | 3 | import org.bukkit.entity.Entity; 4 | import org.bukkit.event.Event; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | import javax.annotation.Nullable; 8 | 9 | public class BQMobDeathEvent extends Event { 10 | private static final HandlerList handlers = new HandlerList(); 11 | 12 | private final Object pluginEntity; 13 | private final Entity bukkitEntity; 14 | private final int amount; 15 | private Entity killer; 16 | 17 | public BQMobDeathEvent(@NotNull Object pluginEntity, @NotNull Entity killer, @Nullable Entity bukkitEntity, int amount) { 18 | this.pluginEntity = pluginEntity; 19 | this.killer = killer; 20 | this.bukkitEntity = bukkitEntity; 21 | this.amount = amount; 22 | } 23 | 24 | public @NotNull Object getPluginMob() { 25 | return pluginEntity; 26 | } 27 | 28 | public @NotNull Entity getKiller() { 29 | return killer; 30 | } 31 | 32 | public void setKiller(@NotNull Entity killer) { 33 | this.killer = killer; 34 | } 35 | 36 | public @Nullable Entity getBukkitEntity() { 37 | return bukkitEntity; 38 | } 39 | 40 | public int getAmount() { 41 | return amount; 42 | } 43 | 44 | @Override 45 | public HandlerList getHandlers() { 46 | return handlers; 47 | } 48 | 49 | public static HandlerList getHandlerList() { 50 | return handlers; 51 | } 52 | } -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/npcs/dialogs/events/DialogSendMessageEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.npcs.dialogs.events; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.Cancellable; 5 | import org.bukkit.event.HandlerList; 6 | import org.bukkit.event.player.PlayerEvent; 7 | import org.jetbrains.annotations.NotNull; 8 | import fr.skytasul.quests.api.npcs.dialogs.DialogRunner; 9 | import fr.skytasul.quests.api.npcs.dialogs.Message; 10 | 11 | public class DialogSendMessageEvent extends PlayerEvent implements Cancellable { 12 | 13 | private boolean cancelled = false; 14 | 15 | private final @NotNull DialogRunner dialog; 16 | private final @NotNull Message message; 17 | 18 | public DialogSendMessageEvent(@NotNull Player who, @NotNull DialogRunner dialog, @NotNull Message message) { 19 | super(who); 20 | this.dialog = dialog; 21 | this.message = message; 22 | } 23 | 24 | @Override 25 | public boolean isCancelled() { 26 | return cancelled; 27 | } 28 | 29 | @Override 30 | public void setCancelled(boolean cancelled) { 31 | this.cancelled = cancelled; 32 | } 33 | 34 | public DialogRunner getDialog() { 35 | return dialog; 36 | } 37 | 38 | public Message getMessage() { 39 | return message; 40 | } 41 | 42 | @Override 43 | public HandlerList getHandlers() { 44 | return handlers; 45 | } 46 | 47 | public static HandlerList getHandlerList() { 48 | return handlers; 49 | } 50 | 51 | private static final HandlerList handlers = new HandlerList(); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/editor/DefaultEditorFactory.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.editor; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.editors.Editor; 5 | import fr.skytasul.quests.api.editors.EditorFactory; 6 | import fr.skytasul.quests.api.editors.parsers.AbstractParser; 7 | import fr.skytasul.quests.api.npcs.BqNpc; 8 | import fr.skytasul.quests.editor.parsers.MaterialParser; 9 | import org.bukkit.entity.Player; 10 | import org.jetbrains.annotations.NotNull; 11 | import java.util.function.Consumer; 12 | 13 | public class DefaultEditorFactory implements EditorFactory { 14 | 15 | public static final MaterialParser ITEM_PARSER = new MaterialParser(true, false); 16 | public static final MaterialParser BLOCK_PARSER = new MaterialParser(false, true); 17 | public static final MaterialParser ANY_PARSER = new MaterialParser(false, false); 18 | 19 | @Override 20 | public @NotNull AbstractParser getMaterialParser(boolean item, boolean block) { 21 | if (item && !block) 22 | return ITEM_PARSER; 23 | if (block && !item) 24 | return BLOCK_PARSER; 25 | if (block && item) 26 | return ANY_PARSER; 27 | 28 | throw new IllegalArgumentException("Material parser must be either for items, for blocks or both, not neither."); 29 | } 30 | 31 | @Override 32 | public @NotNull Editor createNpcSelection(@NotNull Player player, @NotNull Runnable cancel, 33 | @NotNull Consumer callback) { 34 | return new SelectNPC(player, cancel, callback); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/stages/creation/StageGuiLine.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.stages.creation; 2 | 3 | import java.util.List; 4 | import java.util.function.UnaryOperator; 5 | import org.bukkit.inventory.ItemStack; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | import fr.skytasul.quests.api.gui.ItemUtils; 9 | 10 | public interface StageGuiLine { 11 | 12 | @Nullable 13 | ItemStack getItem(int slot); 14 | 15 | int setItem(int slot, @NotNull ItemStack item, @Nullable StageGuiClickHandler click); 16 | 17 | void refreshItem(int slot, @NotNull ItemStack item); 18 | 19 | default void refreshItem(int slot, UnaryOperator consumer) { 20 | refreshItem(slot, consumer.apply(getItem(slot))); 21 | } 22 | 23 | default void refreshItemLore(int slot, String... lore) { 24 | refreshItem(slot, ItemUtils.lore(getItem(slot), lore)); 25 | } 26 | 27 | default void refreshItemLore(int slot, List lore) { 28 | refreshItem(slot, ItemUtils.lore(getItem(slot), lore)); 29 | } 30 | 31 | default void refreshItemLoreOptionValue(int slot, @Nullable Object value) { 32 | refreshItem(slot, ItemUtils.loreOptionValue(getItem(slot), value)); 33 | } 34 | 35 | default void refreshItemName(int slot, String name) { 36 | refreshItem(slot, ItemUtils.name(getItem(slot), name)); 37 | } 38 | 39 | void removeItem(int slot); 40 | 41 | int getPage(); 42 | 43 | void setPage(int page); 44 | 45 | @Nullable 46 | StageGuiClickHandler getClick(int rawSlot); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/mobs/BQStackMob.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations.mobs; 2 | 3 | import com.google.common.cache.Cache; 4 | import com.google.common.cache.CacheBuilder; 5 | import fr.skytasul.quests.api.QuestsAPI; 6 | import fr.skytasul.quests.api.QuestsPlugin; 7 | import fr.skytasul.quests.api.mobs.MobStacker; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.entity.Entity; 10 | import org.bukkit.event.EventHandler; 11 | import org.bukkit.event.Listener; 12 | import org.jetbrains.annotations.NotNull; 13 | import uk.antiperson.stackmob.events.StackDeathEvent; 14 | import java.util.concurrent.TimeUnit; 15 | 16 | public class BQStackMob implements Listener, MobStacker { 17 | 18 | private final Cache killedStacks = 19 | CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.SECONDS).build(); 20 | 21 | private BQStackMob() {} 22 | 23 | public static void initialize() { 24 | BQStackMob stacker = new BQStackMob(); 25 | QuestsAPI.getAPI().registerMobStacker(stacker); 26 | Bukkit.getPluginManager().registerEvents(stacker, QuestsPlugin.getPlugin()); 27 | } 28 | 29 | @EventHandler 30 | public void onStackDeath(StackDeathEvent event) { 31 | killedStacks.put(event.getStackEntity().getEntity().getEntityId(), event.getDeathStep()); 32 | } 33 | 34 | @Override 35 | public int getEntityStackSize(@NotNull Entity entity) { 36 | Integer amount = killedStacks.getIfPresent(entity.getEntityId()); 37 | return amount == null ? 1 : amount.intValue(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/blocks/BQBlockTag.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.blocks; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.blocks.BQBlock; 5 | import fr.skytasul.quests.api.blocks.BQBlockOptions; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.Material; 8 | import org.bukkit.NamespacedKey; 9 | import org.bukkit.Tag; 10 | import org.bukkit.block.Block; 11 | import java.util.Set; 12 | 13 | public class BQBlockTag extends BQBlock { 14 | 15 | private final Tag tag; 16 | private final String tagKey; 17 | 18 | public BQBlockTag(BQBlockOptions options, String stringData) { 19 | this(options, Bukkit.getTag(Tag.REGISTRY_BLOCKS, NamespacedKey.fromString(stringData), Material.class)); 20 | } 21 | 22 | public BQBlockTag(BQBlockOptions options, Tag tag) { 23 | super(options); 24 | this.tagKey = tag.getKey().toString(); 25 | this.tag = tag; 26 | } 27 | 28 | @Override 29 | public boolean applies(Block block) { 30 | return tag != null && tag.isTagged(block.getType()); 31 | } 32 | 33 | @Override 34 | public XMaterial retrieveMaterial() { 35 | if (tag != null) { 36 | Set values = tag.getValues(); 37 | if (!values.isEmpty()) return XMaterial.matchXMaterial(values.iterator().next()); 38 | } 39 | return XMaterial.BARRIER; 40 | } 41 | 42 | @Override 43 | public String getDefaultName() { 44 | return tag == null ? tagKey : tag.getKey().getKey(); 45 | } 46 | 47 | @Override 48 | public String getDataString() { 49 | return tagKey; 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionCancelRewards.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.QuestsAPI; 5 | import fr.skytasul.quests.api.gui.ItemUtils; 6 | import fr.skytasul.quests.api.localization.Lang; 7 | import fr.skytasul.quests.api.objects.QuestObjectGUI; 8 | import fr.skytasul.quests.api.objects.QuestObjectLocation; 9 | import fr.skytasul.quests.api.options.QuestOptionRewards; 10 | import fr.skytasul.quests.api.quests.creation.QuestCreationGuiClickEvent; 11 | import fr.skytasul.quests.api.rewards.RewardList; 12 | import java.util.stream.Collectors; 13 | 14 | public class OptionCancelRewards extends QuestOptionRewards { 15 | 16 | @Override 17 | public XMaterial getItemMaterial() { 18 | return XMaterial.TNT_MINECART; 19 | } 20 | 21 | @Override 22 | public String getItemName() { 23 | return Lang.cancelRewards.toString(); 24 | } 25 | 26 | @Override 27 | public String getItemDescription() { 28 | return Lang.cancelRewardsLore.toString(); 29 | } 30 | 31 | @Override 32 | public void click(QuestCreationGuiClickEvent event) { 33 | new QuestObjectGUI<>(Lang.INVENTORY_CANCEL_ACTIONS.toString(), QuestObjectLocation.CANCELLING, QuestsAPI.getAPI() 34 | .getRewards().getCreators().stream().filter(x -> !x.canBeAsync()).collect(Collectors.toList()), objects -> { 35 | setValue(new RewardList(objects)); 36 | ItemUtils.lore(event.getClicked(), getLore()); 37 | event.reopen(); 38 | }, getValue()).open(event.getPlayer()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/npcs/BqNpcManager.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.npcs; 2 | 3 | import java.util.Collection; 4 | import org.bukkit.Location; 5 | import org.bukkit.entity.Entity; 6 | import org.bukkit.entity.EntityType; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.event.Cancellable; 9 | import org.jetbrains.annotations.NotNull; 10 | import org.jetbrains.annotations.Nullable; 11 | import fr.skytasul.quests.api.npcs.BqInternalNpcFactory.BqInternalNpcFactoryCreatable; 12 | 13 | public interface BqNpcManager { 14 | 15 | boolean isEnabled(); 16 | 17 | /** 18 | * Adds a new npc factory to the npc manager. 19 | * 20 | * @param key unique key of the npc factory 21 | * @param internalFactory factory 22 | */ 23 | void addInternalFactory(@NotNull String key, @NotNull BqInternalNpcFactory internalFactory); 24 | 25 | @NotNull 26 | Collection getAvailableIds(); 27 | 28 | boolean isNPC(@NotNull Entity entity); 29 | 30 | @NotNull 31 | BqNpc createNPC(@NotNull BqInternalNpcFactoryCreatable internalFactory, @NotNull Location location, 32 | @NotNull EntityType type, @NotNull String name, @Nullable String skin); 33 | 34 | @Nullable 35 | BqNpc getById(String id); 36 | 37 | void npcRemoved(@NotNull BqInternalNpcFactory internalFactory, String internalId); 38 | 39 | void npcClicked(@NotNull BqInternalNpcFactory internalFactory, @Nullable Cancellable event, String internalId, 40 | @NotNull Player p, @NotNull NpcClickType click); 41 | 42 | void reload(@NotNull BqInternalNpcFactory internalFactory); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionStartable.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import fr.skytasul.quests.api.options.QuestOptionBoolean; 5 | import fr.skytasul.quests.api.options.description.QuestDescriptionContext; 6 | import fr.skytasul.quests.api.options.description.QuestDescriptionProvider; 7 | import fr.skytasul.quests.api.utils.PlayerListCategory; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | public class OptionStartable extends QuestOptionBoolean implements QuestDescriptionProvider { 12 | 13 | private static final List STARTABLE = Arrays.asList(Lang.startLore.toString()); 14 | private static final List NOT_STARTABLE = Arrays.asList(Lang.startImpossibleLore.toString()); 15 | 16 | @Override 17 | public String getName() { 18 | return Lang.startableFromGUI.toString(); 19 | } 20 | 21 | @Override 22 | public String getDescription() { 23 | return Lang.startableFromGUILore.toString(); 24 | } 25 | 26 | @Override 27 | public List provideDescription(QuestDescriptionContext context) { 28 | if (context.getCategory() != PlayerListCategory.NOT_STARTED || context.getPlayer() == null) 29 | return null; 30 | return context.getQuest().canStart(context.getPlayer(), false) ? STARTABLE : NOT_STARTABLE; 31 | } 32 | 33 | @Override 34 | public String getDescriptionId() { 35 | return "startable_from_gui"; 36 | } 37 | 38 | @Override 39 | public double getDescriptionPriority() { 40 | return 100; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/npcs/BqInternalNpcFactory.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.npcs; 2 | 3 | import java.util.Collection; 4 | import org.bukkit.Location; 5 | import org.bukkit.entity.Entity; 6 | import org.bukkit.entity.EntityType; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.event.Cancellable; 9 | import org.jetbrains.annotations.NotNull; 10 | import org.jetbrains.annotations.Nullable; 11 | import fr.skytasul.quests.api.QuestsPlugin; 12 | import fr.skytasul.quests.api.utils.AutoRegistered; 13 | 14 | @AutoRegistered 15 | public interface BqInternalNpcFactory { 16 | 17 | int getTimeToWaitForNPCs(); 18 | 19 | boolean isNPC(@NotNull Entity entity); 20 | 21 | @NotNull 22 | Collection<@NotNull String> getIDs(); 23 | 24 | @Nullable 25 | BqInternalNpc fetchNPC(String id); 26 | 27 | default void npcClicked(@Nullable Cancellable event, String npcID, @NotNull Player p, @NotNull NpcClickType click) { 28 | QuestsPlugin.getPlugin().getNpcManager().npcClicked(this, event, npcID, p, click); 29 | } 30 | 31 | default void npcRemoved(String id) { 32 | QuestsPlugin.getPlugin().getNpcManager().npcRemoved(this, id); 33 | } 34 | 35 | default void npcsReloaded() { 36 | QuestsPlugin.getPlugin().getNpcManager().reload(this); 37 | } 38 | 39 | public interface BqInternalNpcFactoryCreatable extends BqInternalNpcFactory { 40 | 41 | boolean isValidEntityType(@NotNull EntityType type); 42 | 43 | @NotNull 44 | BqInternalNpc create(@NotNull Location location, @NotNull EntityType type, @NotNull String name, 45 | @Nullable String skin); 46 | 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /v1_19_R2/src/main/java/fr/skytasul/quests/utils/nms/v1_19_R2.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.nms; 2 | 3 | import net.kyori.adventure.key.Key; 4 | import java.util.List; 5 | import org.bukkit.Material; 6 | import net.minecraft.core.Holder.Reference; 7 | import net.minecraft.core.HolderLookup.RegistryLookup; 8 | import net.minecraft.core.registries.Registries; 9 | import net.minecraft.resources.ResourceKey; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.server.MinecraftServer; 12 | import net.minecraft.world.level.block.Block; 13 | import net.minecraft.world.level.block.state.BlockState; 14 | import net.minecraft.world.level.block.state.StateDefinition; 15 | import net.minecraft.world.level.block.state.properties.Property; 16 | 17 | public class v1_19_R2 extends NMS{ 18 | 19 | @Override 20 | public List getAvailableBlockProperties(Material material) { 21 | RegistryLookup blockRegistry = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK); 22 | Reference block = blockRegistry 23 | .getOrThrow(ResourceKey.create(Registries.BLOCK, new ResourceLocation(material.getKey().getKey()))); 24 | StateDefinition stateList = block.value().getStateDefinition(); 25 | return stateList.getProperties().stream().map(Property::getName).toList(); 26 | } 27 | 28 | @Override 29 | public List getAvailableBlockTags() { 30 | return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK).listTags() 31 | .map(x -> Key.key(x.key().location().toString())).toList(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /v1_19_R3/src/main/java/fr/skytasul/quests/utils/nms/v1_19_R3.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.nms; 2 | 3 | import net.kyori.adventure.key.Key; 4 | import java.util.List; 5 | import org.bukkit.Material; 6 | import net.minecraft.core.Holder.Reference; 7 | import net.minecraft.core.HolderLookup.RegistryLookup; 8 | import net.minecraft.core.registries.Registries; 9 | import net.minecraft.resources.ResourceKey; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.server.MinecraftServer; 12 | import net.minecraft.world.level.block.Block; 13 | import net.minecraft.world.level.block.state.BlockState; 14 | import net.minecraft.world.level.block.state.StateDefinition; 15 | import net.minecraft.world.level.block.state.properties.Property; 16 | 17 | public class v1_19_R3 extends NMS{ 18 | 19 | @Override 20 | public List getAvailableBlockProperties(Material material) { 21 | RegistryLookup blockRegistry = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK); 22 | Reference block = blockRegistry 23 | .getOrThrow(ResourceKey.create(Registries.BLOCK, new ResourceLocation(material.getKey().getKey()))); 24 | StateDefinition stateList = block.value().getStateDefinition(); 25 | return stateList.getProperties().stream().map(Property::getName).toList(); 26 | } 27 | 28 | @Override 29 | public List getAvailableBlockTags() { 30 | return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK).listTags() 31 | .map(x -> Key.key(x.key().location().toString())).toList(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /v1_20_R1/src/main/java/fr/skytasul/quests/utils/nms/v1_20_R1.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.nms; 2 | 3 | import net.kyori.adventure.key.Key; 4 | import java.util.List; 5 | import org.bukkit.Material; 6 | import net.minecraft.core.Holder.Reference; 7 | import net.minecraft.core.HolderLookup.RegistryLookup; 8 | import net.minecraft.core.registries.Registries; 9 | import net.minecraft.resources.ResourceKey; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.server.MinecraftServer; 12 | import net.minecraft.world.level.block.Block; 13 | import net.minecraft.world.level.block.state.BlockState; 14 | import net.minecraft.world.level.block.state.StateDefinition; 15 | import net.minecraft.world.level.block.state.properties.Property; 16 | 17 | public class v1_20_R1 extends NMS{ 18 | 19 | @Override 20 | public List getAvailableBlockProperties(Material material) { 21 | RegistryLookup blockRegistry = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK); 22 | Reference block = blockRegistry 23 | .getOrThrow(ResourceKey.create(Registries.BLOCK, new ResourceLocation(material.getKey().getKey()))); 24 | StateDefinition stateList = block.value().getStateDefinition(); 25 | return stateList.getProperties().stream().map(Property::getName).toList(); 26 | } 27 | 28 | @Override 29 | public List getAvailableBlockTags() { 30 | return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK).listTags() 31 | .map(x -> Key.key(x.key().location().toString())).toList(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /v1_20_R2/src/main/java/fr/skytasul/quests/utils/nms/v1_20_R2.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.nms; 2 | 3 | import net.kyori.adventure.key.Key; 4 | import java.util.List; 5 | import org.bukkit.Material; 6 | import net.minecraft.core.Holder.Reference; 7 | import net.minecraft.core.HolderLookup.RegistryLookup; 8 | import net.minecraft.core.registries.Registries; 9 | import net.minecraft.resources.ResourceKey; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.server.MinecraftServer; 12 | import net.minecraft.world.level.block.Block; 13 | import net.minecraft.world.level.block.state.BlockState; 14 | import net.minecraft.world.level.block.state.StateDefinition; 15 | import net.minecraft.world.level.block.state.properties.Property; 16 | 17 | public class v1_20_R2 extends NMS{ 18 | 19 | @Override 20 | public List getAvailableBlockProperties(Material material) { 21 | RegistryLookup blockRegistry = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK); 22 | Reference block = blockRegistry 23 | .getOrThrow(ResourceKey.create(Registries.BLOCK, new ResourceLocation(material.getKey().getKey()))); 24 | StateDefinition stateList = block.value().getStateDefinition(); 25 | return stateList.getProperties().stream().map(Property::getName).toList(); 26 | } 27 | 28 | @Override 29 | public List getAvailableBlockTags() { 30 | return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK).listTags() 31 | .map(x -> Key.key(x.key().location().toString())).toList(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /v1_20_R3/src/main/java/fr/skytasul/quests/utils/nms/v1_20_R3.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.utils.nms; 2 | 3 | import net.kyori.adventure.key.Key; 4 | import java.util.List; 5 | import org.bukkit.Material; 6 | import net.minecraft.core.Holder.Reference; 7 | import net.minecraft.core.HolderLookup.RegistryLookup; 8 | import net.minecraft.core.registries.Registries; 9 | import net.minecraft.resources.ResourceKey; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.server.MinecraftServer; 12 | import net.minecraft.world.level.block.Block; 13 | import net.minecraft.world.level.block.state.BlockState; 14 | import net.minecraft.world.level.block.state.StateDefinition; 15 | import net.minecraft.world.level.block.state.properties.Property; 16 | 17 | public class v1_20_R3 extends NMS{ 18 | 19 | @Override 20 | public List getAvailableBlockProperties(Material material) { 21 | RegistryLookup blockRegistry = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK); 22 | Reference block = blockRegistry 23 | .getOrThrow(ResourceKey.create(Registries.BLOCK, new ResourceLocation(material.getKey().getKey()))); 24 | StateDefinition stateList = block.value().getStateDefinition(); 25 | return stateList.getProperties().stream().map(Property::getName).toList(); 26 | } 27 | 28 | @Override 29 | public List getAvailableBlockTags() { 30 | return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BLOCK).listTags() 31 | .map(x -> Key.key(x.key().location().toString())).toList(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /api/src/test/java/fr/skytasul/quests/api/utils/ChatColorUtilsTest.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertArrayEquals; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.junit.jupiter.api.Disabled; 6 | import org.junit.jupiter.api.extension.ParameterContext; 7 | import org.junit.jupiter.params.ParameterizedTest; 8 | import org.junit.jupiter.params.aggregator.AggregateWith; 9 | import org.junit.jupiter.params.aggregator.ArgumentsAccessor; 10 | import org.junit.jupiter.params.aggregator.ArgumentsAggregationException; 11 | import org.junit.jupiter.params.aggregator.ArgumentsAggregator; 12 | import org.junit.jupiter.params.provider.CsvFileSource; 13 | import java.util.List; 14 | 15 | class ChatColorUtilsTest { 16 | 17 | @Disabled("The word wrapping code is broken and I've already lost too many hours on it") 18 | @ParameterizedTest 19 | @CsvFileSource(resources = "/word_wrap.csv", numLinesToSkip = 1) 20 | void test(String string, int line, int critical, @AggregateWith(VarargsAggregator.class) String... expected) { 21 | List<@NotNull String> wrapped = ChatColorUtils.wordWrap(string, line, critical); 22 | assertArrayEquals(expected, wrapped.toArray(new String[0])); 23 | } 24 | 25 | static class VarargsAggregator implements ArgumentsAggregator { 26 | @Override 27 | public Object aggregateArguments(ArgumentsAccessor accessor, ParameterContext context) 28 | throws ArgumentsAggregationException { 29 | return accessor.toList().stream() 30 | .skip(context.getIndex()) 31 | .map(String::valueOf) 32 | .toArray(String[]::new); 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /api/src/test/resources/word_wrap.csv: -------------------------------------------------------------------------------- 1 | string,line,critical,expected, 2 | "Hello there, it's me",12,15,"Hello there,",it's me 3 | "§aHello there, it's me", 12, 15, "§aHello there,", "§ait's me" 4 | "§aHello §cthere, it's me", 12, 16, "§aHello §cthere,", "§cit's me" 5 | "§aHello §cthere, it's me", 13, 17, "§aHello §cthere,", "§cit's me" 6 | "§aHello §lthere, it's me", 12, 16, "§aHello §lthere,", "§a§lit's me" 7 | "§aHello §c§lthere, it's me", 12, 16, "§aHello", "§c§lthere, it's", "§c§lme" 8 | "§aHello §c§a§o§c§lthere, it's me", 12, 16, "§aHello", "§c§lthere, it's", "§c§lme" 9 | "§aHello §x§1§1§1§1§1§2there, it's me", 12, 30, "§aHello §x§1§1§1§1§1§2there,", "§x§1§1§1§1§1§2it's me" 10 | "§aHello §x§1§1§1§1§1§2there, it's me", 12, 14, "§aHello there,", "it's me" 11 | "§aHello §x§1§1§1§1§1§2there, it's me", 12, 12, "§aHello", "§athere,", "it's me" 12 | "§aHello §x§1§1§1§1§1§2§lthere, it's me", 12, 30, "§aHello §x§1§1§1§1§1§2§lthere,", "§x§1§1§1§1§1§2§lit's me" 13 | "§aHello §x§1§1§1§1§1§2the§lre, it's me", 12, 30, "§aHello §x§1§1§1§1§1§2the§lre,", "§x§1§1§1§1§1§2§lit's me" 14 | "§aHello §x§1§1§1§1§1§2there, §lit's me, owo §ofellas §nowo", 26, 100, "§aHello §x§1§1§1§1§1§2there, §lit's me, owo", "§x§1§1§1§1§1§2§l§ofellas §nowo" 15 | "1 §x§B§B§E§E§D§DHello there, §lhow are you, fellow §ostranger§x§B§B§E§E§D§D?", 40, 100, "1 §x§B§B§E§E§D§DHello there, §lhow are you, fellow", "§x§B§B§E§E§D§D§l§ostranger§x§B§B§E§E§D§D?" 16 | "§aHello, thisisaverylongword and thisisa§lverylongword", 10, 25, "§aHello,", "§athisisaver", "§aylongword", "§aand", "§athisisa§lv", "§a§lerylongwor", "§a§ld" 17 | "§bVery_much_§along_word_§dwith_colors_§cinside_and_useless_words_after", 20, 50, "idk" 18 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/editor/SelectNPC.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.editor; 2 | 3 | import fr.skytasul.quests.api.QuestsPlugin; 4 | import fr.skytasul.quests.api.editors.InventoryClear; 5 | import fr.skytasul.quests.api.localization.Lang; 6 | import fr.skytasul.quests.api.npcs.BqNpc; 7 | import fr.skytasul.quests.api.utils.messaging.MessageType.DefaultMessageType; 8 | import fr.skytasul.quests.api.utils.messaging.MessageUtils; 9 | import fr.skytasul.quests.npcs.BQNPCClickEvent; 10 | import fr.skytasul.quests.utils.QuestUtils; 11 | import org.bukkit.entity.Player; 12 | import org.bukkit.event.EventHandler; 13 | import org.bukkit.event.EventPriority; 14 | import org.bukkit.event.Listener; 15 | import java.util.function.Consumer; 16 | 17 | public class SelectNPC extends InventoryClear implements Listener { 18 | 19 | private Consumer run; 20 | 21 | public SelectNPC(Player p, Runnable cancel, Consumer end) { 22 | super(p, cancel); 23 | this.run = end; 24 | } 25 | 26 | @EventHandler (priority = EventPriority.LOW) 27 | private void onNPCClick(BQNPCClickEvent e) { 28 | if (e.getPlayer() != player) return; 29 | e.setCancelled(true); 30 | stop(); 31 | run.accept(e.getNPC()); 32 | } 33 | 34 | @Override 35 | public void begin(){ 36 | super.begin(); 37 | if (!QuestsPlugin.getPlugin().getNpcManager().isEnabled()) { 38 | MessageUtils.sendMessage(player, "§cWARNING: No NPC plugin registered.\nLeft editor.", 39 | DefaultMessageType.PREFIXED); 40 | QuestUtils.runSync(this::cancel); 41 | return; 42 | } 43 | 44 | Lang.NPC_EDITOR_ENTER.send(player); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/requirements/LevelRequirement.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.requirements; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import fr.skytasul.quests.api.requirements.AbstractRequirement; 5 | import fr.skytasul.quests.api.requirements.TargetNumberRequirement; 6 | import fr.skytasul.quests.api.utils.ComparisonMethod; 7 | import org.bukkit.entity.Player; 8 | 9 | public class LevelRequirement extends TargetNumberRequirement { 10 | 11 | public LevelRequirement() { 12 | this(null, null, 0, ComparisonMethod.GREATER_OR_EQUAL); 13 | } 14 | 15 | public LevelRequirement(String customDescription, String customReason, double target, ComparisonMethod comparison) { 16 | super(customDescription, customReason, target, comparison); 17 | } 18 | 19 | @Override 20 | public double getPlayerTarget(Player p) { 21 | return p.getLevel(); 22 | } 23 | 24 | @Override 25 | protected String getDefaultReason(Player player) { 26 | return Lang.REQUIREMENT_LEVEL.format(this); 27 | } 28 | 29 | @Override 30 | public Class numberClass() { 31 | return Integer.class; 32 | } 33 | 34 | @Override 35 | public void sendHelpString(Player p) { 36 | Lang.CHOOSE_XP_REQUIRED.send(p); 37 | } 38 | 39 | @Override 40 | protected String getPlaceholderName() { 41 | return "level"; 42 | } 43 | 44 | @Override 45 | public String getDefaultDescription(Player p) { 46 | return Lang.RDLevel.format(this); 47 | } 48 | 49 | @Override 50 | public AbstractRequirement clone() { 51 | return new LevelRequirement(getCustomDescription(), getCustomReason(), target, comparison); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/editors/WaitBlockClick.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.editors; 2 | 3 | import java.util.function.Consumer; 4 | import org.bukkit.Location; 5 | import org.bukkit.entity.Player; 6 | import org.bukkit.event.EventHandler; 7 | import org.bukkit.event.Listener; 8 | import org.bukkit.event.block.Action; 9 | import org.bukkit.event.player.PlayerInteractEvent; 10 | import org.bukkit.inventory.ItemStack; 11 | import fr.skytasul.quests.api.QuestsPlugin; 12 | 13 | public class WaitBlockClick extends InventoryClear implements Listener { 14 | 15 | private Consumer run; 16 | private ItemStack item; 17 | 18 | public WaitBlockClick(Player p, Runnable cancel, Consumer end, ItemStack is) { 19 | super(p, cancel); 20 | this.run = end; 21 | this.item = is; 22 | } 23 | 24 | @EventHandler 25 | public void onClick(PlayerInteractEvent e){ 26 | if (e.getPlayer() != player) return; 27 | if (QuestsPlugin.getPlugin().getGuiManager().getItemFactory().getCancel().equals(e.getItem())) { 28 | cancel(); 29 | return; 30 | } 31 | if (e.getAction() != Action.RIGHT_CLICK_BLOCK) return; 32 | if (e.getClickedBlock() == null) return; 33 | if (!item.equals(e.getItem())) return; 34 | e.setCancelled(true); 35 | stop(); 36 | run.accept(e.getClickedBlock().getLocation()); 37 | } 38 | 39 | @Override 40 | public void begin(){ 41 | super.begin(); 42 | player.getInventory().setItem(4, item); 43 | player.getInventory().setHeldItemSlot(4); 44 | if (cancel != null) 45 | player.getInventory().setItem(8, QuestsPlugin.getPlugin().getGuiManager().getItemFactory().getCancel()); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/IntegrationsConfiguration.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations; 2 | 3 | import fr.skytasul.quests.api.QuestsPlugin; 4 | import org.bukkit.configuration.file.FileConfiguration; 5 | 6 | public class IntegrationsConfiguration { 7 | 8 | private final FileConfiguration config; 9 | 10 | private String dSetName = "Quests"; 11 | private String dIcon = "bookshelf"; 12 | private int dMinZoom = 0; 13 | private boolean mythicMobsPetKillToOwner = true; 14 | 15 | public IntegrationsConfiguration(FileConfiguration config) { 16 | this.config = config; 17 | } 18 | 19 | public void load() { 20 | if (config.getBoolean("skillAPIoverride", false)) { 21 | config.set("skillAPIoverride", null); 22 | QuestsPlugin.getPlugin().getLogger().warning("The config option \"skillAPIoverride\" is no longer supported." 23 | + " You must change your vanilla XP rewards to specialized SkillAPI XP rewards."); 24 | } 25 | 26 | dSetName = config.getString("dynmap.markerSetName"); 27 | dIcon = config.getString("dynmap.markerIcon"); 28 | dMinZoom = config.getInt("dynmap.minZoom"); 29 | mythicMobsPetKillToOwner = config.getBoolean("mythicmobs.count kill for pet owner"); 30 | } 31 | 32 | public String dynmapSetName() { 33 | return dSetName; 34 | } 35 | 36 | public String dynmapMarkerIcon() { 37 | return dIcon; 38 | } 39 | 40 | public int dynmapMinimumZoom() { 41 | return dMinZoom; 42 | } 43 | 44 | public boolean mythicMobsPetKillToOwner() { 45 | return mythicMobsPetKillToOwner; 46 | } 47 | 48 | public static IntegrationsConfiguration getConfiguration() { 49 | return IntegrationsLoader.getInstance().getConfig(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/rewards/RewardGiveContext.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.rewards; 2 | 3 | import fr.skytasul.quests.api.questers.Quester; 4 | import org.bukkit.entity.Player; 5 | import org.jetbrains.annotations.NotNull; 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public class RewardGiveContext { 12 | 13 | private final @NotNull Quester quester; 14 | 15 | private boolean interrupBranch; 16 | private Map> earnings = new HashMap<>(); 17 | 18 | public RewardGiveContext(@NotNull Quester quester) { 19 | this.quester = quester; 20 | } 21 | 22 | public @NotNull Quester getQuester() { 23 | return quester; 24 | } 25 | 26 | public boolean isBranchInterrupted() { 27 | return interrupBranch; 28 | } 29 | 30 | public void interruptBranch() { 31 | this.interrupBranch = true; 32 | } 33 | 34 | public @NotNull Map> getEarnings() { 35 | return earnings; 36 | } 37 | 38 | public void addEarning(@NotNull Player player, @NotNull AbstractReward reward) { 39 | earnings.computeIfAbsent(player, __ -> new ArrayList<>()).add(reward.getDescription(player)); 40 | } 41 | 42 | public void addEarning(@NotNull Player player, @NotNull String reward) { 43 | earnings.computeIfAbsent(player, __ -> new ArrayList<>()).add(reward); 44 | } 45 | 46 | public void addEarning(@NotNull AbstractReward reward) { 47 | for (var player : quester.getOnlinePlayers()) 48 | addEarning(player, reward); 49 | } 50 | 51 | public void addEarning(@NotNull String reward) { 52 | for (var player : quester.getOnlinePlayers()) 53 | addEarning(player, reward); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/templates/StaticPagedGUI.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui.templates; 2 | 3 | import java.util.Map; 4 | import java.util.Map.Entry; 5 | import java.util.function.Consumer; 6 | import java.util.function.Function; 7 | import org.bukkit.DyeColor; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.event.inventory.ClickType; 10 | import org.bukkit.inventory.ItemStack; 11 | import fr.skytasul.quests.api.gui.close.CloseBehavior; 12 | import fr.skytasul.quests.api.gui.close.DelayCloseBehavior; 13 | import fr.skytasul.quests.api.gui.close.StandardCloseBehavior; 14 | 15 | public class StaticPagedGUI extends PagedGUI> { 16 | 17 | protected final Consumer clicked; 18 | private boolean cancelAllowed = false; 19 | 20 | public StaticPagedGUI(String name, DyeColor color, Map objects, Consumer clicked, Function nameMapper) { 21 | super(name, color, objects.entrySet(), null, nameMapper == null ? null : entry -> nameMapper.apply(entry.getKey())); 22 | this.clicked = clicked; 23 | } 24 | 25 | public StaticPagedGUI allowCancel() { 26 | cancelAllowed = true; 27 | return this; 28 | } 29 | 30 | @Override 31 | public ItemStack getItemStack(Entry object) { 32 | return object.getValue(); 33 | } 34 | 35 | @Override 36 | public void click(Entry existing, ItemStack item, ClickType clickType) { 37 | clicked.accept(existing.getKey()); 38 | } 39 | 40 | @Override 41 | public CloseBehavior onClose(Player player) { 42 | if (cancelAllowed) { 43 | return new DelayCloseBehavior(() -> clicked.accept(null)); 44 | }else { 45 | return StandardCloseBehavior.REOPEN; 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/gui/DefaultItemFactory.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.gui; 2 | 3 | import static fr.skytasul.quests.api.gui.ItemUtils.addEnchant; 4 | import static fr.skytasul.quests.api.gui.ItemUtils.item; 5 | import static fr.skytasul.quests.api.gui.ItemUtils.name; 6 | import com.cryptomorin.xseries.XEnchantment; 7 | import com.cryptomorin.xseries.XMaterial; 8 | import fr.skytasul.quests.api.QuestsConfiguration; 9 | import fr.skytasul.quests.api.gui.ItemFactory; 10 | import fr.skytasul.quests.api.localization.Lang; 11 | import net.md_5.bungee.api.ChatColor; 12 | import org.bukkit.inventory.ItemStack; 13 | import org.jetbrains.annotations.NotNull; 14 | 15 | public class DefaultItemFactory implements ItemFactory { 16 | 17 | @Override 18 | public @NotNull ItemStack getPreviousPage() { 19 | return name(QuestsConfiguration.getConfig().getGuiConfig().getPreviousPageItem().clone(), 20 | Lang.laterPage.toString()); 21 | } 22 | 23 | @Override 24 | public @NotNull ItemStack getNextPage() { 25 | return name(QuestsConfiguration.getConfig().getGuiConfig().getNextPageItem().clone(), 26 | Lang.nextPage.toString()); 27 | } 28 | 29 | @Override 30 | public @NotNull ItemStack getCancel() { 31 | return item(XMaterial.BARRIER, Lang.cancel.toString()); 32 | } 33 | 34 | @Override 35 | public @NotNull ItemStack getDone() { 36 | return addEnchant(item(XMaterial.DIAMOND, Lang.done.toString()), XEnchantment.UNBREAKING.getEnchant(), 0); 37 | } 38 | 39 | @Override 40 | public @NotNull ItemStack getNotDone() { 41 | return item(XMaterial.CHARCOAL, "§c§l§m" + ChatColor.stripColor(Lang.done.toString())); 42 | } 43 | 44 | @Override 45 | public @NotNull ItemStack getNone() { 46 | return item(XMaterial.BARRIER, "§cNone"); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/QuestsPlugin.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api; 2 | 3 | import fr.skytasul.quests.QuestsAPIProvider; 4 | import fr.skytasul.quests.api.commands.CommandsManager; 5 | import fr.skytasul.quests.api.editors.EditorManager; 6 | import fr.skytasul.quests.api.gui.GuiManager; 7 | import fr.skytasul.quests.api.npcs.BqNpcManager; 8 | import fr.skytasul.quests.api.players.PlayerManager; 9 | import fr.skytasul.quests.api.utils.IntegrationManager; 10 | import fr.skytasul.quests.api.utils.logger.LoggerExpanded; 11 | import net.kyori.adventure.platform.bukkit.BukkitAudiences; 12 | import org.bukkit.plugin.Plugin; 13 | import org.jetbrains.annotations.NotNull; 14 | 15 | public interface QuestsPlugin extends Plugin { 16 | 17 | /** 18 | * Utility method to get the API object. 19 | * 20 | * @return the api object 21 | */ 22 | public @NotNull QuestsAPI getAPI(); 23 | 24 | public @NotNull CommandsManager getCommand(); 25 | 26 | public @NotNull QuestsConfiguration getConfiguration(); 27 | 28 | public @NotNull PlayerManager getPlayersManager(); 29 | 30 | public @NotNull LoggerExpanded getLoggerExpanded(); 31 | 32 | public @NotNull GuiManager getGuiManager(); 33 | 34 | public @NotNull EditorManager getEditorManager(); 35 | 36 | public @NotNull BqNpcManager getNpcManager(); 37 | 38 | public @NotNull IntegrationManager getIntegrationManager(); 39 | 40 | public void notifyLoadingFailure(); 41 | 42 | public @NotNull BukkitAudiences getAudiences(); 43 | 44 | public boolean isRunningPaper(); 45 | 46 | /** 47 | * Utility method to get the plugin object. 48 | * 49 | * @return the plugin object 50 | */ 51 | public static @NotNull QuestsPlugin getPlugin() { 52 | return QuestsAPIProvider.getAPI().getPlugin(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/fabled/FabledLevelRequirement.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations.fabled; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import fr.skytasul.quests.api.requirements.AbstractRequirement; 5 | import fr.skytasul.quests.api.requirements.TargetNumberRequirement; 6 | import fr.skytasul.quests.api.utils.ComparisonMethod; 7 | import org.bukkit.entity.Player; 8 | import studio.magemonkey.fabled.Fabled; 9 | 10 | public class FabledLevelRequirement extends TargetNumberRequirement { 11 | 12 | public FabledLevelRequirement() { 13 | this(null, null, 0, ComparisonMethod.GREATER_OR_EQUAL); 14 | } 15 | 16 | public FabledLevelRequirement(String customDescription, String customReason, double target, 17 | ComparisonMethod comparison) { 18 | super(customDescription, customReason, target, comparison); 19 | } 20 | 21 | @Override 22 | public double getPlayerTarget(Player p) { 23 | return Fabled.getData(p).getMainClass().getLevel(); 24 | } 25 | 26 | @Override 27 | protected String getPlaceholderName() { 28 | return "level"; 29 | } 30 | 31 | @Override 32 | protected String getDefaultReason(Player player) { 33 | return Lang.REQUIREMENT_LEVEL.format(this); 34 | } 35 | 36 | @Override 37 | public Class numberClass() { 38 | return Integer.class; 39 | } 40 | 41 | @Override 42 | public void sendHelpString(Player p) { 43 | Lang.CHOOSE_XP_REQUIRED.send(p); 44 | } 45 | 46 | @Override 47 | public String getDefaultDescription(Player p) { 48 | return Lang.RDLevel.format(this); 49 | } 50 | 51 | @Override 52 | public AbstractRequirement clone() { 53 | return new FabledLevelRequirement(getCustomDescription(), getCustomReason(), target, comparison); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /core/src/main/resources/scoreboard.yml: -------------------------------------------------------------------------------- 1 | # Configuration relative to quests 2 | quests: 3 | # Time in seconds before the quest tracker switch 4 | changeTime: 10 5 | # If enabled and the player has no quest launched, the scoreboard will disappear 6 | # until the player starts a new quest 7 | hideIfEmpty: true 8 | # If enabled, scoreboard lines containing a {quest_xxx} placeholder 9 | # will be automatically refreshed whenever the quest tracker is updated 10 | refreshLines: true 11 | # If enabled, lines containing quest placeholders which relies on context 12 | # (such as {quest_time_left} in the expansion) that are not available for the 13 | # currently displayed quest will not be shown. 14 | hide unknown quest placeholders: false 15 | 16 | worlds: 17 | # List of worlds to filter 18 | filterList: [] 19 | # If true, the list above will be treated as an "allow list" and not a "block list" 20 | isAllowList: false 21 | 22 | # Automatically hide the scoreboard after this amount of seconds. 23 | # If set to -1, the scoreboard will never hide itself. 24 | auto hide: -1 25 | 26 | # Lines contained in the scoreboard 27 | # Available parameters are: 28 | # * value: the value of line, surrounded by quotes (') 29 | # -> special placeholders: {quest_name}, {quest_advancement}, {quest_description} 30 | # * refresh: time in seconds before the line is refreshed (useful with dynamic placeholders) 31 | # -> not needed for {quest_xxx} lines if the "refreshLines" setting is set to true 32 | # * length: max length of the line, if the number of characters exceed this limit the line will be split 33 | lines: 34 | - value: '' 35 | - value: '§6{quest_name}' 36 | - value: '' 37 | - value: '{quest_advancement}' 38 | length: 30 39 | - value: '' 40 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/AbstractMapIntegration.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api; 2 | 3 | import org.bukkit.Location; 4 | import fr.skytasul.quests.api.npcs.BqNpc; 5 | import fr.skytasul.quests.api.quests.Quest; 6 | import fr.skytasul.quests.api.utils.QuestVisibilityLocation; 7 | 8 | public abstract class AbstractMapIntegration implements QuestsHandler { 9 | 10 | @Override 11 | public final void load() { 12 | if (isEnabled()) 13 | initializeMarkers(this::initializeQuests); 14 | } 15 | 16 | private void initializeQuests() { 17 | QuestsAPI.getAPI().getQuestsManager().getQuests().forEach(this::questLoaded); 18 | } 19 | 20 | @Override 21 | public void questLoaded(Quest quest) { 22 | if (!isEnabled()) 23 | return; 24 | 25 | BqNpc starter = quest.getStarterNpc(); 26 | if (starter == null) 27 | return; 28 | if (quest.isHidden(QuestVisibilityLocation.MAPS)) { 29 | QuestsPlugin.getPlugin().getLoggerExpanded().debug("No marker created for quest " + quest.getId() + ": quest is hidden"); 30 | return; 31 | } 32 | 33 | Location lc = starter.getLocation(); 34 | if (lc == null) { 35 | QuestsPlugin.getPlugin().getLoggerExpanded().warning("Cannot create map marker for quest #" + quest.getId() + " (" + quest.getName() + ")"); 36 | }else { 37 | addMarker(quest, lc); 38 | } 39 | } 40 | 41 | @Override 42 | public void questUnload(Quest quest) { 43 | if (!quest.isHidden(QuestVisibilityLocation.MAPS) && quest.getStarterNpc() != null) 44 | removeMarker(quest); 45 | } 46 | 47 | public abstract boolean isEnabled(); 48 | 49 | protected abstract void initializeMarkers(Runnable initializeQuests); 50 | 51 | protected abstract void addMarker(Quest quest, Location lc); 52 | 53 | protected abstract void removeMarker(Quest quest); 54 | 55 | } 56 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/templates/ConfirmGUI.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui.templates; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | import org.bukkit.event.inventory.InventoryType; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | import com.cryptomorin.xseries.XMaterial; 9 | import fr.skytasul.quests.api.gui.AbstractGui; 10 | import fr.skytasul.quests.api.gui.close.StandardCloseBehavior; 11 | import fr.skytasul.quests.api.gui.layout.LayoutedButton; 12 | import fr.skytasul.quests.api.gui.layout.LayoutedClickHandler; 13 | import fr.skytasul.quests.api.gui.layout.LayoutedGUI; 14 | import fr.skytasul.quests.api.localization.Lang; 15 | 16 | public final class ConfirmGUI { 17 | 18 | private ConfirmGUI() {} 19 | 20 | public static AbstractGui confirm(@Nullable Runnable yes, @Nullable Runnable no, @NotNull String indication, 21 | @Nullable List<@Nullable String> lore) { 22 | return LayoutedGUI.newBuilder() 23 | .addButton(1, 24 | LayoutedButton.create(XMaterial.LIME_DYE, Lang.confirmYes.toString(), Collections.emptyList(), event -> { 25 | event.close(); 26 | if (yes != null) 27 | yes.run(); 28 | })) 29 | .addButton(3, 30 | LayoutedButton.create(XMaterial.RED_DYE, Lang.confirmNo.toString(), Collections.emptyList(), event -> { 31 | event.close(); 32 | if (no != null) 33 | no.run(); 34 | })) 35 | .addButton(2, LayoutedButton.create(XMaterial.PAPER, indication, lore, LayoutedClickHandler.EMPTY)) 36 | .setInventoryType(InventoryType.HOPPER) 37 | .setName(Lang.INVENTORY_CONFIRM.toString()) 38 | .setCloseBehavior(StandardCloseBehavior.REOPEN) 39 | .build(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/vault/permission/PermissionListGUI.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations.vault.permission; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.gui.ItemUtils; 5 | import fr.skytasul.quests.api.gui.templates.ListGUI; 6 | import fr.skytasul.quests.api.localization.Lang; 7 | import org.bukkit.DyeColor; 8 | import org.bukkit.event.inventory.ClickType; 9 | import org.bukkit.inventory.ItemStack; 10 | import java.util.List; 11 | import java.util.function.Consumer; 12 | import java.util.function.Function; 13 | 14 | public class PermissionListGUI extends ListGUI { 15 | 16 | private Consumer> end; 17 | 18 | public PermissionListGUI(List list, Consumer> end) { 19 | super(Lang.INVENTORY_PERMISSION_LIST.toString(), DyeColor.PURPLE, list); 20 | this.end = end; 21 | } 22 | 23 | @Override 24 | public ItemStack getObjectItemStack(Permission object) { 25 | return ItemUtils.item(XMaterial.PAPER, "§e" + object.permission, createLoreBuilder(object) 26 | .addDescription(Lang.permRemoved.format(object)) 27 | .addDescription(Lang.permWorld.format(object)).toLoreArray()); 28 | } 29 | 30 | @Override 31 | public void createObject(Function callback) { 32 | new PermissionGUI(perm -> { 33 | callback.apply(perm); 34 | }, null).open(player); 35 | } 36 | 37 | @Override 38 | public void clickObject(Permission object, ItemStack item, ClickType clickType) { 39 | new PermissionGUI(perm -> { 40 | updateObject(object, perm); 41 | reopen(); 42 | }, object).open(player); 43 | } 44 | 45 | @Override 46 | public void finish(List objects) { 47 | end.accept(objects); 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/options/OptionRepeatable.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.options; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import fr.skytasul.quests.api.options.QuestOptionBoolean; 5 | import fr.skytasul.quests.api.options.description.QuestDescriptionContext; 6 | import fr.skytasul.quests.api.options.description.QuestDescriptionProvider; 7 | import fr.skytasul.quests.api.utils.PlayerListCategory; 8 | import fr.skytasul.quests.structure.QuestImplementation; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class OptionRepeatable extends QuestOptionBoolean implements QuestDescriptionProvider { 13 | 14 | @Override 15 | public String getName() { 16 | return Lang.multiple.toString(); 17 | } 18 | 19 | @Override 20 | public String getDescription() { 21 | return Lang.multipleLore.toString(); 22 | } 23 | 24 | @Override 25 | public List provideDescription(QuestDescriptionContext context) { 26 | if (context.getCategory() != PlayerListCategory.FINISHED) return null; 27 | 28 | List lore = new ArrayList<>(4); 29 | QuestImplementation quest = (QuestImplementation) context.getQuest(); 30 | if (quest.testTimer(context.getQuester(), false)) { 31 | lore.add(Lang.canRedo.toString()); 32 | }else { 33 | lore.add(Lang.timeWait.quickFormat("time_left", quest.getTimeLeft(context.getQuester()))); 34 | } 35 | lore.add(null); 36 | lore.add(Lang.timesFinished.quickFormat("times_finished", 37 | context.getQuestDatas().map(x -> x.getTimesFinished()).orElse(0))); 38 | return lore; 39 | } 40 | 41 | @Override 42 | public String getDescriptionId() { 43 | return "repeatable"; 44 | } 45 | 46 | @Override 47 | public double getDescriptionPriority() { 48 | return 100; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/vault/permission/Permission.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations.vault.permission; 2 | 3 | import fr.skytasul.quests.api.localization.Lang; 4 | import fr.skytasul.quests.api.utils.messaging.HasPlaceholders; 5 | import fr.skytasul.quests.api.utils.messaging.MessageUtils; 6 | import fr.skytasul.quests.api.utils.messaging.PlaceholderRegistry; 7 | import fr.skytasul.quests.integrations.vault.Vault; 8 | import org.bukkit.entity.Player; 9 | import org.jetbrains.annotations.NotNull; 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | public class Permission implements Cloneable, HasPlaceholders { 14 | 15 | public final String permission, world; 16 | public final boolean take; 17 | 18 | public Permission(String permission, boolean take, String world) { 19 | this.permission = permission; 20 | this.take = take; 21 | this.world = world; 22 | } 23 | 24 | public void give(Player p) { 25 | Vault.changePermission(p, permission, take, world); 26 | } 27 | 28 | @Override 29 | public @NotNull PlaceholderRegistry getPlaceholdersRegistry() { 30 | return PlaceholderRegistry.of("permission", permission, "permission_removed", MessageUtils.getYesNo(take), 31 | "permission_world", world == null ? Lang.worldGlobal.toString() : world); 32 | } 33 | 34 | public Map serialize() { 35 | Map map = new HashMap<>(); 36 | 37 | map.put("perm", permission); 38 | if (take) map.put("take", take); 39 | if (world != null) map.put("world", world); 40 | 41 | return map; 42 | } 43 | 44 | public static Permission deserialize(Map map) { 45 | return new Permission((String) map.get("perm"), map.containsKey("take") ? (boolean) map.get("take") : false, (String) map.get("world")); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/AbstractGui.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui; 2 | 3 | import com.cryptomorin.xseries.inventory.XInventoryView; 4 | import fr.skytasul.quests.api.gui.close.CloseBehavior; 5 | import fr.skytasul.quests.api.gui.close.StandardCloseBehavior; 6 | import org.bukkit.entity.Player; 7 | import org.bukkit.inventory.Inventory; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.jetbrains.annotations.Nullable; 10 | 11 | public abstract class AbstractGui implements Gui { 12 | 13 | private @Nullable Inventory inventory; 14 | 15 | @Override 16 | public @Nullable Inventory getInventory() { 17 | return inventory; 18 | } 19 | 20 | @Override 21 | public final void showInternal(Player player) { 22 | if (inventory == null) { 23 | inventory = instanciate(player); 24 | populate(player, inventory); 25 | } else { 26 | refresh(player, inventory); 27 | } 28 | inventory = XInventoryView.of(player.openInventory(inventory)).getTopInventory(); 29 | } 30 | 31 | @Override 32 | public final void reopen(@NotNull Player player, boolean refresh) { 33 | if (refresh) 34 | inventory = null; 35 | open(player); 36 | } 37 | 38 | public final void repopulate(@NotNull Player player) { 39 | if (inventory == null) 40 | inventory = instanciate(player); 41 | else 42 | inventory.clear(); 43 | 44 | populate(player, inventory); 45 | } 46 | 47 | protected abstract Inventory instanciate(@NotNull Player player); 48 | 49 | protected abstract void populate(@NotNull Player player, @NotNull Inventory inventory); 50 | 51 | protected void refresh(@NotNull Player player, @NotNull Inventory inventory) {} 52 | 53 | @Override 54 | public @NotNull CloseBehavior onClose(@NotNull Player player) { 55 | return StandardCloseBehavior.CONFIRM; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /integrations/src/main/java/fr/skytasul/quests/integrations/mcmmo/McCombatLevelRequirement.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.integrations.mcmmo; 2 | 3 | import com.gmail.mrphpfan.mccombatlevel.McCombatLevel; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | import fr.skytasul.quests.api.requirements.AbstractRequirement; 6 | import fr.skytasul.quests.api.requirements.TargetNumberRequirement; 7 | import fr.skytasul.quests.api.utils.ComparisonMethod; 8 | import org.bukkit.entity.Player; 9 | 10 | public class McCombatLevelRequirement extends TargetNumberRequirement { 11 | 12 | public McCombatLevelRequirement(){ 13 | this(null, null, 0, ComparisonMethod.GREATER_OR_EQUAL); 14 | } 15 | 16 | public McCombatLevelRequirement(String customDescription, String customReason, double target, 17 | ComparisonMethod comparison) { 18 | super(customDescription, customReason, target, comparison); 19 | } 20 | 21 | @Override 22 | public double getPlayerTarget(Player p) { 23 | return McCombatLevel.getPlugin(McCombatLevel.class).getLevel(p).orElse(0); 24 | } 25 | 26 | @Override 27 | protected String getPlaceholderName() { 28 | return "level"; 29 | } 30 | 31 | @Override 32 | protected String getDefaultReason(Player player) { 33 | return Lang.REQUIREMENT_COMBAT_LEVEL.format(this); 34 | } 35 | 36 | @Override 37 | public String getDefaultDescription(Player p) { 38 | return Lang.RDCombatLevel.format(this); 39 | } 40 | 41 | @Override 42 | public Class numberClass() { 43 | return Integer.class; 44 | } 45 | 46 | @Override 47 | public void sendHelpString(Player p) { 48 | Lang.CHOOSE_XP_REQUIRED.send(p); 49 | } 50 | 51 | @Override 52 | public AbstractRequirement clone() { 53 | return new McCombatLevelRequirement(getCustomDescription(), getCustomReason(), target, comparison); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/utils/PlayerListCategory.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.utils; 2 | 3 | import com.cryptomorin.xseries.XMaterial; 4 | import fr.skytasul.quests.api.QuestsConfiguration; 5 | import fr.skytasul.quests.api.localization.Lang; 6 | import fr.skytasul.quests.api.localization.Locale; 7 | import org.bukkit.DyeColor; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.jetbrains.annotations.NotNull; 10 | import org.jetbrains.annotations.Nullable; 11 | 12 | public enum PlayerListCategory { 13 | 14 | FINISHED( 15 | 1, 16 | Lang.finisheds), 17 | IN_PROGRESS( 18 | 2, 19 | Lang.inProgress), 20 | NOT_STARTED( 21 | 3, 22 | Lang.notStarteds); 23 | 24 | private final int slot; 25 | private final @NotNull Locale name; 26 | private @NotNull ItemStack icon = XMaterial.BARRIER.parseItem(); 27 | private @Nullable DyeColor color = DyeColor.RED; 28 | 29 | private PlayerListCategory(int slot, @NotNull Locale name) { 30 | this.slot = slot; 31 | this.name = name; 32 | } 33 | 34 | public int getSlot() { 35 | return slot; 36 | } 37 | 38 | public @NotNull String getName() { 39 | return name.getValue(); 40 | } 41 | 42 | public @NotNull ItemStack getIcon() { 43 | return icon; 44 | } 45 | 46 | public void setIcon(@NotNull ItemStack icon) { 47 | this.icon = icon; 48 | } 49 | 50 | public @Nullable DyeColor getColor() { 51 | return color; 52 | } 53 | 54 | public void setColor(@NotNull DyeColor color) { 55 | this.color = color; 56 | } 57 | 58 | public boolean isEnabled() { 59 | return QuestsConfiguration.getConfig().getQuestsMenuConfig().getEnabledTabs().contains(this); 60 | } 61 | 62 | public static @Nullable PlayerListCategory fromString(@NotNull String name) { 63 | try { 64 | return PlayerListCategory.valueOf(name.toUpperCase()); 65 | }catch (IllegalArgumentException ex) {} 66 | return null; 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /core/src/main/java/fr/skytasul/quests/rewards/TitleReward.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.rewards; 2 | 3 | import fr.skytasul.quests.api.gui.LoreBuilder; 4 | import fr.skytasul.quests.api.objects.QuestObjectClickEvent; 5 | import fr.skytasul.quests.api.rewards.AbstractReward; 6 | import fr.skytasul.quests.api.rewards.RewardGiveContext; 7 | import fr.skytasul.quests.gui.misc.TitleGUI; 8 | import fr.skytasul.quests.utils.types.Title; 9 | import org.bukkit.configuration.ConfigurationSection; 10 | 11 | public class TitleReward extends AbstractReward { 12 | 13 | private Title title; 14 | 15 | public TitleReward() {} 16 | 17 | public TitleReward(String customDescription, Title title) { 18 | super(customDescription); 19 | this.title = title; 20 | } 21 | 22 | @Override 23 | protected void addLore(LoreBuilder loreBuilder) { 24 | super.addLore(loreBuilder); 25 | loreBuilder.addDescriptionAsValue(title); 26 | } 27 | 28 | @Override 29 | public void itemClick(QuestObjectClickEvent event) { 30 | new TitleGUI(newTitle -> { 31 | if (newTitle == null) { 32 | event.cancel(); 33 | return; 34 | } 35 | 36 | title = newTitle; 37 | event.reopenGUI(); 38 | }).edit(title).open(event.getPlayer()); 39 | } 40 | 41 | @Override 42 | public void give(RewardGiveContext context) { 43 | if (title != null) 44 | title.send(context.getQuester()); 45 | } 46 | 47 | @Override 48 | public AbstractReward clone() { 49 | return new TitleReward(getCustomDescription(), title); 50 | } 51 | 52 | @Override 53 | public void save(ConfigurationSection section) { 54 | super.save(section); 55 | if (title != null) title.serialize(section.createSection("title")); 56 | } 57 | 58 | @Override 59 | public void load(ConfigurationSection section) { 60 | super.load(section); 61 | title = section.contains("title") ? Title.deserialize(section.getConfigurationSection("title")) : null; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/GuiClickEvent.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.inventory.ClickType; 6 | import org.bukkit.inventory.ItemStack; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public class GuiClickEvent { 11 | 12 | private final @NotNull Player player; 13 | private final @NotNull Gui gui; 14 | private final @Nullable ItemStack clicked; 15 | private final @Nullable ItemStack cursor; 16 | private final int slot; 17 | private final @NotNull ClickType click; 18 | 19 | private boolean cancelled = true; 20 | 21 | public GuiClickEvent(@NotNull Player player, @NotNull Gui gui, @Nullable ItemStack clicked, @Nullable ItemStack cursor, 22 | int slot, @NotNull ClickType click) { 23 | this.player = player; 24 | this.gui = gui; 25 | this.clicked = clicked; 26 | this.cursor = cursor; 27 | this.slot = slot; 28 | this.click = click; 29 | } 30 | 31 | public @NotNull Player getPlayer() { 32 | return player; 33 | } 34 | 35 | public @NotNull Gui getGui() { 36 | return gui; 37 | } 38 | 39 | public @Nullable ItemStack getClicked() { 40 | return clicked; 41 | } 42 | 43 | public @Nullable ItemStack getCursor() { 44 | return cursor; 45 | } 46 | 47 | public boolean hasCursor() { 48 | return cursor != null && cursor.getType() != Material.AIR; 49 | } 50 | 51 | public int getSlot() { 52 | return slot; 53 | } 54 | 55 | public @NotNull ClickType getClick() { 56 | return click; 57 | } 58 | 59 | public boolean isCancelled() { 60 | return cancelled; 61 | } 62 | 63 | public void setCancelled(boolean cancelled) { 64 | this.cancelled = cancelled; 65 | } 66 | 67 | public void reopen() { 68 | gui.reopen(player); 69 | } 70 | 71 | public void close() { 72 | gui.close(player); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/templates/ChooseGUI.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui.templates; 2 | 3 | import java.util.List; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.entity.Player; 6 | import org.bukkit.inventory.Inventory; 7 | import org.bukkit.inventory.ItemStack; 8 | import org.jetbrains.annotations.NotNull; 9 | import fr.skytasul.quests.api.gui.AbstractGui; 10 | import fr.skytasul.quests.api.gui.GuiClickEvent; 11 | import fr.skytasul.quests.api.gui.close.CloseBehavior; 12 | import fr.skytasul.quests.api.gui.close.StandardCloseBehavior; 13 | 14 | public abstract class ChooseGUI extends AbstractGui { 15 | 16 | private List available; 17 | 18 | protected ChooseGUI(List available) { 19 | this.available = available; 20 | } 21 | 22 | @Override 23 | protected Inventory instanciate(@NotNull Player player) { 24 | return Bukkit.createInventory(null, (int) Math.ceil(available.size() * 1.0 / 9.0) * 9, name()); 25 | } 26 | 27 | @Override 28 | protected void populate(@NotNull Player player, @NotNull Inventory inventory) { 29 | for (int i = 0; i < available.size(); i++) { 30 | inventory.setItem(i, getItemStack(available.get(i))); 31 | } 32 | } 33 | 34 | @Override 35 | public void onClick(GuiClickEvent event) { 36 | finish(available.get(event.getSlot())); 37 | } 38 | 39 | @Override 40 | public CloseBehavior onClose(Player player) { 41 | return StandardCloseBehavior.REOPEN; 42 | } 43 | 44 | /** 45 | * @return Inventory's name 46 | */ 47 | public abstract String name(); 48 | 49 | /** 50 | * @param object existing object to represent 51 | * @return ItemStack who represents the object 52 | */ 53 | 54 | public abstract ItemStack getItemStack(T object); 55 | 56 | /** 57 | * Called when the player click on an item 58 | */ 59 | public abstract void finish(T object); 60 | 61 | } 62 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/rewards/AbstractReward.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.rewards; 2 | 3 | import fr.skytasul.quests.api.QuestsAPI; 4 | import fr.skytasul.quests.api.localization.Lang; 5 | import fr.skytasul.quests.api.objects.QuestObject; 6 | import fr.skytasul.quests.api.objects.QuestObjectClickEvent; 7 | import fr.skytasul.quests.api.serializable.SerializableObject; 8 | import org.bukkit.entity.Player; 9 | import org.jetbrains.annotations.NotNull; 10 | import org.jetbrains.annotations.Nullable; 11 | import java.util.Map; 12 | 13 | public abstract class AbstractReward extends QuestObject { 14 | 15 | protected AbstractReward() { 16 | this(null); 17 | } 18 | 19 | protected AbstractReward(@Nullable String customDescription) { 20 | super(QuestsAPI.getAPI().getRewards(), customDescription); 21 | } 22 | 23 | @Override 24 | public @NotNull RewardCreator getCreator() { 25 | return (RewardCreator) super.getCreator(); 26 | } 27 | 28 | /** 29 | * Give the reward to the quester in the context 30 | * 31 | * @param context context of the reward giving 32 | */ 33 | public abstract void give(@NotNull RewardGiveContext context); 34 | 35 | @Override 36 | protected void sendCustomDescriptionHelpMessage(@NotNull Player p) { 37 | Lang.CHOOSE_REWARD_CUSTOM_DESCRIPTION.send(p); 38 | } 39 | 40 | @Override 41 | protected final void clickInternal(@NotNull QuestObjectClickEvent event) { 42 | itemClick(event); 43 | } 44 | 45 | protected abstract void itemClick(@NotNull QuestObjectClickEvent event); 46 | 47 | @Override 48 | public abstract @NotNull AbstractReward clone(); 49 | 50 | public static @NotNull AbstractReward deserialize(Map map) { 51 | return SerializableObject.deserialize(map, QuestsAPI.getAPI().getRewards()); 52 | } 53 | 54 | public boolean isAsync() { 55 | return false; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/comparison/ItemComparison.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.comparison; 2 | 3 | import java.util.function.BiPredicate; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public class ItemComparison { 8 | 9 | private final @NotNull String id, itemName, itemDescription; 10 | private final @NotNull BiPredicate<@NotNull ItemStack, @NotNull ItemStack> comparator; 11 | private boolean enabledByDefault, needsMeta, hasPriority; 12 | 13 | public ItemComparison(@NotNull String id, @NotNull String itemName, @NotNull String itemDescription, 14 | @NotNull BiPredicate<@NotNull ItemStack, @NotNull ItemStack> comparator) { 15 | this.id = id; 16 | this.itemName = itemName; 17 | this.itemDescription = itemDescription; 18 | this.comparator = comparator; 19 | } 20 | 21 | public String getID() { 22 | return id; 23 | } 24 | 25 | public String getItemName() { 26 | return itemName; 27 | } 28 | 29 | public String getItemDescription() { 30 | return itemDescription; 31 | } 32 | 33 | public ItemComparison setEnabledByDefault() { 34 | this.enabledByDefault = true; 35 | return this; 36 | } 37 | 38 | public boolean isEnabledByDefault() { 39 | return enabledByDefault; 40 | } 41 | 42 | public ItemComparison setMetaNeeded() { 43 | this.needsMeta = true; 44 | return this; 45 | } 46 | 47 | public boolean isMetaNeeded() { 48 | return needsMeta; 49 | } 50 | 51 | public ItemComparison setHasPriority() { 52 | this.hasPriority = true; 53 | return this; 54 | } 55 | 56 | public boolean hasPriority() { 57 | return hasPriority; 58 | } 59 | 60 | /** 61 | * This must not check the amount of the item. The function call must not affect the item in any way. 62 | */ 63 | public boolean isSimilar(@NotNull ItemStack item1, @NotNull ItemStack item2) { 64 | return comparator.test(item1, item2); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /api/src/main/java/fr/skytasul/quests/api/gui/Gui.java: -------------------------------------------------------------------------------- 1 | package fr.skytasul.quests.api.gui; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.inventory.Inventory; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | import fr.skytasul.quests.api.QuestsPlugin; 8 | import fr.skytasul.quests.api.gui.close.CloseBehavior; 9 | 10 | public interface Gui { 11 | 12 | /** 13 | * Gets the inventory for this Gui. 14 | * 15 | * @return the Bukkit inventory of this Gui, or null if it has not yet been built. 16 | */ 17 | @Nullable 18 | Inventory getInventory(); 19 | 20 | /** 21 | * Called internally when opening inventory 22 | * 23 | * @param p Player to open 24 | * @return inventory opened 25 | */ 26 | void showInternal(@NotNull Player player); 27 | 28 | /** 29 | * Opens the inventory to the player. Direct reference to 30 | * {@link GuiManager#open(Player, CustomInventory)} 31 | * 32 | * @param player Player 33 | * @see Inventories#create(Player, CustomInventory) 34 | */ 35 | default void open(@NotNull Player player) { 36 | QuestsPlugin.getPlugin().getGuiManager().open(player, this); 37 | } 38 | 39 | default void reopen(@NotNull Player player) { 40 | reopen(player, false); 41 | } 42 | 43 | void reopen(@NotNull Player player, boolean refresh); 44 | 45 | default void close(@NotNull Player player) { 46 | QuestsPlugin.getPlugin().getGuiManager().closeAndExit(player); 47 | } 48 | 49 | /** 50 | * Called when clicking on an item 51 | * 52 | * @param event object containing informations about click action 53 | */ 54 | void onClick(@NotNull GuiClickEvent event); 55 | 56 | /** 57 | * Called when closing the inventory 58 | * 59 | * @param player Player who has the inventory opened 60 | * @return behavior to have for this closing 61 | */ 62 | @NotNull 63 | CloseBehavior onClose(@NotNull Player player); 64 | 65 | } 66 | --------------------------------------------------------------------------------