diff --git a/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/AbstractTraitHandler.java b/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/AbstractTraitHandler.java index e5c22c4..c869b65 100644 --- a/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/AbstractTraitHandler.java +++ b/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/AbstractTraitHandler.java @@ -4,6 +4,7 @@ import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.npc.NPC; import net.knarcraft.dynmapcitizens.DynmapCitizens; import net.knarcraft.dynmapcitizens.settings.TraitSettings; +import net.knarcraft.dynmapcitizens.util.DynmapHelper; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -13,7 +14,6 @@ import org.dynmap.markers.MarkerIcon; import org.dynmap.markers.MarkerSet; import java.util.UUID; -import java.util.logging.Level; /** * An abstract class with useful code for all citizens-trait-handlers @@ -34,7 +34,7 @@ public abstract class AbstractTraitHandler implements CitizensTraitHandler { protected void initializeMarkerSet() { TraitSettings settings = getSettings(); DynmapAPI dynmapAPI = DynmapCitizens.getInstance().getDynmapAPI(); - markerSet = getMarkerSet(dynmapAPI, settings.getMarkerSetId(), settings.getMarkerSetName()); + markerSet = DynmapHelper.getMarkerSet(dynmapAPI, settings.getMarkerSetId(), settings.getMarkerSetName()); if (markerSet != null) { markerSet.setHideByDefault(settings.markersHiddenByDefault()); markerSet.setLayerPriority(settings.getMarkerSetPriority()); @@ -42,28 +42,6 @@ public abstract class AbstractTraitHandler implements CitizensTraitHandler { } } - /** - * Gets the given marker set (and creates it if necessary) - * - * @param dynmapAPI
A reference to dynmap's API
- * @param setIdThe id of the marker set to get
- * @param labelThe label of the marker set if creation is necessary
- * @returnThe marker set, or null if something went wrong
- */ - protected MarkerSet getMarkerSet(DynmapAPI dynmapAPI, String setId, String label) { - MarkerSet markerSet = dynmapAPI.getMarkerAPI().getMarkerSet(setId); - if (markerSet == null) { - markerSet = dynmapAPI.getMarkerAPI().createMarkerSet(setId, label, null, false); - if (markerSet == null) { - DynmapCitizens.getInstance().getLogger().log(Level.SEVERE, "Unable to get or create " + setId + - " marker set"); - DynmapCitizens.getInstance().onDisable(); - return null; - } - } - return markerSet; - } - /** * Adds a marker for an NPC * diff --git a/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/quests/QuestAreaHandler.java b/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/quests/QuestAreaHandler.java new file mode 100644 index 0000000..25cf000 --- /dev/null +++ b/src/main/java/net/knarcraft/dynmapcitizens/handler/trait/quests/QuestAreaHandler.java @@ -0,0 +1,114 @@ +package net.knarcraft.dynmapcitizens.handler.trait.quests; + +import me.blackvein.quests.QuestsAPI; +import me.blackvein.quests.quests.IQuest; +import me.blackvein.quests.quests.IStage; +import net.knarcraft.dynmapcitizens.settings.QuestsSettings; +import net.knarcraft.dynmapcitizens.util.DynmapHelper; +import net.knarcraft.dynmapcitizens.util.QuestsHelper; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.dynmap.DynmapAPI; +import org.dynmap.markers.GenericMarker; +import org.dynmap.markers.MarkerSet; + +import java.util.List; + +/** + * A handler class for quest areas + */ +public class QuestAreaHandler { + + private final QuestsAPI questsAPI; + private final MarkerSet killAreaMarkerSet; + private final MarkerSet reachAreaMarkerSet; + private final QuestsSettings settings; + private final ListA reference to the quests API
+ * @param dynmapAPIA reference to the dynmap API
+ * @param settingsThe quests settings to use
+ * @param unavailableQuestsThe list of currently unavailable quests to possibly skip
+ */ + public QuestAreaHandler(QuestsAPI questsAPI, DynmapAPI dynmapAPI, QuestsSettings settings, + ListThe quest the stage belongs to
+ * @param stageThe stage to search for reach locations
+ */ + private void markReachLocations(IQuest quest, IStage stage) { + if (settings.getReachAreaSettings().isDisabled()) { + return; + } + for (int i = 0; i < stage.getLocationsToReach().size(); i++) { + Location location = stage.getLocationsToReach().get(i); + int radius = stage.getRadiiToReachWithin().get(i); + String areaName = stage.getLocationNames().get(i); + String description = ""; + if (areaName != null) { + description += "" + areaName + "The quest the stage belongs to
+ * @param stageThe stage to search for kill locations
+ */ + private void markKillLocations(IQuest quest, IStage stage) { + if (settings.getKillAreaSettings().isDisabled()) { + return; + } + for (int i = 0; i < stage.getLocationsToKillWithin().size(); i++) { + Location location = stage.getLocationsToKillWithin().get(i); + int radius = stage.getRadiiToKillWithin().get(i); + EntityType mob = stage.getMobsToKill().get(i); + int mobAmount = stage.getMobNumToKill().get(i); + String areaName = stage.getKillNames().get(i); + + String description = ""; + if (areaName != null) { + description += "" + areaName + "A reference to the Dynmap API
- * @param markerSettingsThe settings to use for initialization
- * @returnThe initialized marker
- */ - private MarkerSet initializeMarkerSet(DynmapAPI dynmapAPI, AreaMarkerSettings markerSettings) { - MarkerSet markerSet = getMarkerSet(dynmapAPI, markerSettings.getMarkerSetId(), markerSettings.getMarkerSetName()); - if (markerSet != null) { - markerSet.setHideByDefault(markerSettings.markersHiddenByDefault()); - markerSet.setLayerPriority(markerSettings.getMarkerSetPriority()); - } - return markerSet; - } - /** * Generates information about all NPCs involved in quests */ private void generateQuestNPCInfo() { //Clear any previous information - questGiverInfo = new HashMap<>(); - unavailableQuests = new ArrayList<>(); + questGiverInfo.clear(); + unavailableQuests.clear(); //Generation information about NPC's parts in each quest for (IQuest quest : questsAPI.getLoadedQuests()) { - if (isQuestUnavailable(quest)) { + if (QuestsHelper.isQuestUnavailable(quest)) { unavailableQuests.add(quest); //If unavailable quests aren't displayed, there is no point in continuing if (settings.hideUnavailableQuests()) { @@ -138,49 +112,6 @@ public class QuestsHandler extends AbstractTraitHandler { } } - /** - * Checks whether the given quest is unavailable, according to its planner information - * - * @param questThe quest to check for availability
- * @returnTrue if the quest is unavailable
- */ - private boolean isQuestUnavailable(IQuest quest) { - Planner planner = quest.getPlanner(); - long currentTime = System.currentTimeMillis(); - - if (!planner.hasEnd() && !planner.hasStart()) { - return false; - } - - if (!planner.hasStart()) { - //If past the end datetime, the quest is no longer available - return currentTime > planner.getEndInMillis(); - } - - if (!planner.hasEnd()) { - //If before the start datetime, the quest is not yet available - return currentTime < planner.getStartInMillis(); - } - - if (!planner.hasRepeat()) { - //If outside the start and end dates, the quest is unavailable - return currentTime < planner.getStartInMillis() || currentTime > planner.getEndInMillis(); - } - - long startTime = planner.getStartInMillis(); - long endTime = planner.getEndInMillis(); - - do { - if (currentTime > startTime && currentTime < endTime) { - return false; - } - startTime += planner.getRepeat(); - endTime += planner.getRepeat(); - //If startTime > currentTime, current time cannot be within the interval - } while (startTime < currentTime); - return true; - } - /** * Generates all quest markers based on the previously generated quest NPC info */ @@ -292,116 +223,4 @@ public class QuestsHandler extends AbstractTraitHandler { return questGiverInfo.get(npcId); } - /** - * Updates all quest area markers - */ - private void updateQuestAreas() { - this.killAreaMarkerSet.getCircleMarkers().forEach(GenericMarker::deleteMarker); - this.reachAreaMarkerSet.getCircleMarkers().forEach(GenericMarker::deleteMarker); - for (IQuest quest : questsAPI.getLoadedQuests()) { - //Skip marker if quest is unavailable, and unavailable quests are hidden - if (settings.hideUnavailableQuests() && this.unavailableQuests.contains(quest)) { - continue; - } - for (IStage stage : quest.getStages()) { - markKillLocations(quest, stage); - markReachLocations(quest, stage); - } - } - //TODO: Mark WorldGuard areas part of quests. Requires WorldGuard integration - } - - /** - * Marks any reach locations found in the given stage - * - * @param questThe quest the stage belongs to
- * @param stageThe stage to search for reach locations
- */ - private void markReachLocations(IQuest quest, IStage stage) { - if (settings.getReachAreaSettings().isDisabled()) { - return; - } - for (int i = 0; i < stage.getLocationsToReach().size(); i++) { - Location location = stage.getLocationsToReach().get(i); - int radius = stage.getRadiiToReachWithin().get(i); - String areaName = stage.getLocationNames().get(i); - String description = ""; - if (areaName != null) { - description += "" + areaName + "The quest the stage belongs to
- * @param stageThe stage to search for kill locations
- */ - private void markKillLocations(IQuest quest, IStage stage) { - if (settings.getKillAreaSettings().isDisabled()) { - return; - } - for (int i = 0; i < stage.getLocationsToKillWithin().size(); i++) { - Location location = stage.getLocationsToKillWithin().get(i); - int radius = stage.getRadiiToKillWithin().get(i); - EntityType mob = stage.getMobsToKill().get(i); - int mobAmount = stage.getMobNumToKill().get(i); - String areaName = stage.getKillNames().get(i); - - String description = ""; - if (areaName != null) { - description += "" + areaName + "The location to mark
- * @param radiusThe radius of the circular area to mark
- * @param descriptionThe description to put on the marker
- * @param markerSetThe marker set to use when marking the location
- * @param markerSettingsThe settings to use for the marker
- */ - private void markLocation(Location location, Integer radius, String description, MarkerSet markerSet, - AreaMarkerSettings markerSettings) { - //Skip if location is invalid - World world = location.getWorld(); - if (world == null) { - return; - } - - CircleMarker circleMarker = markerSet.createCircleMarker(null, description, true, - world.getName(), location.getX(), location.getY(), location.getZ(), radius, radius, false); - if (circleMarker == null) { - DynmapCitizens.getInstance().getLogger().log(Level.WARNING, "Unable to create circle marker at " + - location + " with radius " + radius); - } else { - circleMarker.setFillStyle(markerSettings.getFillOpacity(), getColor(markerSettings.getFillColor())); - circleMarker.setLineStyle(markerSettings.getLineThickness(), markerSettings.getLineOpacity(), - getColor(markerSettings.getLineColor())); - } - } - - /** - * Gets an integer representation from a hexadecimal color code - * - * @param colorA hexadecimal color
- * @returnAn integer representation of the color
- */ - private int getColor(String color) { - try { - return Integer.parseInt(color, 16); - } catch (NumberFormatException exception) { - return 0; - } - } - } diff --git a/src/main/java/net/knarcraft/dynmapcitizens/util/DynmapHelper.java b/src/main/java/net/knarcraft/dynmapcitizens/util/DynmapHelper.java new file mode 100644 index 0000000..fbe9990 --- /dev/null +++ b/src/main/java/net/knarcraft/dynmapcitizens/util/DynmapHelper.java @@ -0,0 +1,97 @@ +package net.knarcraft.dynmapcitizens.util; + +import net.knarcraft.dynmapcitizens.DynmapCitizens; +import net.knarcraft.dynmapcitizens.settings.AreaMarkerSettings; +import org.bukkit.Location; +import org.bukkit.World; +import org.dynmap.DynmapAPI; +import org.dynmap.markers.CircleMarker; +import org.dynmap.markers.MarkerSet; + +import java.util.logging.Level; + +public class DynmapHelper { + + /** + * Gets the given marker set (and creates it if necessary) + * + * @param dynmapAPIA reference to dynmap's API
+ * @param setIdThe id of the marker set to get
+ * @param labelThe label of the marker set if creation is necessary
+ * @returnThe marker set, or null if something went wrong
+ */ + public static MarkerSet getMarkerSet(DynmapAPI dynmapAPI, String setId, String label) { + MarkerSet markerSet = dynmapAPI.getMarkerAPI().getMarkerSet(setId); + if (markerSet == null) { + markerSet = dynmapAPI.getMarkerAPI().createMarkerSet(setId, label, null, false); + if (markerSet == null) { + DynmapCitizens.getInstance().getLogger().log(Level.SEVERE, "Unable to get or create " + setId + + " marker set"); + DynmapCitizens.getInstance().onDisable(); + return null; + } + } + return markerSet; + } + + /** + * Initializes a marker set from the given settings + * + * @param dynmapAPIA reference to the Dynmap API
+ * @param markerSettingsThe settings to use for initialization
+ * @returnThe initialized marker
+ */ + public static MarkerSet initializeMarkerSet(DynmapAPI dynmapAPI, AreaMarkerSettings markerSettings) { + MarkerSet markerSet = DynmapHelper.getMarkerSet(dynmapAPI, markerSettings.getMarkerSetId(), + markerSettings.getMarkerSetName()); + if (markerSet != null) { + markerSet.setHideByDefault(markerSettings.markersHiddenByDefault()); + markerSet.setLayerPriority(markerSettings.getMarkerSetPriority()); + } + return markerSet; + } + + /** + * Marks a location on the dynamic map + * + * @param locationThe location to mark
+ * @param radiusThe radius of the circular area to mark
+ * @param descriptionThe description to put on the marker
+ * @param markerSetThe marker set to use when marking the location
+ * @param markerSettingsThe settings to use for the marker
+ */ + public static void markLocation(Location location, Integer radius, String description, MarkerSet markerSet, + AreaMarkerSettings markerSettings) { + //Skip if location is invalid + World world = location.getWorld(); + if (world == null) { + return; + } + + CircleMarker circleMarker = markerSet.createCircleMarker(null, description, true, + world.getName(), location.getX(), location.getY(), location.getZ(), radius, radius, false); + if (circleMarker == null) { + DynmapCitizens.getInstance().getLogger().log(Level.WARNING, "Unable to create circle marker at " + + location + " with radius " + radius); + } else { + circleMarker.setFillStyle(markerSettings.getFillOpacity(), getColor(markerSettings.getFillColor())); + circleMarker.setLineStyle(markerSettings.getLineThickness(), markerSettings.getLineOpacity(), + getColor(markerSettings.getLineColor())); + } + } + + /** + * Gets an integer representation from a hexadecimal color code + * + * @param colorA hexadecimal color
+ * @returnAn integer representation of the color
+ */ + private static int getColor(String color) { + try { + return Integer.parseInt(color, 16); + } catch (NumberFormatException exception) { + return 0; + } + } + +} diff --git a/src/main/java/net/knarcraft/dynmapcitizens/util/QuestsHelper.java b/src/main/java/net/knarcraft/dynmapcitizens/util/QuestsHelper.java index 21b06e3..a29f5d8 100644 --- a/src/main/java/net/knarcraft/dynmapcitizens/util/QuestsHelper.java +++ b/src/main/java/net/knarcraft/dynmapcitizens/util/QuestsHelper.java @@ -1,5 +1,7 @@ package net.knarcraft.dynmapcitizens.util; +import me.blackvein.quests.quests.IQuest; +import me.blackvein.quests.quests.Planner; import net.knarcraft.dynmapcitizens.DynmapCitizens; import net.knarcraft.dynmapcitizens.handler.VaultHandler; import net.knarcraft.dynmapcitizens.handler.trait.quests.QuestNPCType; @@ -81,4 +83,47 @@ public class QuestsHelper { }; } + /** + * Checks whether the given quest is unavailable, according to its planner information + * + * @param questThe quest to check for availability
+ * @returnTrue if the quest is unavailable
+ */ + public static boolean isQuestUnavailable(IQuest quest) { + Planner planner = quest.getPlanner(); + long currentTime = System.currentTimeMillis(); + + if (!planner.hasEnd() && !planner.hasStart()) { + return false; + } + + if (!planner.hasStart()) { + //If past the end datetime, the quest is no longer available + return currentTime > planner.getEndInMillis(); + } + + if (!planner.hasEnd()) { + //If before the start datetime, the quest is not yet available + return currentTime < planner.getStartInMillis(); + } + + if (!planner.hasRepeat()) { + //If outside the start and end dates, the quest is unavailable + return currentTime < planner.getStartInMillis() || currentTime > planner.getEndInMillis(); + } + + long startTime = planner.getStartInMillis(); + long endTime = planner.getEndInMillis(); + + do { + if (currentTime > startTime && currentTime < endTime) { + return false; + } + startTime += planner.getRepeat(); + endTime += planner.getRepeat(); + //If startTime > currentTime, current time cannot be within the interval + } while (startTime < currentTime); + return true; + } + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 08a4b88..9dd6bdc 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -74,7 +74,7 @@ traits: reachMarker: enabled: true # The priority of quest reach area markers. Higher priority markers will display on top of lower priority ones - markerSetPriority: 1 + markerSetPriority: 2 # The id of the quest reach area marker set. Change if it overlaps with an existing set id markerSetId: "quests_reach" # The name of the reach areas marker set. Change it if you want a cooler name