Compare commits

...

19 Commits

Author SHA1 Message Date
stijn 379ba6d624 Merge pull request 'OnceABranch' (#1) from OnceABranch into master
Reviewed-on: #1
2024-04-13 18:03:03 +00:00
once_a_fairy 410a825681 Fixed upper case quest names breaking bossbars. 2023-09-20 09:22:14 +02:00
once_a_fairy 2409103b3e Minor changes for OtherQuests and a progress bar was added. 2023-09-19 19:32:56 +02:00
Teriuihi e93a922cc8 Attempting to fix thread issues, temporarily disabled them 2023-08-06 20:57:59 +02:00
Teriuihi b8114ba0d3 Added auto hiding bossbar 2023-08-06 20:07:12 +02:00
once_a_fairy 2b9d6c0160 Minor changes. 2023-08-06 14:53:36 +02:00
once_a_fairy e258644a20 Fixed some dumb mistakes for the progress book. 2023-08-05 17:35:19 +02:00
once_a_fairy 0a0c4ffb98 Tried to add a progress book which only shows the quest progress upon using a command. 2023-08-05 13:49:12 +02:00
once_a_fairy e85e79c801 Added support for raid quests. 2023-08-04 23:41:13 +02:00
once_a_fairy 8eb28ea5f6 Added support for Shearing and Bucket quests and fixed some minor things. 2023-08-04 22:44:06 +02:00
OnceAFairy e0d3251bc9
Delete .gradle directory 2023-07-16 16:28:42 +02:00
OnceAFairy 75c9e71e00
Delete .idea directory 2023-07-16 16:28:33 +02:00
OnceAFairy 48968e445f
Delete build directory 2023-07-16 16:28:20 +02:00
once_a_fairy 244ac818a3 Merge remote-tracking branch 'origin/OnceABranch' into OnceABranch 2023-07-16 16:26:29 +02:00
once_a_fairy 3df774c2b6 Added ItemCaught.java which I previously forgot to push. 2023-07-16 16:15:10 +02:00
OnceAFairy 5b0cb847c4
Delete build/classes/java/main/com/alttd/altitudequests/events directory 2023-07-16 16:13:10 +02:00
once_a_fairy 1aee415642 Added support for other quests.
Support for other quests of the fishing type was added.
2023-07-16 15:48:07 +02:00
once_a_fairy 5929582e71 Added support for other quests.
Support for other quests of the fishing type was added.
2023-07-13 13:38:29 +02:00
once_a_fairy 241dce0537 Added quest support for harvesting plants. 2023-07-10 17:33:48 +02:00
21 changed files with 641 additions and 62 deletions

View File

@ -4,6 +4,7 @@ import com.alttd.altitudequests.commands.CommandManager;
import com.alttd.altitudequests.config.*;
import com.alttd.altitudequests.events.*;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.util.AutoHideBossBar;
import com.alttd.altitudequests.util.Logger;
import com.alttd.altitudequests.util.Utilities;
import com.alttd.datalock.DataLockAPI;
@ -37,6 +38,7 @@ public final class AQuest extends JavaPlugin {
} else {
dataLockAPI.registerChannel("aquest:player-data");
}
AutoHideBossBar.initiate();
Logger.info("--------------------------------------------------");
Logger.info("AQuest started");
@ -69,6 +71,11 @@ public final class AQuest extends JavaPlugin {
getServer().getPluginManager().registerEvents(new EntityBreed(), this);
getServer().getPluginManager().registerEvents(new DonNotMessWithNPC(), this);
getServer().getPluginManager().registerEvents(new DataLock(), this);
getServer().getPluginManager().registerEvents(new ItemCaught(), this);
// getServer().getPluginManager().registerEvents(new PotionBrewingStarted(), this);
// getServer().getPluginManager().registerEvents(new PotionBrewingFinished(), this);
getServer().getPluginManager().registerEvents(new FinishedRaid(), this);
// getServer().getMessenger().registerOutgoingPluginChannel(this, "aquest:player-data");
// getServer().getMessenger().registerIncomingPluginChannel(this, "aquest:player-data", new PluginMessageListener());
}

View File

@ -35,7 +35,8 @@ public class CommandManager implements CommandExecutor, TabExecutor {
new CommandChangeQuest(),
new CommandTurnIn(),
new CommandSetQuest(),
new CommandGetReward());
new CommandGetReward(),
new CommandProgress());
}
@Override

View File

@ -1,15 +1,55 @@
package com.alttd.altitudequests.commands.subcommands;
import com.alttd.altitudequests.AQuest;
import com.alttd.altitudequests.commands.SubCommand;
import com.alttd.altitudequests.config.MessagesConfig;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.util.ProgressBookOpener;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class CommandProgress extends SubCommand {
//TODO show player current quest progress
private static final Set<UUID> inProcess = new HashSet<>();
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
return false;
if (!(commandSender instanceof Player player)) {
commandSender.sendMiniMessage(MessagesConfig.NO_CONSOLE, null);
return true;
}
if (player == null || !player.hasPlayedBefore()) {
commandSender.sendMiniMessage(getHelpMessage(), null);
return true;
}
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null) {
player.sendMiniMessage("<red>You have no active quests.</red>", null);
return true;
}
if (dailyQuest.isDone()) {
player.sendMiniMessage("<green>You already completed the daily quest.</green>", null);
return true;
}
final UUID uniqueId = player.getUniqueId();
if (inProcess.contains(uniqueId)) {
return true;
}
inProcess.add(uniqueId);
new BukkitRunnable() {
@Override
public void run() {
ProgressBookOpener.openProgressBook(player);
inProcess.remove(uniqueId);
}
}.runTaskAsynchronously(AQuest.getInstance());
return true;
}
@Override

