diff --git a/src/main/java/com/alttd/altitudequests/AQuest.java b/src/main/java/com/alttd/altitudequests/AQuest.java index b0e7a64..1c466f5 100644 --- a/src/main/java/com/alttd/altitudequests/AQuest.java +++ b/src/main/java/com/alttd/altitudequests/AQuest.java @@ -5,6 +5,7 @@ import com.alttd.altitudequests.config.*; import com.alttd.altitudequests.events.*; import com.alttd.altitudequests.objects.Quest; import com.alttd.altitudequests.util.Logger; +import com.alttd.altitudequests.util.Utilities; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; @@ -35,7 +36,9 @@ public final class AQuest extends JavaPlugin { @Override public void onDisable() { - // Plugin shutdown logic + if (Config.DEBUG) + Logger.info("Syncing users."); + Quest.saveAll(); } public void reloadConfigs() { @@ -56,6 +59,7 @@ public final class AQuest extends JavaPlugin { getServer().getMessenger().registerIncomingPluginChannel(this, "aquest:player-data", new PluginMessageListener()); } + private static int yearDay = Utilities.getYearDay(); private void scheduleTasks() { new BukkitRunnable() { @Override @@ -64,6 +68,17 @@ public final class AQuest extends JavaPlugin { Logger.info("Syncing users."); Quest.saveAll(); } - }.runTaskTimerAsynchronously(getInstance(), 10 * 60 * 20L, 10 * 60 * 20L); + }.runTaskTimerAsynchronously(getInstance(), 10 * 60 * 20L, 10 * 60 * 20L); //every 10 minutes + + new BukkitRunnable() { + @Override + public void run() { + int tmp = Utilities.getYearDay(); + if (tmp == yearDay) + return; + yearDay = tmp; + Quest.resetQuests(); + } + }.runTaskTimerAsynchronously(getInstance(), 100, 100); //every 5 seconds } } diff --git a/src/main/java/com/alttd/altitudequests/commands/CommandManager.java b/src/main/java/com/alttd/altitudequests/commands/CommandManager.java index 6bc7388..51978a1 100644 --- a/src/main/java/com/alttd/altitudequests/commands/CommandManager.java +++ b/src/main/java/com/alttd/altitudequests/commands/CommandManager.java @@ -33,7 +33,8 @@ public class CommandManager implements CommandExecutor, TabExecutor { new CommandReload(AQuest.getInstance()), new CommandCreateScruff(), new CommandChangeQuest(), - new CommandTurnIn()); + new CommandTurnIn(), + new CommandSetQuest()); } @Override @@ -58,6 +59,7 @@ public class CommandManager implements CommandExecutor, TabExecutor { if (args.length <= 1) { res.addAll(subCommands.stream() + .filter(SubCommand::shouldTabComplete) .filter(subCommand -> commandSender.hasPermission(subCommand.getPermission())) .map(SubCommand::getName) .filter(name -> args.length == 0 || name.startsWith(args[0])) diff --git a/src/main/java/com/alttd/altitudequests/commands/subcommands/CommandSetQuest.java b/src/main/java/com/alttd/altitudequests/commands/subcommands/CommandSetQuest.java new file mode 100644 index 0000000..6da4d58 --- /dev/null +++ b/src/main/java/com/alttd/altitudequests/commands/subcommands/CommandSetQuest.java @@ -0,0 +1,61 @@ +package com.alttd.altitudequests.commands.subcommands; + +import com.alttd.altitudequests.commands.SubCommand; +import com.alttd.altitudequests.objects.Quest; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class CommandSetQuest extends SubCommand { + + @Override + public boolean onCommand(CommandSender commandSender, String[] args) { + if (args.length != 4) + return true;//TODO Error invalid length + Player player = Bukkit.getServer().getPlayer(args[1]); + if (player == null || !player.hasPlayedBefore()) + return true; //TODO error invalid player; + if (!Quest.loadDailyQuest(args[2], args[3], 0, 0, player.getUniqueId())) + commandSender.sendMiniMessage("Unable to create quest of variant .", + TagResolver.resolver(Placeholder.parsed("quest", args[2]), + Placeholder.parsed("variant", args[3]))); + commandSender.sendMiniMessage("Created quest of variant .", + TagResolver.resolver(Placeholder.parsed("quest", args[2]), + Placeholder.parsed("variant", args[3]))); + return true; + } + + @Override + public String getName() { + return "setquest"; + } + + @Override + public List getTabComplete(CommandSender commandSender, String[] args) { + List res = new ArrayList<>(); + switch (args.length) { + case 2 -> res.addAll(Bukkit.getServer().getOnlinePlayers().stream() + .map(Player::getName) + .collect(Collectors.toList())); + case 3 -> res.addAll(Quest.getTypes()); + case 4 -> res.add("enter quest type"); + } + return res; + } + + @Override + public String getHelpMessage() { + return "tmp help message"; //TODO fix + } + + @Override + public boolean shouldTabComplete() { + return true; + } +} diff --git a/src/main/java/com/alttd/altitudequests/commands/subcommands/CommandTurnIn.java b/src/main/java/com/alttd/altitudequests/commands/subcommands/CommandTurnIn.java index b08bee2..d917333 100644 --- a/src/main/java/com/alttd/altitudequests/commands/subcommands/CommandTurnIn.java +++ b/src/main/java/com/alttd/altitudequests/commands/subcommands/CommandTurnIn.java @@ -4,6 +4,7 @@ import com.alttd.altitudequests.commands.SubCommand; import com.alttd.altitudequests.config.Config; import com.alttd.altitudequests.config.LocalConfig; import com.alttd.altitudequests.objects.Quest; +import com.alttd.altitudequests.util.BookOpener; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -30,6 +31,7 @@ public class CommandTurnIn extends SubCommand { return true; } dailyQuest.turnIn(player); + BookOpener.openBook(player); return true; } diff --git a/src/main/java/com/alttd/altitudequests/config/Config.java b/src/main/java/com/alttd/altitudequests/config/Config.java index a2572be..cd1cc9e 100644 --- a/src/main/java/com/alttd/altitudequests/config/Config.java +++ b/src/main/java/com/alttd/altitudequests/config/Config.java @@ -28,7 +28,17 @@ public final class Config extends AbstractConfig { public static String QUEST_BOOK_AUTHOR = "Scruff"; public static String QUEST_BOOK_TITLE = "Quest Title"; - public static List QUEST_PAGES = List.of("Example"); + public static List QUEST_PAGES = List.of(""" + Hey + + Here is a quick summary of your quest progress so far! + * Quest: + * Variant: + * Items obtained: / + * Items turned in: / + + Click here to turn in more items + """); private static void loadBook() { QUEST_BOOK_AUTHOR = config.getString("book.author", QUEST_BOOK_AUTHOR); QUEST_BOOK_TITLE = config.getString("book.title", QUEST_BOOK_TITLE); @@ -37,9 +47,11 @@ public final class Config extends AbstractConfig { public static String TOO_FAR_FROM_NPC = "You are too far from Scruff";//TODO replace scruff with ? public static String DAILY_ALREADY_DONE = "You already completed your daily quest"; + public static String RESETTING_QUESTS = "[Mascot] Scruff: Thank you everyone that completed their daily quest! I will be handing out new ones now so come visit me at /spawn!"; private static void loadMessages() { TOO_FAR_FROM_NPC = config.getString("messages.too-far-from-npc", TOO_FAR_FROM_NPC); DAILY_ALREADY_DONE = config.getString("messages.daily-already-done", DAILY_ALREADY_DONE); + RESETTING_QUESTS = config.getString("messages.resetting-quests", RESETTING_QUESTS); } private static void loadGUIText() { diff --git a/src/main/java/com/alttd/altitudequests/config/QuestsConfig.java b/src/main/java/com/alttd/altitudequests/config/QuestsConfig.java index e929d3b..921a5f8 100644 --- a/src/main/java/com/alttd/altitudequests/config/QuestsConfig.java +++ b/src/main/java/com/alttd/altitudequests/config/QuestsConfig.java @@ -1,6 +1,6 @@ package com.alttd.altitudequests.config;; -import com.alttd.altitudequests.objects.MineQuestObject; +import com.alttd.altitudequests.objects.variants.MineQuestObject; import com.alttd.altitudequests.util.Logger; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -24,6 +24,7 @@ public class QuestsConfig extends AbstractConfig { } public static List MINE_QUESTS = new ArrayList<>(); + public static String MINE_QUEST_NAME = "Mine quest"; private static void loadMineQuests() { MINE_QUESTS.clear(); @@ -35,13 +36,13 @@ public class QuestsConfig extends AbstractConfig { Set keys = configurationSection.getKeys(false); for (String key : keys) { Material material = Material.valueOf(configurationSection.getString(key + ".material")); -//TODO maybe have pages for in progress and pages for done??? - List collect = configurationSection.getStringList(key + ".pages"); MINE_QUESTS.add(new MineQuestObject(key, configurationSection.getString(key + ".name"), material, configurationSection.getInt(key + ".amount"), - collect)); + configurationSection.getStringList(key + ".quest-pages"), + configurationSection.getStringList(key + ".done-pages"))); } + MINE_QUEST_NAME = config.getString("mining.name", MINE_QUEST_NAME); } } diff --git a/src/main/java/com/alttd/altitudequests/database/Database.java b/src/main/java/com/alttd/altitudequests/database/Database.java index 8cd946a..250bebf 100644 --- a/src/main/java/com/alttd/altitudequests/database/Database.java +++ b/src/main/java/com/alttd/altitudequests/database/Database.java @@ -91,6 +91,7 @@ public class Database { private static void createUserPointsTable() { try { String sql = "CREATE TABLE IF NOT EXISTS generic_quest_progress(" + + "year_day INT NOT NULL, " + "uuid VARCHAR(36) NOT NULL, " + "quest VARCHAR(36) NOT NULL, " + "quest_variant VARCHAR(36) NOT NULL, " + diff --git a/src/main/java/com/alttd/altitudequests/events/LogoutEvent.java b/src/main/java/com/alttd/altitudequests/events/LogoutEvent.java index 7161e5a..0caf485 100644 --- a/src/main/java/com/alttd/altitudequests/events/LogoutEvent.java +++ b/src/main/java/com/alttd/altitudequests/events/LogoutEvent.java @@ -24,9 +24,6 @@ public class LogoutEvent implements Listener { public void run() { if (Config.DEBUG) Logger.info("Syncing %", event.getPlayer().getName()); - Quest dailyQuest = Quest.getDailyQuest(uuid); - if (dailyQuest != null) - dailyQuest.save(); Quest.unloadUser(uuid); ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF("try-unlock"); diff --git a/src/main/java/com/alttd/altitudequests/events/PluginMessageListener.java b/src/main/java/com/alttd/altitudequests/events/PluginMessageListener.java index aeb878c..f80de2d 100644 --- a/src/main/java/com/alttd/altitudequests/events/PluginMessageListener.java +++ b/src/main/java/com/alttd/altitudequests/events/PluginMessageListener.java @@ -5,6 +5,7 @@ import com.alttd.altitudequests.config.Config; import com.alttd.altitudequests.database.Database; import com.alttd.altitudequests.objects.Quest; import com.alttd.altitudequests.util.Logger; +import com.alttd.altitudequests.util.Utilities; import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteStreams; import org.bukkit.Bukkit; @@ -70,7 +71,7 @@ public class PluginMessageListener implements org.bukkit.plugin.messaging.Plugin PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql); statement.setString(1, uuid.toString()); ResultSet resultSet = statement.executeQuery(); - if (resultSet.next()) { + if (resultSet.next() && resultSet.getInt("year_day") < Utilities.getYearDay()) { Quest.loadDailyQuest( resultSet.getString("quest"), resultSet.getString("quest_variant"), diff --git a/src/main/java/com/alttd/altitudequests/events/TalkToQuest.java b/src/main/java/com/alttd/altitudequests/events/TalkToQuest.java index b600eed..24409ef 100644 --- a/src/main/java/com/alttd/altitudequests/events/TalkToQuest.java +++ b/src/main/java/com/alttd/altitudequests/events/TalkToQuest.java @@ -1,14 +1,8 @@ package com.alttd.altitudequests.events; import com.alttd.altitudequests.AQuest; -import com.alttd.altitudequests.config.Config; import com.alttd.altitudequests.config.LocalConfig; -import com.alttd.altitudequests.objects.Quest; -import net.kyori.adventure.inventory.Book; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import com.alttd.altitudequests.util.BookOpener; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -17,15 +11,11 @@ import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.scheduler.BukkitRunnable; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; public class TalkToQuest implements Listener { - private static final MiniMessage miniMessage = MiniMessage.miniMessage(); - private static final Set inProcess = new HashSet<>(); @EventHandler(priority = EventPriority.HIGH) @@ -42,38 +32,11 @@ public class TalkToQuest implements Listener { new BukkitRunnable() { @Override public void run() { - player.openBook(getBook(event)); + BookOpener.openBook(player); inProcess.remove(uniqueId); } }.runTaskAsynchronously(AQuest.getInstance()); //TODO make it so everything can be done with commands and just don't let them tab complete and do them through the book instead //TODO in config allow a multitude of events to be prepared and randomly select from them at certain times of day? } - - private Book getBook (PlayerInteractEntityEvent event) { - Player player = event.getPlayer(); - - return Book.builder() - .author(miniMessage.deserialize(Config.QUEST_BOOK_AUTHOR)) - .title(miniMessage.deserialize(Config.QUEST_BOOK_TITLE)) - .pages(getPages(player)) - .build(); - } - - private static final Component error = MiniMessage.miniMessage().deserialize("Error retrieving quest data"); - private List getPages(Player player) { - Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId()); - if (dailyQuest == null) - return List.of(error); - TagResolver tagResolver = TagResolver.resolver( - TagResolver.resolver(Placeholder.component("player", player.name())), - TagResolver.resolver(Placeholder.parsed("br", "\n")), - dailyQuest.getTagResolvers() - ); - //TODO add weekly quest? - List pages = dailyQuest.getPages().stream() - .map(page -> miniMessage.deserialize(page, tagResolver)) - .collect(Collectors.toList()); - return (pages); - } } \ No newline at end of file diff --git a/src/main/java/com/alttd/altitudequests/objects/MineQuestObject.java b/src/main/java/com/alttd/altitudequests/objects/MineQuestObject.java deleted file mode 100644 index fc031f2..0000000 --- a/src/main/java/com/alttd/altitudequests/objects/MineQuestObject.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.alttd.altitudequests.objects; - -import org.bukkit.Material; - -import java.util.List; - -public class MineQuestObject { - - String internalName; - String name; - Material material; - int amount; - List pages; - - public MineQuestObject(String internalName, String name, Material material, int amount, List pages) { - this.internalName = internalName; - this.name = name; - this.material = material; - this.amount = amount; - this.pages = pages; - } - - public String getInternalName() { - return internalName; - } - - public String getName() { - return name; - } - - public Material getMaterial() { - return material; - } - - public int getAmount() { - return amount; - } - - public List getPages() { - return pages; - } -} diff --git a/src/main/java/com/alttd/altitudequests/objects/Quest.java b/src/main/java/com/alttd/altitudequests/objects/Quest.java index 2efcb2f..4d489f9 100644 --- a/src/main/java/com/alttd/altitudequests/objects/Quest.java +++ b/src/main/java/com/alttd/altitudequests/objects/Quest.java @@ -7,6 +7,8 @@ import com.alttd.altitudequests.util.Logger; import com.alttd.altitudequests.util.Utilities; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -15,6 +17,7 @@ import org.bukkit.scheduler.BukkitRunnable; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.*; +import java.util.stream.Collectors; public abstract class Quest { @@ -28,6 +31,20 @@ public abstract class Quest { possibleQuests.add(MineQuest.class); } + private final UUID uuid; + private int step1; + private int step2; + private final Variant variant; + private boolean isDone; + + public Quest(UUID uuid, int step1, int step2, Variant variant) { + this.uuid = uuid; + this.step1 = step1; + this.step2 = step2; + this.variant = variant; + this.isDone = false; + } + public static void createDailyQuest(Player player) { if (possibleQuests.size() == 0) { player.sendMiniMessage("Unable to create quest, no quests in config", null); @@ -76,17 +93,12 @@ public abstract class Quest { }.runTaskAsynchronously(AQuest.getInstance()); } - public static void unloadUser(UUID uuid) { + public static void unloadUser(UUID uuid) { //Pls only run async queriedUsers.remove(uuid); Quest quest = dailyQuests.remove(uuid); if (quest == null) return; - new BukkitRunnable() { - @Override - public void run() { - quest.save(); - } - }.runTaskAsynchronously(AQuest.getInstance()); + quest.save(); } public static void saveAll() { @@ -95,11 +107,11 @@ public abstract class Quest { } } - public static void loadDailyQuest(String quest, String quest_variant, int step_1_progress, int step_2_progress, UUID uuid) { + public static boolean loadDailyQuest(String quest, String quest_variant, int step_1_progress, int step_2_progress, UUID uuid) { Optional> any = possibleQuests.stream().filter(q -> q.getSimpleName().equals(quest)).findAny(); if (any.isEmpty()) { //TODO error - return; + return false; } Class aClass = any.get(); Constructor constructor; @@ -109,16 +121,93 @@ public abstract class Quest { dailyQuests.put(uuid, quest1); } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { e.printStackTrace(); + return false; } + return true; + } + + public static Collection getTypes() { + return possibleQuests.stream().map(Class::getSimpleName).collect(Collectors.toList()); + } + + public static void resetQuests() { + new BukkitRunnable() { + @Override + public void run() { + Bukkit.getServer().sendMessage(MiniMessage.miniMessage().deserialize(Config.RESETTING_QUESTS)); + dailyQuests.clear(); + for (Player player : Bukkit.getOnlinePlayers()) { + createDailyQuest(player); + } + } + }.runTaskAsynchronously(AQuest.getInstance()); } public abstract void save(); - public abstract boolean isDone(); - - public abstract List getPages(); - public abstract TagResolver getTagResolvers(); public abstract int turnIn(Player player); + + public abstract Component getDisplayName(); + + public List getQuestPages() { + return variant.getQuestPages(); + } + + public List getDonePages() { + return variant.getDonePages(); + } + + protected void checkDone() { + if (isDone()) + return; + if (getStep1() == variant.getAmount() && getStep2() == variant.getAmount()) { + setDone(true); + } + } + + public void checkDone(Player player) { + checkDone(); + if (!isDone) + return; + QuestCompleteEvent event = new QuestCompleteEvent(player, this, true); + event.callEvent(); + } + + public Variant getVariant() { + return variant; + } + + public UUID getUuid() { + return uuid; + } + + public int getStep1() { + return step1; + } + + public void addStep1(int step1) { + this.step1 += step1; + } + + public int getStep2() { + return step2; + } + + public void addStep2(int step2) { + this.step2 += step2; + } + + public void setDone(boolean done) { + isDone = done; + } + + public boolean isDone() { + return isDone; + } + + public int getMaxToTurnIn() { + return Math.min(variant.getAmount() - getStep2(), getStep1() - getStep2()); + } } diff --git a/src/main/java/com/alttd/altitudequests/objects/Variant.java b/src/main/java/com/alttd/altitudequests/objects/Variant.java new file mode 100644 index 0000000..0536097 --- /dev/null +++ b/src/main/java/com/alttd/altitudequests/objects/Variant.java @@ -0,0 +1,43 @@ +package com.alttd.altitudequests.objects; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; + +import java.util.List; + +public abstract class Variant { + + private final String internalName; + private final Component name; + private final int amount; + private final List questPages; + private final List donePages; + + public Variant(String internalName, String name, int amount, List questPages, List donePages) { + this.internalName = internalName; + this.name = MiniMessage.miniMessage().deserialize(name); + this.amount = amount; + this.questPages = questPages; + this.donePages = donePages; + } + + public String getInternalName() { + return internalName; + } + + public Component getName() { + return name; + } + + public int getAmount() { + return amount; + } + + public List getQuestPages() { + return questPages; + } + + public List getDonePages() { + return donePages; + } +} diff --git a/src/main/java/com/alttd/altitudequests/objects/quests/MineQuest.java b/src/main/java/com/alttd/altitudequests/objects/quests/MineQuest.java index 61306e4..f671eb8 100644 --- a/src/main/java/com/alttd/altitudequests/objects/quests/MineQuest.java +++ b/src/main/java/com/alttd/altitudequests/objects/quests/MineQuest.java @@ -1,12 +1,14 @@ package com.alttd.altitudequests.objects.quests; +import com.alttd.altitudequests.config.Config; import com.alttd.altitudequests.config.QuestsConfig; import com.alttd.altitudequests.database.Database; -import com.alttd.altitudequests.objects.MineQuestObject; +import com.alttd.altitudequests.objects.variants.MineQuestObject; import com.alttd.altitudequests.objects.Quest; -import com.alttd.altitudequests.objects.QuestCompleteEvent; import com.alttd.altitudequests.util.Logger; import com.alttd.altitudequests.util.Utilities; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.block.Block; @@ -19,83 +21,82 @@ import java.util.*; public class MineQuest extends Quest { - private final UUID uuid; - private int mined; - private int turnedIn; private final MineQuestObject mineQuestObject; - private boolean isDone = false; public MineQuest(UUID uuid) { - this.uuid = uuid; - mined = 0; - turnedIn = 0; - this.mineQuestObject = QuestsConfig.MINE_QUESTS.get(Utilities.randomOr0(QuestsConfig.MINE_QUESTS.size() - 1)); + super(uuid, 0, 0, + QuestsConfig.MINE_QUESTS.get(Utilities.randomOr0(QuestsConfig.MINE_QUESTS.size() - 1))); + if (getVariant() instanceof MineQuestObject mineQuestObject) + this.mineQuestObject = mineQuestObject; + else + this.mineQuestObject = null; + if (mineQuestObject == null) { + Logger.warning("Tried to create MineQuest but unable to find variant: %.", "unknown"); + return; //TODO error + } } - public MineQuest(String variantInternalName, int mined, int turnedIn, UUID uuid) { - this.mined = mined; - this.turnedIn = turnedIn; - this.uuid = uuid; - Optional any = QuestsConfig.MINE_QUESTS.stream().filter(object -> variantInternalName.equals(object.getInternalName())).findAny(); - if (any.isEmpty()) { + public MineQuest(String variantInternalName, int mined, int turnedIn, UUID uuid) { + super(uuid, mined, turnedIn, QuestsConfig.MINE_QUESTS.stream() + .filter(object -> variantInternalName.equals(object.getInternalName())) + .findAny().orElse(null)); + if (getVariant() instanceof MineQuestObject mineQuestObject) + this.mineQuestObject = mineQuestObject; + else this.mineQuestObject = null; + if (mineQuestObject == null) { Logger.warning("Tried to create MineQuest but unable to find variant: %.", variantInternalName); return; //TODO error } - this.mineQuestObject = any.get(); + checkDone(); } @Override public void save() { String sql = "INSERT INTO generic_quest_progress " + - "(uuid, quest, quest_variant, step_1_progress, step_2_progress) " + - "VALUES (?, ?, ?, ?, ?) " + + "(year_day, uuid, quest, quest_variant, step_1_progress, step_2_progress) " + + "VALUES (?, ?, ?, ?, ?, ?) " + "ON DUPLICATE KEY UPDATE " + - "quest = ?, quest_variant = ?, step_1_progress = ?, step_2_progress = ?"; + "quest = ?, quest_variant = ?, step_1_progress = ?, step_2_progress = ?, year_day = ?"; try { PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql); - statement.setString(1, uuid.toString()); - statement.setString(2, MineQuest.class.getSimpleName()); - statement.setString(3, mineQuestObject.getInternalName()); - statement.setInt(4, mined); - statement.setInt(5, turnedIn); - statement.setString(6, MineQuest.class.getSimpleName()); - statement.setString(7, mineQuestObject.getInternalName()); - statement.setInt(8, mined); - statement.setInt(9, turnedIn); + int yearDay = Utilities.getYearDay(); + if (Config.DEBUG) + Logger.info("Saving user for year day %.", String.valueOf(yearDay)); + statement.setInt(1, yearDay); + statement.setString(2, getUuid().toString()); + statement.setString(3, MineQuest.class.getSimpleName()); + statement.setString(4, mineQuestObject.getInternalName()); + statement.setInt(5, getStep1()); + statement.setInt(6, getStep2()); + statement.setString(7, MineQuest.class.getSimpleName()); + statement.setString(8, mineQuestObject.getInternalName()); + statement.setInt(9, getStep1()); + statement.setInt(10, getStep2()); + statement.setInt(11, yearDay); statement.execute(); } catch (SQLException exception) { exception.printStackTrace(); } } - @Override - public boolean isDone() { - return isDone; - } - - @Override - public List getPages() { - return mineQuestObject.getPages(); - } - @Override public TagResolver getTagResolvers() { return TagResolver.resolver( Placeholder.unparsed("block", mineQuestObject.getMaterial().name()), - Placeholder.parsed("mined", mined == mineQuestObject.getAmount() ? - "" + mined + "" : "" + mined + ""), - Placeholder.parsed("total_to_mine", String.valueOf(mineQuestObject.getAmount())), - Placeholder.parsed("turned_in", turnedIn == mineQuestObject.getAmount() ? - "" + turnedIn + "" : "" + turnedIn + ""), - Placeholder.parsed("total_to_turn_in", String.valueOf(mineQuestObject.getAmount())) + Placeholder.parsed("step_1_progress", getStep1() == mineQuestObject.getAmount() ? + "" + getStep1() + "" : "" + getStep1() + ""), + Placeholder.parsed("step_1_total", String.valueOf(mineQuestObject.getAmount())), + Placeholder.parsed("step_2_progress", getStep2() == mineQuestObject.getAmount() ? + "" + getStep2() + "" : "" + getStep2() + ""), + Placeholder.parsed("step_2_total", String.valueOf(mineQuestObject.getAmount())) ); } @Override public int turnIn(Player player) { PlayerInventory inventory = player.getInventory(); - int maxToTurnIn = Math.min(mineQuestObject.getAmount() - turnedIn, mined); + int maxToTurnIn = getMaxToTurnIn(); if (maxToTurnIn == 0) return 0; @@ -118,22 +119,20 @@ public class MineQuest extends Quest { } }); int totalTurnedIn = maxToTurnIn - ref.tmpAmount; - turnedIn += totalTurnedIn; + addStep2(totalTurnedIn); checkDone(player); return totalTurnedIn; } - public void mine(Block block) { - if (isDone || mined == mineQuestObject.getAmount() || !block.getType().equals(mineQuestObject.getMaterial())) - return; - mined += 1; + @Override + public Component getDisplayName() { + return MiniMessage.miniMessage().deserialize(QuestsConfig.MINE_QUEST_NAME); } - public void checkDone(Player player) { - if (turnedIn == mineQuestObject.getAmount() && mined == mineQuestObject.getAmount()) { - isDone = true; - QuestCompleteEvent event = new QuestCompleteEvent(player, this, true); - event.callEvent(); - } + public void mine(Block block) { + if (isDone() || !block.getType().equals(mineQuestObject.getMaterial())) + return; + addStep1(1); + checkDone(); } } diff --git a/src/main/java/com/alttd/altitudequests/objects/variants/MineQuestObject.java b/src/main/java/com/alttd/altitudequests/objects/variants/MineQuestObject.java new file mode 100644 index 0000000..9bdcf2f --- /dev/null +++ b/src/main/java/com/alttd/altitudequests/objects/variants/MineQuestObject.java @@ -0,0 +1,21 @@ +package com.alttd.altitudequests.objects.variants; + +import com.alttd.altitudequests.objects.Variant; +import org.bukkit.Material; + +import java.util.List; + +public class MineQuestObject extends Variant { + + private final Material material; + + public MineQuestObject(String internalName, String name, Material material, int amount, + List questPages, List donePages) { + super(internalName, name, amount, questPages, donePages); + this.material = material; + } + + public Material getMaterial() { + return material; + } +} diff --git a/src/main/java/com/alttd/altitudequests/util/BookOpener.java b/src/main/java/com/alttd/altitudequests/util/BookOpener.java new file mode 100644 index 0000000..89d6a98 --- /dev/null +++ b/src/main/java/com/alttd/altitudequests/util/BookOpener.java @@ -0,0 +1,53 @@ +package com.alttd.altitudequests.util; + +import com.alttd.altitudequests.config.Config; +import com.alttd.altitudequests.objects.Quest; +import net.kyori.adventure.inventory.Book; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class BookOpener { + + private static final MiniMessage miniMessage = MiniMessage.miniMessage(); + + public static void openBook(Player player) { + player.openBook(getBook(player)); + } + + private static Book getBook (Player player) { + return Book.builder() + .author(miniMessage.deserialize(Config.QUEST_BOOK_AUTHOR)) + .title(miniMessage.deserialize(Config.QUEST_BOOK_TITLE)) + .pages(getPages(player)) + .build(); + } + + private static final Component error = MiniMessage.miniMessage().deserialize("Error retrieving quest data"); + private static List getPages(Player player) { + Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId()); + if (dailyQuest == null) + return List.of(error); + TagResolver tagResolver = TagResolver.resolver( + TagResolver.resolver(Placeholder.component("player", player.name())), + TagResolver.resolver(Placeholder.component("quest", dailyQuest.getDisplayName())), + TagResolver.resolver(Placeholder.component("variant", dailyQuest.getVariant().getName())), + dailyQuest.getTagResolvers() + ); + //TODO add weekly quest? + List pages = new ArrayList<>(Config.QUEST_PAGES); + if (dailyQuest.isDone()) + pages.addAll(dailyQuest.getDonePages()); + else + pages.addAll(dailyQuest.getQuestPages()); + return (pages.stream() + .map(page -> miniMessage.deserialize(page, tagResolver)) + .collect(Collectors.toList())); + } +} diff --git a/src/main/java/com/alttd/altitudequests/util/Utilities.java b/src/main/java/com/alttd/altitudequests/util/Utilities.java index 95ceb44..d284f7a 100644 --- a/src/main/java/com/alttd/altitudequests/util/Utilities.java +++ b/src/main/java/com/alttd/altitudequests/util/Utilities.java @@ -1,5 +1,7 @@ package com.alttd.altitudequests.util; +import java.util.Calendar; +import java.util.Date; import java.util.Random; public class Utilities { @@ -13,4 +15,10 @@ public class Utilities { return 0; return new Random().nextInt(0, max - 1); } + + public static int getYearDay() { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + return (calendar.get(Calendar.YEAR) * 1000) + calendar.get(Calendar.DAY_OF_YEAR); + } }