View File

@ -4,10 +4,7 @@ import com.alttd.altitudequests.AQuest;
import com.alttd.altitudequests.commands.SubCommand;
import com.alttd.altitudequests.config.MessagesConfig;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.quests.BreedMobsQuest;
import com.alttd.altitudequests.objects.quests.CollectDropsQuest;
import com.alttd.altitudequests.objects.quests.KillMobsQuest;
import com.alttd.altitudequests.objects.quests.MineQuest;
import com.alttd.altitudequests.objects.quests.*;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
@ -17,8 +14,6 @@ import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;
public class CommandSetQuest extends SubCommand {
@ -68,6 +63,7 @@ public class CommandSetQuest extends SubCommand {
case "collectdropsquest" -> res.addAll(CollectDropsQuest.getSubTypes());
case "killmobsquest" -> res.addAll(KillMobsQuest.getSubTypes());
case "minequest" -> res.addAll(MineQuest.getSubTypes());
case "otherquest" -> res.addAll(OtherQuest.getSubTypes());
default -> res.add("invalid quest type");
}
}

View File

@ -1,10 +1,10 @@
package com.alttd.altitudequests.config;
import java.io.File;
import java.time.Duration;
import java.util.List;
public final class Config extends AbstractConfig {
static Config config;
static int version;
public Config() {
@ -21,6 +21,8 @@ public final class Config extends AbstractConfig {
public static String QUEST_BOOK_AUTHOR = "<magenta>Scruff</magenta>";
public static String QUEST_BOOK_TITLE = "<green>Quest Title</green>";
public static String PROGRESS_BOOK_AUTHOR = "<magenta>Scruff</magenta>";
public static String PROGRESS_BOOK_TITLE = "<green>Quest Title</green>";
public static List<String> QUEST_PAGES = List.of("""
<bold><gold>Hey <player></gold></bold>
@ -31,6 +33,16 @@ public final class Config extends AbstractConfig {
* <step_2>: <step_2_progress>/<step_2_total>
<click:run_command:/aquest turnin><turn_in_text></click>
""");
public static List<String> PROGRESS_PAGES = List.of("""
<bold><gold>Hey <player></gold></bold>
Your quest progress:
* Quest: <quest>
* Type: <variant>
* <step_1>: <step_1_progress>/<step_1_total>
* <step_2>: <step_2_progress>/<step_2_total>
""");
private static void loadBook() {
QUEST_BOOK_AUTHOR = config.getString("book.author", QUEST_BOOK_AUTHOR);
@ -38,21 +50,31 @@ public final class Config extends AbstractConfig {
QUEST_PAGES = config.getStringList("book.pages", QUEST_PAGES);
}
private static void loadProgressBook() {
PROGRESS_BOOK_AUTHOR = config.getString("progressBook.author", PROGRESS_BOOK_AUTHOR);
PROGRESS_BOOK_TITLE = config.getString("progressBook.title", PROGRESS_BOOK_TITLE);
PROGRESS_PAGES = config.getStringList("progressBook.pages", PROGRESS_PAGES);
}
public static String NPC_NAME = "<light_purple>Scruff</light_purple>";
public static boolean DEBUG = false;
public static Duration BOSS_BAR_AUTO_HIDE;
private static void loadSettings() {
NPC_NAME = config.getString("settings.npc-name", NPC_NAME);
DEBUG = config.getBoolean("settings.debug", DEBUG);
BOSS_BAR_AUTO_HIDE = Duration.ofSeconds(config.getInt("settings.boss-bar-auto-hide-seconds", 10));
}
public static int MINE_QUEST_FREQ = 1;
public static int KILL_QUEST_FREQ = 1;
public static int COLLECT_QUEST_FREQ = 1;
public static int BREED_QUEST_FREQ = 1;
public static int OTHER_QUEST_FRQ = 1;
private static void loadQuestTypeFrequency() {
MINE_QUEST_FREQ = config.getInt("quest-type-frequency.mine", MINE_QUEST_FREQ);
KILL_QUEST_FREQ = config.getInt("quest-type-frequency.kill", KILL_QUEST_FREQ);
COLLECT_QUEST_FREQ = config.getInt("quest-type-frequency.collect", COLLECT_QUEST_FREQ);
BREED_QUEST_FREQ = config.getInt("quest-type-frequency.breed", BREED_QUEST_FREQ);
OTHER_QUEST_FRQ = config.getInt("quest-type-frequency.other", OTHER_QUEST_FRQ);
}
}

View File

@ -4,6 +4,7 @@ import com.alttd.altitudequests.objects.variants.BreedMobsQuestObject;
import com.alttd.altitudequests.objects.variants.CollectDropsQuestObject;
import com.alttd.altitudequests.objects.variants.KillMobsQuestObject;
import com.alttd.altitudequests.objects.variants.MineQuestObject;
import com.alttd.altitudequests.objects.variants.OtherQuestObject;
import com.alttd.altitudequests.util.Logger;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@ -33,6 +34,8 @@ public class QuestsConfig extends AbstractConfig {
public static String MINE_STEP_2 = "Turned in";
public static String MINE_TURN_IN = "<gold>Click here to turn in your <block></gold>";
public static List<String> MINE_COMMANDS = List.of("broadcast <player> Finished their daily quest!");
public static Material material;
public static Material turnInMaterial;
private static void loadMineQuests() {
MINE_QUESTS.clear();
@ -44,10 +47,18 @@ public class QuestsConfig extends AbstractConfig {
Set<String> keys = configurationSection.getKeys(false);
for (String key : keys) {
try {
Material material = Material.valueOf(configurationSection.getString(key + ".material"));
material = Material.valueOf(configurationSection.getString(key + ".material"));
if (configurationSection.getString(key + ".turnInMaterial") == null) {
turnInMaterial = material;
}
else {
turnInMaterial = Material.valueOf(configurationSection.getString(key + ".turnInMaterial"));
}
MINE_QUESTS.add(new MineQuestObject(key,
configurationSection.getString(key + ".name"),
material,
turnInMaterial,
configurationSection.getStringList(key + ".quest-pages"),
configurationSection.getStringList(key + ".done-pages"),
configurationSection.getInt(key + ".amount-min"),
@ -144,6 +155,54 @@ public class QuestsConfig extends AbstractConfig {
COLLECT_DROPS_COMMANDS = config.getStringList("collect_drops.commands", COLLECT_DROPS_COMMANDS);
}
public static List<OtherQuestObject> OTHER_QUEST = new ArrayList<>();
public static String OTHER_QUEST_NAME = "<green>Other quest</green>";
public static String OTHER_TURN_IN = "<gold>Click here to turn in your <item></gold>";
public static List<String> OTHER_COMMANDS = List.of("broadcast <player> Finished their daily quest!");
public static Material item;
public static EntityType entityType;
private static void loadOtherQuests() {
OTHER_QUEST.clear();
ConfigurationSection configurationSection = config.getConfigurationSection("other.possible_tasks");
if (configurationSection == null) {
Logger.warning("No other quests in config");
return;
}
Set<String> keys = configurationSection.getKeys(false);
for (String key : keys) {
try {
item = Material.valueOf(configurationSection.getString(key + ".item"));
if (configurationSection.getString(key + ".mob") == null) {
entityType = null;
}
else {
entityType = EntityType.valueOf(configurationSection.getString(key + ".mob"));
}
OTHER_QUEST.add(new OtherQuestObject(key,
configurationSection.getString(key + ".name"),
configurationSection.getString(key + ".category"),
item,
entityType,
configurationSection.getStringList(key + ".quest-pages"),
configurationSection.getStringList(key + ".done-pages"),
configurationSection.getInt(key + ".amount-min"),
configurationSection.getInt(key + ".amount-max"),
configurationSection.getString(key + ".step-1"),
configurationSection.getString(key + ".step-2")));
if (Config.DEBUG)
Logger.info("Loaded Collect drops quest " + key);
}
catch (Exception e) {
e.printStackTrace();
}
}
OTHER_QUEST_NAME = config.getString("other.name", OTHER_QUEST_NAME);
OTHER_TURN_IN = config.getString("other.turn-in", OTHER_TURN_IN);
OTHER_COMMANDS = config.getStringList("other.commands", OTHER_COMMANDS);
}
public static List<BreedMobsQuestObject> BREED_MOB_QUEST = new ArrayList<>();
public static String BREED_MOB_QUEST_NAME = "<green>Breed mobs quest</green>";
public static String BREED_STEP_1 = "Bred";

View File

@ -2,27 +2,28 @@ package com.alttd.altitudequests.events;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.quests.CollectDropsQuest;
import com.alttd.altitudequests.objects.quests.OtherQuest;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerBucketFillEvent;
import org.bukkit.event.player.PlayerBucketEntityEvent;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public class EntityBucketed implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBucketFill(PlayerBucketFillEvent event) {
public void onBucketFill(PlayerBucketEntityEvent event) {
Player player = event.getPlayer();
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null || dailyQuest.isDone())
return;
if (dailyQuest instanceof CollectDropsQuest collectDropsQuest) {
ItemStack itemStack = event.getItemStack();
if (itemStack != null)
collectDropsQuest.collectDrops(List.of(itemStack));
if (dailyQuest instanceof OtherQuest otherQuest) {
ItemStack itemStack = event.getEntityBucket();
Entity entity = event.getEntity();
if (itemStack != null && entity != null)
otherQuest.bucket(itemStack, entity);
}
}

View File

@ -1,15 +1,13 @@
package com.alttd.altitudequests.events;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.quests.CollectDropsQuest;
import com.alttd.altitudequests.objects.quests.OtherQuest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerShearEntityEvent;
import java.util.List;
public class EntitySheared implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
@ -18,8 +16,8 @@ public class EntitySheared implements Listener {
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null || dailyQuest.isDone())
return;
if (dailyQuest instanceof CollectDropsQuest collectDropsQuest) {
collectDropsQuest.collectDrops(List.of(event.getItem()));
if (dailyQuest instanceof OtherQuest otherQuest) {
otherQuest.shear(event.getEntity());
}
}
}

View File

@ -0,0 +1,30 @@
package com.alttd.altitudequests.events;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.quests.OtherQuest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.raid.RaidFinishEvent;
import java.util.List;
import java.util.UUID;
public class FinishedRaid implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onRaidFinish(RaidFinishEvent event) {
List<Player> winners = event.getWinners();
for (Player player : winners) {
UUID uuid = player.getUniqueId();
Quest dailyQuest = Quest.getDailyQuest(uuid);
if (dailyQuest == null || dailyQuest.isDone()) {
return;
}
if (dailyQuest instanceof OtherQuest otherQuest) {
otherQuest.raid();
}
}
}
}

View File

@ -0,0 +1,32 @@
package com.alttd.altitudequests.events;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.quests.OtherQuest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack;
public class ItemCaught implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onItemCaught(PlayerFishEvent event) {
if (event.getCaught() == null || event.getCaught().getType() != EntityType.DROPPED_ITEM) {
return; //Only if an item was caught do further processing. Otherwise error might come up later
}
Player player = event.getPlayer();
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null || dailyQuest.isDone()) {
return;
}
if (dailyQuest instanceof OtherQuest otherQuest) {
Item item = (Item) event.getCaught();
ItemStack caughtItem = item.getItemStack();
otherQuest.fish(caughtItem);
}
}
}

View File

@ -22,5 +22,4 @@ public class MineBlocks implements Listener {
if (quest instanceof MineQuest mineQuest)
mineQuest.mine(event.getBlock());
}
}

View File

@ -4,12 +4,11 @@ import com.alttd.altitudequests.AQuest;
import com.alttd.altitudequests.config.Config;
import com.alttd.altitudequests.config.MessagesConfig;
import com.alttd.altitudequests.database.Database;
import com.alttd.altitudequests.objects.quests.BreedMobsQuest;
import com.alttd.altitudequests.objects.quests.CollectDropsQuest;
import com.alttd.altitudequests.objects.quests.KillMobsQuest;
import com.alttd.altitudequests.objects.quests.MineQuest;
import com.alttd.altitudequests.objects.quests.*;
import com.alttd.altitudequests.util.Logger;
import com.alttd.altitudequests.util.Utilities;
import com.alttd.altitudequests.util.AutoHideBossBar;
import org.bukkit.boss.BarColor;
import com.alttd.datalock.DataLockAPI;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
@ -17,7 +16,6 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.PreparedStatement;
@ -29,7 +27,7 @@ import java.util.stream.Collectors;
public abstract class Quest {
private static final HashMap<UUID, Quest> dailyQuests = new HashMap<>();
// private static Quest weeklyQuest = null;
// private static Quest weeklyQuest = null;
private static final List<Class<? extends Quest>> possibleQuests = new ArrayList<>();
static { // maybe make this make more sense idk
@ -41,6 +39,8 @@ public abstract class Quest {
possibleQuests.add(CollectDropsQuest.class);
for (int i = 0; i < Config.BREED_QUEST_FREQ; i++)
possibleQuests.add(BreedMobsQuest.class);
for (int i = 0; i < Config.OTHER_QUEST_FRQ; i++)
possibleQuests.add(OtherQuest.class);
}
private final UUID uuid;
@ -50,6 +50,8 @@ public abstract class Quest {
private boolean isDone;
private boolean rewardReceived;
private final int amount;
private final AutoHideBossBar barProgressOne;
private final AutoHideBossBar barProgressTwo;
public static synchronized void putDailyQuest(UUID uuid, Quest quest) {
dailyQuests.put(uuid, quest);
@ -75,8 +77,8 @@ public abstract class Quest {
dailyQuests.clear();
}
public Quest(UUID uuid, int step1, int step2, Variant variant, int amount, boolean rewardReceived) {
this.uuid = uuid;
public Quest(Player player, int step1, int step2, Variant variant, int amount, boolean rewardReceived) throws Exception {
this.uuid = player.getUniqueId();
this.step1 = step1;
this.step2 = step2;
this.variant = variant;
@ -84,11 +86,14 @@ public abstract class Quest {
this.rewardReceived = rewardReceived;
if (variant == null) {
Logger.warning("Created % quest without a variant for %", this.getClass().getName(), uuid.toString());
throw new Exception("Invalid variant");
}
if (variant != null && amount == -1)
if (amount == -1)
this.amount = variant.calculateAmount(loadQuestsDoneThisMonth(uuid));
else
this.amount = amount;
this.barProgressOne = new AutoHideBossBar(player, variant, "1", "Step One Progress", BarColor.GREEN);
this.barProgressTwo = new AutoHideBossBar(player, variant, "2", "Step Two Progress", BarColor.PURPLE);
}
private int loadQuestsDoneThisMonth(UUID uuid) {
@ -117,12 +122,17 @@ public abstract class Quest {
Class<? extends Quest> questClass = possibleQuests.get(Utilities.randomOr0(possibleQuests.size() - 1));
try {
Constructor<? extends Quest> constructor = questClass.getDeclaredConstructor(UUID.class);
putDailyQuest(player.getUniqueId(), constructor.newInstance(player.getUniqueId()));
} catch (InvocationTargetException | IllegalAccessException | InstantiationException | NoSuchMethodException e) {
Constructor<? extends Quest> constructor = questClass.getDeclaredConstructor(Player.class);
putDailyQuest(player.getUniqueId(), constructor.newInstance(player));
} catch (InvocationTargetException | IllegalAccessException | InstantiationException |
NoSuchMethodException e) {
player.sendMiniMessage("<red>Unable to create quest, contact an admin</red>", null);
e.printStackTrace();
Logger.severe("% does not have a constructor with a UUID input or has improper access.", questClass.getName());
Logger.severe("% does not have a constructor with a Player input or has improper access.", questClass.getName());
} catch (Exception e) {
player.sendMiniMessage("<red>Unable to create quest, contact an admin</red>", null);
e.printStackTrace();
Logger.severe("% could not be created due to invalid namespace key or variant.", questClass.getName());
}
}
@ -130,7 +140,7 @@ public abstract class Quest {
// Quest.weeklyQuest = newQuest;
// }
// private static final HashSet<UUID> queriedUsers = new HashSet<>();
// private static final HashSet<UUID> queriedUsers = new HashSet<>();
public static void tryLoadDailyQuest(UUID uuid) {
// if (queriedUsers.contains(uuid))
// return;
@ -172,6 +182,7 @@ public abstract class Quest {
Class<? extends Quest> aClass = any.get();
Constructor<? extends Quest> constructor;
try {
Player player = Bukkit.getPlayer(uuid);
if (Config.DEBUG) {
Logger.info("quest: %, uuid: %, step1: %, step2: %, variant: %, amount: %, turnedIn:%",
quest,
@ -182,10 +193,11 @@ public abstract class Quest {
String.valueOf(amount),
String.valueOf(turnedIn));
}
constructor = aClass.getConstructor(UUID.class, int.class, int.class, String.class, int.class, boolean.class);
Quest quest1 = constructor.newInstance(uuid, step_1_progress, step_2_progress, quest_variant, amount, turnedIn);
constructor = aClass.getConstructor(Player.class, int.class, int.class, String.class, int.class, boolean.class);
Quest quest1 = constructor.newInstance(player, step_1_progress, step_2_progress, quest_variant, amount, turnedIn);
putDailyQuest(uuid, quest1);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException |
InvocationTargetException e) {
e.printStackTrace();
return false;
}
@ -290,6 +302,7 @@ public abstract class Quest {
public void addStep1(int step1) {
this.step1 += step1;
barProgressOne.show(((double) getStep1()) / getAmount());
}
public int getStep2() {
@ -298,6 +311,7 @@ public abstract class Quest {
public void addStep2(int step2) {
this.step2 += step2;
barProgressTwo.show(((double) getStep2()) / getAmount());
}
public void setDone(boolean done) {

View File

@ -18,15 +18,14 @@ import org.bukkit.entity.Player;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
public class BreedMobsQuest extends Quest {
private final BreedMobsQuestObject breedMobsQuestObject;
public BreedMobsQuest(UUID uuid) {
super(uuid, 0, 0,
public BreedMobsQuest(Player player) throws Exception {
super(player, 0, 0,
QuestsConfig.BREED_MOB_QUEST.get(Utilities.randomOr0(QuestsConfig.BREED_MOB_QUEST.size() - 1)), -1, false);
if (getVariant() instanceof BreedMobsQuestObject breedMobsQuestObject)
this.breedMobsQuestObject = breedMobsQuestObject;
@ -38,8 +37,8 @@ public class BreedMobsQuest extends Quest {
}
}
public BreedMobsQuest(UUID uuid, int step1, int step2, String variant, int amount, boolean rewardReceived) {
super(uuid, step1, step2, QuestsConfig.BREED_MOB_QUEST.stream()
public BreedMobsQuest(Player player, int step1, int step2, String variant, int amount, boolean rewardReceived) throws Exception {
super(player, step1, step2, QuestsConfig.BREED_MOB_QUEST.stream()
.filter(object -> variant.equals(object.getInternalName()))
.findAny().orElse(null), amount, rewardReceived);
if (getVariant() instanceof BreedMobsQuestObject breedMobsQuestObject)

View File

@ -28,8 +28,8 @@ public class CollectDropsQuest extends Quest {
private final CollectDropsQuestObject collectDropsQuestObject;
public CollectDropsQuest(UUID uuid) {
super(uuid, 0, 0,
public CollectDropsQuest(Player player) throws Exception {
super(player, 0, 0,
QuestsConfig.COLLECT_DROPS_QUEST.get(Utilities.randomOr0(QuestsConfig.COLLECT_DROPS_QUEST.size() - 1)), -1, false);
if (getVariant() instanceof CollectDropsQuestObject collectDropsQuestObject)
this.collectDropsQuestObject = collectDropsQuestObject;
@ -41,8 +41,8 @@ public class CollectDropsQuest extends Quest {
}
}
public CollectDropsQuest(UUID uuid, int step1, int step2, String variant, int amount, boolean rewardReceived) {
super(uuid, step1, step2, QuestsConfig.COLLECT_DROPS_QUEST.stream()
public CollectDropsQuest(Player player, int step1, int step2, String variant, int amount, boolean rewardReceived) throws Exception {
super(player, step1, step2, QuestsConfig.COLLECT_DROPS_QUEST.stream()
.filter(object -> variant.equals(object.getInternalName()))
.findAny().orElse(null), amount, rewardReceived);
if (getVariant() instanceof CollectDropsQuestObject collectDropsQuestObject)

View File

@ -25,8 +25,8 @@ public class KillMobsQuest extends Quest {
private final KillMobsQuestObject killMobsQuestObject;
public KillMobsQuest(UUID uuid) {
super(uuid, 0, 0,
public KillMobsQuest(Player player) throws Exception {
super(player, 0, 0,
QuestsConfig.KILL_MOB_QUEST.get(Utilities.randomOr0(QuestsConfig.KILL_MOB_QUEST.size() - 1)), -1, false);
if (getVariant() instanceof KillMobsQuestObject killMobsQuestObject)
this.killMobsQuestObject = killMobsQuestObject;
@ -38,8 +38,8 @@ public class KillMobsQuest extends Quest {
}
}
public KillMobsQuest(UUID uuid, int step1, int step2, String variant, int amount, boolean rewardReceived) {
super(uuid, step1, step2, QuestsConfig.KILL_MOB_QUEST.stream()
public KillMobsQuest(Player player, int step1, int step2, String variant, int amount, boolean rewardReceived) throws Exception {
super(player, step1, step2, QuestsConfig.KILL_MOB_QUEST.stream()
.filter(object -> variant.equals(object.getInternalName()))
.findAny().orElse(null), amount, rewardReceived);
if (getVariant() instanceof KillMobsQuestObject killMobsQuestObject)

View File

@ -13,6 +13,8 @@ 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;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Ageable;
import org.bukkit.entity.Player;
import org.bukkit.inventory.PlayerInventory;
@ -25,8 +27,8 @@ public class MineQuest extends Quest {
private final MineQuestObject mineQuestObject;
public MineQuest(UUID uuid) {
super(uuid, 0, 0,
public MineQuest(Player player) throws Exception {
super(player, 0, 0,
QuestsConfig.MINE_QUESTS.get(Utilities.randomOr0(QuestsConfig.MINE_QUESTS.size() - 1)), -1, false);
if (getVariant() instanceof MineQuestObject mineQuestObject)
this.mineQuestObject = mineQuestObject;
@ -38,8 +40,8 @@ public class MineQuest extends Quest {
}
}
public MineQuest(UUID uuid, int mined, int turnedIn, String variant, int amount, boolean rewardReceived) {
super(uuid, mined, turnedIn, QuestsConfig.MINE_QUESTS.stream()
public MineQuest(Player player, int mined, int turnedIn, String variant, int amount, boolean rewardReceived) throws Exception {
super(player, mined, turnedIn, QuestsConfig.MINE_QUESTS.stream()
.filter(object -> variant.equals(object.getInternalName()))
.findAny().orElse(null), amount,
rewardReceived);
@ -91,7 +93,7 @@ public class MineQuest extends Quest {
@Override
public TagResolver getTagResolvers() {
TagResolver resolver = TagResolver.resolver(
Placeholder.unparsed("block", Utilities.formatName(mineQuestObject.getMaterial().name())),
Placeholder.unparsed("block", Utilities.formatName(mineQuestObject.getTurnInMaterial().name())),
Placeholder.parsed("step_1_progress", getStep1() == getAmount() ?
"<green>" + getStep1() + "</green>" : "<red>" + getStep1() + "</red>"),
Placeholder.parsed("step_1_total", String.valueOf(getAmount())),
@ -121,7 +123,7 @@ public class MineQuest extends Quest {
Arrays.stream(inventory.getContents())
.filter(Objects::nonNull)
.filter(itemStack -> itemStack.getType().equals(mineQuestObject.getMaterial()))
.filter(itemStack -> itemStack.getType().equals(mineQuestObject.getTurnInMaterial()))
.forEach(itemStack -> {
if (ref.tmpAmount == 0)
return;
@ -149,8 +151,23 @@ public class MineQuest extends Quest {
return QuestsConfig.MINE_COMMANDS;
}
public boolean checkBlock(Block block) {
BlockData blockData = block.getBlockData();
if (!block.getType().equals(mineQuestObject.getMaterial())) {
return true;
}
else if (blockData instanceof Ageable) {
Ageable ageable = (Ageable) blockData;
if (ageable.getAge() != ageable.getMaximumAge()) {
return true;
}
}
return false;
}
public void mine(Block block) {
if (isDone() || !block.getType().equals(mineQuestObject.getMaterial()) || getAmount() == getStep1())
if (isDone() || checkBlock(block) || getAmount() == getStep1())
return;
addStep1(1);
checkDone();

View File

@ -0,0 +1,218 @@
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.Quest;
import com.alttd.altitudequests.objects.Variant;
import com.alttd.altitudequests.objects.variants.OtherQuestObject;
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.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Sheep;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class OtherQuest extends Quest {
private final OtherQuestObject otherQuestObject;
public OtherQuest(Player player) throws Exception {
super(player, 0, 0,
QuestsConfig.OTHER_QUEST.get(Utilities.randomOr0(QuestsConfig.OTHER_QUEST.size() - 1)), -1, false);
if (getVariant() instanceof OtherQuestObject otherQuestObject)
this.otherQuestObject = otherQuestObject;
else
this.otherQuestObject = null;
if (otherQuestObject == null) {
Logger.warning("Tried to create OtherQuest but unable to find variant: %.", "unknown");
}
}
public OtherQuest(Player player, int step1, int step2, String variant, int amount, boolean rewardReceived) throws Exception {
super(player, step1, step2, QuestsConfig.OTHER_QUEST.stream()
.filter(object -> variant.equals(object.getInternalName()))
.findAny().orElse(null), amount, rewardReceived);
if (getVariant() instanceof OtherQuestObject otherQuestObject)
this.otherQuestObject = otherQuestObject;
else
this.otherQuestObject = null;
if (otherQuestObject == null) {
Logger.warning("Tried to create OtherQuest but unable to find variant: %.", variant);
Logger.warning("Possible variants: %", QuestsConfig.OTHER_QUEST.stream().map(Variant::getInternalName).collect(Collectors.joining(", ")));
return;
}
checkDone();
}
@Override
public void save() {
String sql = "INSERT INTO generic_quest_progress " +
"(year_day, uuid, quest, quest_variant, step_1_progress, step_2_progress, amount, reward_received) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE " +
"quest = ?, quest_variant = ?, step_1_progress = ?, step_2_progress = ?, year_day = ?, amount = ?, reward_received = ?";
try {
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
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, this.getClass().getSimpleName());
statement.setString(4, otherQuestObject.getInternalName());
statement.setInt(5, getStep1());
statement.setInt(6, getStep2());
statement.setInt(7, getAmount());
statement.setInt(8, isRewardReceived() ? 1 : 0);
statement.setString(9, this.getClass().getSimpleName());
statement.setString(10, otherQuestObject.getInternalName());
statement.setInt(11, getStep1());
statement.setInt(12, getStep2());
statement.setInt(13, yearDay);
statement.setInt(14, getAmount());
statement.setInt(15, isRewardReceived() ? 1 : 0);
statement.execute();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
@Override
public TagResolver getTagResolvers() {
TagResolver resolver = TagResolver.resolver(
Placeholder.unparsed("item", Utilities.formatName(otherQuestObject.getMaterial().name())),
Placeholder.parsed("step_1_progress", getStep1() == getAmount() ?
"<green>" + getStep1() + "</green>" : "<red>" + getStep1() + "</red>"),
Placeholder.parsed("step_1_total", String.valueOf(getAmount())),
Placeholder.parsed("step_2_progress", getStep2() == getAmount() ?
"<green>" + getStep2() + "</green>" : "<red>" + getStep2() + "</red>"),
Placeholder.parsed("step_2_total", String.valueOf(getAmount())),
Placeholder.unparsed("step_1", otherQuestObject.getStep1()),
Placeholder.unparsed("step_2", otherQuestObject.getStep2()),
Placeholder.unparsed("turn_in_text", QuestsConfig.OTHER_TURN_IN)
);
Component turnInText = MiniMessage.miniMessage().deserialize(QuestsConfig.OTHER_TURN_IN, resolver);
return TagResolver.resolver(
resolver,
Placeholder.component("turn_in_text", turnInText)
);
}
@Override
public int turnIn(Player player) {
PlayerInventory inventory = player.getInventory();
int maxToTurnIn = getMaxToTurnIn();
if (maxToTurnIn == 0)
return 0;
var ref = new Object() {
int tmpAmount = maxToTurnIn;
};
Arrays.stream(inventory.getContents())
.filter(Objects::nonNull)
.filter(itemStack -> itemStack.getType().equals(otherQuestObject.getMaterial()))
.forEach(itemStack -> {
if (ref.tmpAmount == 0)
return;
if (itemStack.getAmount() > ref.tmpAmount) {
itemStack.setAmount(itemStack.getAmount() - ref.tmpAmount);
ref.tmpAmount = 0;
} else {
ref.tmpAmount -= itemStack.getAmount();
itemStack.setAmount(0);
}
});
int totalTurnedIn = maxToTurnIn - ref.tmpAmount;
addStep2(totalTurnedIn);
checkDone(player);
return totalTurnedIn;
}
@Override
public Component getDisplayName() {
return MiniMessage.miniMessage().deserialize("<green>%s</green>".formatted(otherQuestObject.getCategory()));
}
@Override
public List<String> getRewardCommand() {
return QuestsConfig.COLLECT_DROPS_COMMANDS;
}
public void fish(ItemStack caughtItem) {
if (isDone() || !caughtItem.getType().equals(otherQuestObject.getMaterial()) || getAmount() == getStep1()|| !otherQuestObject.getCategory().equalsIgnoreCase("FISHING")) {
return;
}
addStep1(1);
checkDone();
}
public void shear(Entity entity) {
if (isDone() || !entity.getType().equals(otherQuestObject.getEntity()) || getAmount() == getStep1()|| !otherQuestObject.getCategory().equalsIgnoreCase("SHEARING")) {
return;
}
DyeColor color = getDyeColorFromItemStack(otherQuestObject.getMaterial());
if (entity instanceof Sheep sheep) {
if (sheep.getColor() != color) {
return;
}
}
addStep1(1);
checkDone();
}
public void bucket(ItemStack bucket, Entity entity) {
if (isDone() || !entity.getType().equals(otherQuestObject.getEntity()) || getAmount() == getStep1()|| !otherQuestObject.getCategory().equalsIgnoreCase("BUCKETING")) {
return;
}
addStep1(1);
checkDone();
}
public void raid() {
if (isDone() || getAmount() == getStep1() || !otherQuestObject.getCategory().equalsIgnoreCase("RAID")) { //without checking the category, other players who have otherQuests active will also have a step added
return;
}
addStep1(1);
checkDone();
}
//public void brewingStarted(ItemStack ingredient, Location brewingStandLocation){
// Logger.warning("Brewing Started");
//}
//public void brewingFinished(List <ItemStack> results, Location brewingStandLocation) {
// Logger.warning("Brewing Finished");
//}
public static List<String> getSubTypes() {
return QuestsConfig.OTHER_QUEST.stream().map(Variant::getInternalName).collect(Collectors.toList());
}
public static DyeColor getDyeColorFromItemStack(Material material) {
if (material != null && material.name().contains("_WOOL")) {
String colorName = material.name().replace("_WOOL", "");
try {
return DyeColor.valueOf(colorName);
} catch (IllegalArgumentException ignored) {
}
}
return null;
}
}

View File

@ -8,14 +8,19 @@ import java.util.List;
public class MineQuestObject extends Variant {
private final Material material;
private final Material turnInMaterial;
public MineQuestObject(String internalName, String name, Material material,
public MineQuestObject(String internalName, String name, Material material, Material turnInMaterial,
List<String> questPages, List<String> donePages, int min, int max) {
super(internalName, name, questPages, donePages, min, max);
this.material = material;
this.turnInMaterial = turnInMaterial;
}
public Material getMaterial() {
return material;
}
public Material getTurnInMaterial() {
return turnInMaterial;
}
}

View File

@ -0,0 +1,34 @@
package com.alttd.altitudequests.objects.variants;
import com.alttd.altitudequests.objects.Variant;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import java.util.List;
public class OtherQuestObject extends Variant {
private final Material material;
private final EntityType entity;
private final String step1;
private final String step2;
private final String category;
public OtherQuestObject(String internalName, String name, String category, Material item, EntityType entity,
List<String> questPages, List<String> donePages, int min, int max, String step1, String step2) {
super(internalName, name, questPages, donePages, min, max);
this.material = item;
this.entity = entity;
this.step1 = step1;
this.step2 = step2;
this.category = category;
}
public Material getMaterial() {
return material;
}
public EntityType getEntity() {return entity;}
public String getStep1() {return step1;}
public String getStep2() {return step2;}
public String getCategory() {return category;}
}

View File

@ -0,0 +1,58 @@
package com.alttd.altitudequests.util;
import com.alttd.altitudequests.AQuest;
import com.alttd.altitudequests.config.Config;
import com.alttd.altitudequests.objects.Variant;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.time.Instant;
import java.util.HashMap;
public class AutoHideBossBar {
private static final HashMap<BossBar, Instant> bossBars = new HashMap<>();
private final BossBar bossBar;
public AutoHideBossBar(Player player, Variant variant, String part, String title, BarColor barColor) throws Exception {
NamespacedKey namespacedKeyOne = NamespacedKey.fromString(player.getUniqueId() + variant.getInternalName().toLowerCase() + part, AQuest.getInstance());
if (namespacedKeyOne == null) {
Logger.warning("Unable to create nameSpacedKey with suffix % for quest for %", part, player.getName());
throw new Exception("Failed to create namespace key");
}
this.bossBar = Bukkit.createBossBar(
namespacedKeyOne,
title,
barColor,
BarStyle.SOLID);
bossBar.setVisible(false);
bossBar.addPlayer(player);
}
public void show(double progress) {
bossBar.setVisible(true);
bossBar.setProgress(progress);
bossBars.put(bossBar, Instant.now().plusSeconds(Config.BOSS_BAR_AUTO_HIDE.toSeconds()));
}
public static void initiate() {
new BukkitRunnable() {
@Override
public void run() {
for (HashMap.Entry<BossBar, Instant> entry : bossBars.entrySet()) {
if (Instant.now().isAfter(entry.getValue())) {
BossBar bossBar = entry.getKey();
bossBar.setVisible(false);
bossBars.remove(entry.getKey());
}
}
}
}.runTaskTimer(AQuest.getInstance(), 10, 10);
}
}

View File

@ -0,0 +1,49 @@
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 ProgressBookOpener {
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
public static void openProgressBook(Player player) {
player.openBook(getProgressBook(player));
}
private static Book getProgressBook (Player player) {
return Book.builder()
.author(miniMessage.deserialize(Config.PROGRESS_BOOK_AUTHOR))
.title(miniMessage.deserialize(Config.PROGRESS_BOOK_TITLE))
.pages(getPages(player))
.build();
}
private static final Component error = MiniMessage.miniMessage().deserialize("<red>Error retrieving quest data</red>");
private static List<Component> 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()
);
List<String> pages = new ArrayList<>();
pages.addAll(Config.PROGRESS_PAGES);
return (pages.stream()
.map(page -> miniMessage.deserialize(page, tagResolver))
.collect(Collectors.toList()));
}
}