Moves code around to split the huge QuestHandler class
This commit is contained in:
parent
3e93b4a733
commit
219abf9ed9
@ -1,10 +1,12 @@
|
||||
package net.knarcraft.dynmapcitizens;
|
||||
|
||||
import net.knarcraft.dynmapcitizens.trait.BlacksmithHandler;
|
||||
import net.knarcraft.dynmapcitizens.trait.CitizensTraitHandler;
|
||||
import net.knarcraft.dynmapcitizens.trait.MinstrelHandler;
|
||||
import net.knarcraft.dynmapcitizens.trait.SentinelHandler;
|
||||
import net.knarcraft.dynmapcitizens.trait.quests.QuestsHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.VaultHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.BlacksmithHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.CitizensTraitHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.MinstrelHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.SentinelHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.quests.QuestsHandler;
|
||||
import net.knarcraft.dynmapcitizens.property.Icon;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.dynmapcitizens;
|
||||
package net.knarcraft.dynmapcitizens.handler;
|
||||
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.dynmapcitizens.trait;
|
||||
package net.knarcraft.dynmapcitizens.handler.trait;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.dynmapcitizens.trait;
|
||||
package net.knarcraft.dynmapcitizens.handler.trait;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
@ -7,8 +7,8 @@ import net.knarcraft.blacksmith.BlacksmithPlugin;
|
||||
import net.knarcraft.blacksmith.config.NPCSettings;
|
||||
import net.knarcraft.blacksmith.trait.BlacksmithTrait;
|
||||
import net.knarcraft.dynmapcitizens.DynmapCitizens;
|
||||
import net.knarcraft.dynmapcitizens.Icon;
|
||||
import net.knarcraft.dynmapcitizens.UpdateRate;
|
||||
import net.knarcraft.dynmapcitizens.property.Icon;
|
||||
import net.knarcraft.dynmapcitizens.property.UpdateRate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.dynmap.DynmapAPI;
|
@ -1,6 +1,6 @@
|
||||
package net.knarcraft.dynmapcitizens.trait;
|
||||
package net.knarcraft.dynmapcitizens.handler.trait;
|
||||
|
||||
import net.knarcraft.dynmapcitizens.UpdateRate;
|
||||
import net.knarcraft.dynmapcitizens.property.UpdateRate;
|
||||
|
||||
/**
|
||||
* A handler which takes care of everything for one citizen trait
|
@ -1,11 +1,11 @@
|
||||
package net.knarcraft.dynmapcitizens.trait;
|
||||
package net.knarcraft.dynmapcitizens.handler.trait;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.knarcraft.dynmapcitizens.DynmapCitizens;
|
||||
import net.knarcraft.dynmapcitizens.Icon;
|
||||
import net.knarcraft.dynmapcitizens.UpdateRate;
|
||||
import net.knarcraft.dynmapcitizens.property.Icon;
|
||||
import net.knarcraft.dynmapcitizens.property.UpdateRate;
|
||||
import net.knarcraft.minstrel.MinstrelPlugin;
|
||||
import net.knarcraft.minstrel.music.Song;
|
||||
import net.knarcraft.minstrel.trait.MinstrelTrait;
|
@ -1,11 +1,11 @@
|
||||
package net.knarcraft.dynmapcitizens.trait;
|
||||
package net.knarcraft.dynmapcitizens.handler.trait;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.knarcraft.dynmapcitizens.DynmapCitizens;
|
||||
import net.knarcraft.dynmapcitizens.Icon;
|
||||
import net.knarcraft.dynmapcitizens.UpdateRate;
|
||||
import net.knarcraft.dynmapcitizens.property.Icon;
|
||||
import net.knarcraft.dynmapcitizens.property.UpdateRate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.dynmap.DynmapAPI;
|
||||
import org.dynmap.markers.GenericMarker;
|
@ -1,7 +1,7 @@
|
||||
package net.knarcraft.dynmapcitizens.trait.quests;
|
||||
package net.knarcraft.dynmapcitizens.handler.trait.quests;
|
||||
|
||||
import me.blackvein.quests.quests.IQuest;
|
||||
import net.knarcraft.dynmapcitizens.Icon;
|
||||
import net.knarcraft.dynmapcitizens.property.Icon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.dynmapcitizens.trait.quests;
|
||||
package net.knarcraft.dynmapcitizens.handler.trait.quests;
|
||||
|
||||
/**
|
||||
* A specifier for a quest NPC's main type
|
@ -0,0 +1,64 @@
|
||||
package net.knarcraft.dynmapcitizens.handler.trait.quests;
|
||||
|
||||
import me.blackvein.quests.quests.IQuest;
|
||||
import me.blackvein.quests.quests.Planner;
|
||||
import net.knarcraft.dynmapcitizens.util.TimeFormatter;
|
||||
|
||||
/**
|
||||
* A class to generate a string containing all information about a quest's planner info
|
||||
*/
|
||||
public class QuestPlannerInfoGenerator {
|
||||
|
||||
private final IQuest quest;
|
||||
|
||||
/**
|
||||
* Instantiates a new quest planner info generator
|
||||
*
|
||||
* @param quest <p>The quest to generate information about</p>
|
||||
*/
|
||||
public QuestPlannerInfoGenerator(IQuest quest) {
|
||||
this.quest = quest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about the time-availability of a quest
|
||||
*
|
||||
* @return <p>Information about when the quest is available</p>
|
||||
*/
|
||||
public String getQuestPlannerInfo() {
|
||||
Planner planner = quest.getPlanner();
|
||||
StringBuilder plannerInfo = new StringBuilder();
|
||||
plannerInfo.append("<b>Planner:</b><ul>");
|
||||
|
||||
//Quest can be repeated after a cool-down
|
||||
if (planner.hasCooldown()) {
|
||||
plannerInfo.append("<li>Quest repeatable after: ");
|
||||
plannerInfo.append(TimeFormatter.getDurationString(planner.getCooldown() / 1000));
|
||||
plannerInfo.append("</li>");
|
||||
} else {
|
||||
plannerInfo.append("<li>Quest cannot be repeated!</li>");
|
||||
}
|
||||
|
||||
//Quest only becomes available after the start date
|
||||
if (planner.hasStart()) {
|
||||
plannerInfo.append("<li>Quest available from ");
|
||||
plannerInfo.append(TimeFormatter.formatTimestamp(planner.getStartInMillis())).append("</li>");
|
||||
}
|
||||
|
||||
//Quest is only available until the end date
|
||||
if (planner.hasEnd()) {
|
||||
plannerInfo.append("<li>Quest available until ");
|
||||
plannerInfo.append(TimeFormatter.formatTimestamp(planner.getEndInMillis())).append("</li>");
|
||||
}
|
||||
|
||||
//Quest availability repeats
|
||||
if (planner.hasRepeat()) {
|
||||
plannerInfo.append("<li>Quest will become available again after ");
|
||||
plannerInfo.append(TimeFormatter.getDurationString(planner.getRepeat() / 1000)).append("</li>");
|
||||
}
|
||||
|
||||
plannerInfo.append("</ul>");
|
||||
return plannerInfo.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package net.knarcraft.dynmapcitizens.handler.trait.quests;
|
||||
|
||||
import me.blackvein.quests.quests.IQuest;
|
||||
import me.blackvein.quests.quests.Requirements;
|
||||
import net.knarcraft.dynmapcitizens.util.QuestsHelper;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A class to generate a string containing all information about a quest's requirements
|
||||
*/
|
||||
public class QuestRequirementsInfoGenerator {
|
||||
|
||||
private final IQuest quest;
|
||||
|
||||
/**
|
||||
* Instantiates a new quest requirement info generator
|
||||
*
|
||||
* @param quest <p>The quest to generate information about</p>
|
||||
*/
|
||||
public QuestRequirementsInfoGenerator(IQuest quest) {
|
||||
this.quest = quest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about all requirements for the given quest
|
||||
*
|
||||
* @return <p>Information about the quest's requirements</p>
|
||||
*/
|
||||
public String getQuestRequirementsInfo() {
|
||||
Requirements requirements = quest.getRequirements();
|
||||
StringBuilder requirementInfo = new StringBuilder();
|
||||
if (!requirements.hasRequirement()) {
|
||||
return requirementInfo.toString();
|
||||
}
|
||||
|
||||
requirementInfo.append("<b>Requirements: </b><ul>");
|
||||
|
||||
if (requirements.getQuestPoints() > 0) {
|
||||
requirementInfo.append("<li>").append(requirements.getQuestPoints()).append(" quest points</li>");
|
||||
}
|
||||
|
||||
if (requirements.getExp() > 0) {
|
||||
requirementInfo.append("<li>").append(requirements.getExp()).append(" exp</li>");
|
||||
}
|
||||
|
||||
if (!requirements.getBlockQuests().isEmpty()) {
|
||||
requirementInfo.append("<li>Blocked by quests:<ul>");
|
||||
for (IQuest blockQuest : requirements.getBlockQuests()) {
|
||||
requirementInfo.append("<li>").append(blockQuest.getName()).append("</li>");
|
||||
}
|
||||
requirementInfo.append("</ul></li>");
|
||||
}
|
||||
|
||||
if (!requirements.getNeededQuests().isEmpty()) {
|
||||
requirementInfo.append("<li>Required quests:<ul>");
|
||||
for (IQuest neededQuest : requirements.getNeededQuests()) {
|
||||
requirementInfo.append("<li>").append(neededQuest.getName()).append("</li>");
|
||||
}
|
||||
requirementInfo.append("</ul></li>");
|
||||
}
|
||||
|
||||
if (!requirements.getItems().isEmpty()) {
|
||||
requirementInfo.append("<li>Required items:<ul>");
|
||||
for (ItemStack item : requirements.getItems()) {
|
||||
requirementInfo.append("<li>").append(QuestsHelper.getUpperCasedItemStackString(item)).append("</li>");
|
||||
}
|
||||
requirementInfo.append("</ul></li>");
|
||||
}
|
||||
|
||||
if (!requirements.getMcmmoSkills().isEmpty()) {
|
||||
List<String> skills = requirements.getMcmmoSkills();
|
||||
List<Integer> amounts = requirements.getMcmmoAmounts();
|
||||
for (int i = 0; i < skills.size(); i++) {
|
||||
requirementInfo.append("<li>Requires mcMMO skill ").append(skills.get(i)).append(" at level ");
|
||||
requirementInfo.append(amounts.get(i)).append("</li>");
|
||||
}
|
||||
}
|
||||
|
||||
if (!requirements.getPermissions().isEmpty()) {
|
||||
requirementInfo.append("<li>Required permissions:<ul>");
|
||||
for (String permission : requirements.getPermissions()) {
|
||||
requirementInfo.append("<li>").append(permission).append("</li>");
|
||||
}
|
||||
requirementInfo.append("</ul></li>");
|
||||
}
|
||||
|
||||
Map<String, Map<String, Object>> customRequirementPlugins = requirements.getCustomRequirements();
|
||||
for (String plugin : customRequirementPlugins.keySet()) {
|
||||
requirementInfo.append("<li>").append(plugin).append(":<ul>");
|
||||
//Note: The format of custom requirements is kind of weird. First, you have the key for which plugin the
|
||||
// requirement belongs to. Getting the value of the key gives another map. The map contains as key, the type
|
||||
// of value, like "Skill Amount" or "Skill Type". The value is the actual value of whatever it is.
|
||||
Map<String, Object> customRequirementEntry = customRequirementPlugins.get(plugin);
|
||||
for (String requirementDescription : customRequirementEntry.keySet()) {
|
||||
requirementInfo.append("<li>").append(requirementDescription).append(" ");
|
||||
requirementInfo.append(customRequirementEntry.get(requirementDescription)).append("</li>");
|
||||
}
|
||||
requirementInfo.append("</ul></li>");
|
||||
}
|
||||
|
||||
requirementInfo.append("</ul>");
|
||||
return requirementInfo.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package net.knarcraft.dynmapcitizens.handler.trait.quests;
|
||||
|
||||
import me.blackvein.quests.quests.IQuest;
|
||||
import me.blackvein.quests.quests.Rewards;
|
||||
import net.knarcraft.dynmapcitizens.util.QuestsHelper;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* A class to generate a string containing all information about a quest's rewards
|
||||
*/
|
||||
public class QuestRewardsInfoGenerator {
|
||||
|
||||
private final IQuest quest;
|
||||
|
||||
/**
|
||||
* Instantiates a new quest reward info generator
|
||||
*
|
||||
* @param quest <p>The quest to generate information about</p>
|
||||
*/
|
||||
public QuestRewardsInfoGenerator(IQuest quest) {
|
||||
this.quest = quest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about all rewards for the given quest
|
||||
*
|
||||
* @return <p>Information about the quest's rewards</p>
|
||||
*/
|
||||
public String getQuestRewardsInfo() {
|
||||
Rewards reward = quest.getRewards();
|
||||
StringBuilder rewardInfo = new StringBuilder();
|
||||
rewardInfo.append("<b>Rewards:</b><ul>");
|
||||
|
||||
if (reward.getMoney() > 0) {
|
||||
rewardInfo.append("<li>").append(reward.getMoney()).append(" ").append(QuestsHelper.getCurrency(reward.getMoney())).append("</li>");
|
||||
}
|
||||
|
||||
if (reward.getExp() > 0) {
|
||||
rewardInfo.append("<li>").append(reward.getExp()).append(" exp").append("</li>");
|
||||
}
|
||||
|
||||
for (String permission : reward.getPermissions()) {
|
||||
rewardInfo.append("<li>").append("Permission: ").append(permission).append("</li>");
|
||||
}
|
||||
|
||||
for (ItemStack item : reward.getItems()) {
|
||||
rewardInfo.append("<li>").append(QuestsHelper.getUpperCasedItemStackString(item)).append("</li>");
|
||||
}
|
||||
|
||||
for (String command : reward.getCommands()) {
|
||||
rewardInfo.append("<li>Command: ").append(command).append("</li>");
|
||||
}
|
||||
|
||||
rewardInfo.append("</ul>");
|
||||
return rewardInfo.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package net.knarcraft.dynmapcitizens.handler.trait.quests;
|
||||
|
||||
import me.blackvein.quests.quests.IQuest;
|
||||
import me.blackvein.quests.quests.IStage;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.knarcraft.dynmapcitizens.util.QuestsHelper;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A class to generate a string containing all information about a quest's stages
|
||||
*/
|
||||
public class QuestStagesInfoGenerator {
|
||||
|
||||
private final IQuest quest;
|
||||
|
||||
/**
|
||||
* Instantiates a new quest stages info generator
|
||||
*
|
||||
* @param quest <p>The quest to generate information about</p>
|
||||
*/
|
||||
public QuestStagesInfoGenerator(IQuest quest) {
|
||||
this.quest = quest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about a quest's stages
|
||||
*
|
||||
* @return <p>A string with information about the quest's stages</p>
|
||||
*/
|
||||
public String getQuestStagesInfo() {
|
||||
StringBuilder questInfo = new StringBuilder();
|
||||
NPCRegistry registry = CitizensAPI.getNPCRegistry();
|
||||
int stageCounter = 1;
|
||||
questInfo.append("<b>Stages:</b><ul>");
|
||||
for (IStage stage : quest.getStages()) {
|
||||
questInfo.append("<li><b>Stage ").append(stageCounter).append(" tasks:</b><ul>");
|
||||
int mobTypes = stage.getMobsToKill().size();
|
||||
for (int i = 0; i < mobTypes; i++) {
|
||||
questInfo.append("<li>Kill ").append(QuestsHelper.normalizeName(stage.getMobsToKill().get(i).name())).append(
|
||||
" X ").append(stage.getMobNumToKill().get(i)).append("</li>");
|
||||
}
|
||||
int deliveries = stage.getItemDeliveryTargets().size();
|
||||
for (int i = 0; i < deliveries; i++) {
|
||||
NPC npc = registry.getByUniqueId(stage.getItemDeliveryTargets().get(i));
|
||||
questInfo.append("<li>Deliver ").append(QuestsHelper.getItemStackString(stage.getItemsToDeliver().get(i))).append(
|
||||
" to ").append(npc.getName()).append("</li>");
|
||||
}
|
||||
if (stage.getFishToCatch() != null) {
|
||||
questInfo.append("<li>Catch ").append(stage.getFishToCatch()).append(" fish").append("</li>");
|
||||
}
|
||||
for (UUID npcId : stage.getNpcsToKill()) {
|
||||
questInfo.append("<li>Kill NPC ").append(registry.getByUniqueId(npcId).getName()).append("</li>");
|
||||
}
|
||||
|
||||
questInfo.append(getQuestItemsTaskString(stage.getBlocksToBreak(), "<li>Break ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getBlocksToCut(), "<li>Cut ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getBlocksToDamage(), "<li>Damage ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getBlocksToUse(), "<li>Use ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getBlocksToPlace(), "<li>Place ")).append("</li>");
|
||||
|
||||
questInfo.append(getQuestItemsTaskString(stage.getItemsToBrew(), "<li>Brew ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getItemsToConsume(), "<li>Consume ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getItemsToCraft(), "<li>Craft ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getItemsToEnchant(), "<li>Enchant ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getItemsToSmelt(), "<li>Smelt ")).append("</li>");
|
||||
|
||||
int sheepTypes = stage.getSheepToShear().size();
|
||||
for (int i = 0; i < sheepTypes; i++) {
|
||||
questInfo.append("<li>Shear ").append(stage.getSheepNumToShear().get(i)).append(" ").append(
|
||||
QuestsHelper.normalizeName(stage.getSheepToShear().get(i).name())).append(" sheep").append("</li>");
|
||||
}
|
||||
if (stage.getCowsToMilk() != null) {
|
||||
questInfo.append("<li>Milk ").append(stage.getCowsToMilk()).append(" cows").append("</li>");
|
||||
}
|
||||
|
||||
int mobTamingEntries = stage.getMobsToTame().size();
|
||||
for (int i = 0; i < mobTamingEntries; i++) {
|
||||
questInfo.append("<li>Tame ").append(stage.getMobNumToTame().get(i)).append(" ").append(
|
||||
QuestsHelper.normalizeName(stage.getMobsToTame().get(i).name())).append("</li>");
|
||||
}
|
||||
|
||||
questInfo.append("</ul></li>");
|
||||
stageCounter++;
|
||||
}
|
||||
questInfo.append("</ul>");
|
||||
return questInfo.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string to display a quest task involving some action on an item
|
||||
*
|
||||
* @param items <p>The items that are part of the task</p>
|
||||
* @param explanation <p>The explanation of what the player needs to do with the items</p>
|
||||
* @return <p>A string describing the necessary tasks</p>
|
||||
*/
|
||||
private String getQuestItemsTaskString(List<ItemStack> items, String explanation) {
|
||||
StringBuilder questInfo = new StringBuilder();
|
||||
for (ItemStack itemStack : items) {
|
||||
questInfo.append(explanation).append(QuestsHelper.getItemStackString(itemStack));
|
||||
}
|
||||
return questInfo.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,266 @@
|
||||
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.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.knarcraft.dynmapcitizens.DynmapCitizens;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.AbstractTraitHandler;
|
||||
import net.knarcraft.dynmapcitizens.property.Icon;
|
||||
import net.knarcraft.dynmapcitizens.property.UpdateRate;
|
||||
import net.knarcraft.dynmapcitizens.util.QuestsHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.dynmap.DynmapAPI;
|
||||
import org.dynmap.markers.CircleMarker;
|
||||
import org.dynmap.markers.GenericMarker;
|
||||
import org.dynmap.markers.MarkerIcon;
|
||||
import org.dynmap.markers.MarkerSet;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A handler class for the quests trait
|
||||
*/
|
||||
public class QuestsHandler extends AbstractTraitHandler {
|
||||
|
||||
private QuestsAPI questsAPI;
|
||||
private MarkerSet questMarkerSet;
|
||||
private MarkerSet questAreaMarkerSet;
|
||||
private Map<Icon, MarkerIcon> markerIcons;
|
||||
private Collection<IQuest> loadedQuests;
|
||||
private Map<UUID, NPCQuestInfo> questGiverInfo;
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
questsAPI = (QuestsAPI) Bukkit.getServer().getPluginManager().getPlugin("Quests");
|
||||
DynmapAPI dynmapAPI = DynmapCitizens.getInstance().getDynmapAPI();
|
||||
markerIcons = DynmapCitizens.getInstance().getMarkerIcons();
|
||||
if (questsAPI != null) {
|
||||
questMarkerSet = getMarkerSet(dynmapAPI, "quests", "Quests");
|
||||
questAreaMarkerSet = getMarkerSet(dynmapAPI, "quest_areas", "Quest areas");
|
||||
if (questMarkerSet != null && questAreaMarkerSet != null) {
|
||||
questMarkerSet.setHideByDefault(false);
|
||||
questAreaMarkerSet.setHideByDefault(true);
|
||||
questMarkerSet.setLayerPriority(3);
|
||||
questAreaMarkerSet.setLayerPriority(2);
|
||||
isEnabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
isEnabled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateRate getUpdateRate() {
|
||||
return UpdateRate.VERY_SLOW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMarkers() {
|
||||
if (questsAPI.isLoading()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//There is no point in updating if there has been no changes in quests
|
||||
boolean questsChanged = loadedQuests == null || !loadedQuests.equals(questsAPI.getLoadedQuests());
|
||||
loadedQuests = questsAPI.getLoadedQuests();
|
||||
|
||||
//Remove old quest markers
|
||||
questMarkerSet.getMarkers().forEach(GenericMarker::deleteMarker);
|
||||
|
||||
//Updates all quest area markers
|
||||
if (questsChanged) {
|
||||
updateQuestAreas();
|
||||
}
|
||||
|
||||
//Generate information about all NPCs involved in quests
|
||||
generateQuestNPCInfo();
|
||||
|
||||
//Generate markers based on the generated info
|
||||
generateAllMarkers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates information about all NPCs involved in quests
|
||||
*/
|
||||
private void generateQuestNPCInfo() {
|
||||
//Clear any previous information
|
||||
questGiverInfo = new HashMap<>();
|
||||
//Generation information about NPC's parts in each quest
|
||||
for (IQuest quest : questsAPI.getLoadedQuests()) {
|
||||
if (quest.getNpcStart() != null) {
|
||||
getInfo(quest.getNpcStart()).addQuestStart(quest);
|
||||
}
|
||||
for (IStage stage : quest.getStages()) {
|
||||
for (UUID npcId : stage.getNpcsToKill()) {
|
||||
getInfo(npcId).addQuestKill(quest);
|
||||
}
|
||||
for (UUID npcId : stage.getItemDeliveryTargets()) {
|
||||
getInfo(npcId).addQuestDeliver(quest);
|
||||
}
|
||||
for (UUID npcId : stage.getNpcsToInteract()) {
|
||||
getInfo(npcId).addQuestInteract(quest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates all quest markers based on the previously generated quest NPC info
|
||||
*/
|
||||
private void generateAllMarkers() {
|
||||
NPCRegistry registry = CitizensAPI.getNPCRegistry();
|
||||
//Add markers for each NPC detected as part of a quest
|
||||
for (UUID npcId : questGiverInfo.keySet()) {
|
||||
NPCQuestInfo info = questGiverInfo.get(npcId);
|
||||
MarkerIcon icon = markerIcons.get(info.getNPCIcon());
|
||||
List<IQuest> questStarts = info.getQuestStarts();
|
||||
StringBuilder markerDescription = new StringBuilder();
|
||||
|
||||
markerDescription.append("<h2>").append(registry.getByUniqueId(npcId).getName()).append("</h2>");
|
||||
|
||||
if (!questStarts.isEmpty()) {
|
||||
markerDescription.append("<h3>Quests offered:</h3><ul>");
|
||||
for (IQuest quest : questStarts) {
|
||||
markerDescription.append("<li><h4><b>").append(quest.getName()).append("</b></h4><h5><b>- ");
|
||||
markerDescription.append(quest.getDescription()).append("</b></h5>").append(
|
||||
new QuestStagesInfoGenerator(quest).getQuestStagesInfo());
|
||||
markerDescription.append(new QuestRewardsInfoGenerator(quest).getQuestRewardsInfo());
|
||||
markerDescription.append(new QuestRequirementsInfoGenerator(quest).getQuestRequirementsInfo());
|
||||
markerDescription.append(new QuestPlannerInfoGenerator(quest).getQuestPlannerInfo()).append("</li>");
|
||||
}
|
||||
markerDescription.append("</ul>");
|
||||
}
|
||||
|
||||
markerDescription.append(getInvolvedInQuestsString(info));
|
||||
|
||||
addNPCMarker(npcId, QuestsHelper.getMarkerTitle(info.getQuestNPCType()), markerDescription.toString(), icon, questMarkerSet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about the quests an NPC is involved in
|
||||
*
|
||||
* @param info <p>The NPC info to look through</p>
|
||||
* @return <p>Information about an NPC's involvement in different quests</p>
|
||||
*/
|
||||
private String getInvolvedInQuestsString(NPCQuestInfo info) {
|
||||
List<IQuest> questKills = info.getQuestKills();
|
||||
List<IQuest> questInteractions = info.getQuestInteractions();
|
||||
List<IQuest> questDeliveries = info.getQuestDeliveries();
|
||||
|
||||
if (questKills.isEmpty() && questInteractions.isEmpty() && questDeliveries.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder markerDescription = new StringBuilder();
|
||||
markerDescription.append("<h3>Involved in quests:</h3><ul>");
|
||||
addInvolvedInString("Killed in", questKills, markerDescription);
|
||||
addInvolvedInString("Delivery target in", questDeliveries, markerDescription);
|
||||
addInvolvedInString("Interacted with in quest", questInteractions, markerDescription);
|
||||
markerDescription.append("</ul>");
|
||||
return markerDescription.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds string explaining how an NPC is involved with the given quests
|
||||
*
|
||||
* @param prefix <p>The string explaining how the NPC is involved</p>
|
||||
* @param quests <p>The quests the NPC is involved in</p>
|
||||
* @param builder <p>The string builder to append to</p>
|
||||
*/
|
||||
private void addInvolvedInString(String prefix, List<IQuest> quests, StringBuilder builder) {
|
||||
for (IQuest quest : new HashSet<>(quests)) {
|
||||
builder.append("<li>").append(prefix).append(": ").append(quest.getName()).append("</li>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the info object for the given NPC
|
||||
*
|
||||
* @param npcId <p>The id of the NPC to get information about</p>
|
||||
* @return <p>The NPC's info object</p>
|
||||
*/
|
||||
private NPCQuestInfo getInfo(UUID npcId) {
|
||||
if (questGiverInfo.get(npcId) == null) {
|
||||
questGiverInfo.put(npcId, new NPCQuestInfo());
|
||||
}
|
||||
return questGiverInfo.get(npcId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all quest area markers
|
||||
*/
|
||||
private void updateQuestAreas() {
|
||||
questAreaMarkerSet.getCircleMarkers().forEach(GenericMarker::deleteMarker);
|
||||
for (IQuest quest : questsAPI.getLoadedQuests()) {
|
||||
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 quest <p>The quest the stage belongs to</p>
|
||||
* @param stage <p>The stage to search for reach locations</p>
|
||||
*/
|
||||
private void markReachLocations(IQuest quest, IStage stage) {
|
||||
markLocations(stage.getLocationsToReach(), stage.getRadiiToReachWithin(),
|
||||
"<b>Target location for:</b> " + quest.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks any kill locations found in the given stage
|
||||
*
|
||||
* @param quest <p>The quest the stage belongs to</p>
|
||||
* @param stage <p>The stage to search for kill locations</p>
|
||||
*/
|
||||
private void markKillLocations(IQuest quest, IStage stage) {
|
||||
markLocations(stage.getLocationsToKillWithin(), stage.getRadiiToKillWithin(),
|
||||
"<b>Kill location for:</b> " + quest.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given locations on the dynamic map
|
||||
*
|
||||
* @param locations <p>The locations to mark</p>
|
||||
* @param radii <p>The radius of each location's circle</p>
|
||||
* @param description <p>The description for what the location means</p>
|
||||
*/
|
||||
private void markLocations(List<Location> locations, List<Integer> radii, String description) {
|
||||
for (int i = 0; i < locations.size(); i++) {
|
||||
Location location = locations.get(i);
|
||||
int radius = radii.get(i);
|
||||
|
||||
//Skip if location is invalid
|
||||
World world = location.getWorld();
|
||||
if (world == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CircleMarker circleMarker = questAreaMarkerSet.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(0.3, 0x75AFD2);
|
||||
circleMarker.setLineStyle(1, 1.0, 0x36c90e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.dynmapcitizens;
|
||||
package net.knarcraft.dynmapcitizens.property;
|
||||
|
||||
/**
|
||||
* Every icon type used
|
@ -1,4 +1,4 @@
|
||||
package net.knarcraft.dynmapcitizens;
|
||||
package net.knarcraft.dynmapcitizens.property;
|
||||
|
||||
/**
|
||||
* An update rate for a group of icons
|
@ -1,604 +0,0 @@
|
||||
package net.knarcraft.dynmapcitizens.trait.quests;
|
||||
|
||||
import me.blackvein.quests.QuestsAPI;
|
||||
import me.blackvein.quests.quests.IQuest;
|
||||
import me.blackvein.quests.quests.IStage;
|
||||
import me.blackvein.quests.quests.Planner;
|
||||
import me.blackvein.quests.quests.Requirements;
|
||||
import me.blackvein.quests.quests.Rewards;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.knarcraft.dynmapcitizens.DynmapCitizens;
|
||||
import net.knarcraft.dynmapcitizens.Icon;
|
||||
import net.knarcraft.dynmapcitizens.UpdateRate;
|
||||
import net.knarcraft.dynmapcitizens.VaultHandler;
|
||||
import net.knarcraft.dynmapcitizens.trait.AbstractTraitHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.dynmap.DynmapAPI;
|
||||
import org.dynmap.markers.CircleMarker;
|
||||
import org.dynmap.markers.GenericMarker;
|
||||
import org.dynmap.markers.MarkerIcon;
|
||||
import org.dynmap.markers.MarkerSet;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static net.knarcraft.blacksmith.formatting.StringFormatter.replacePlaceholder;
|
||||
|
||||
/**
|
||||
* A handler class for the quests trait
|
||||
*/
|
||||
public class QuestsHandler extends AbstractTraitHandler {
|
||||
|
||||
private QuestsAPI questsAPI;
|
||||
private MarkerSet questMarkerSet;
|
||||
private MarkerSet questAreaMarkerSet;
|
||||
private Map<Icon, MarkerIcon> markerIcons;
|
||||
private Collection<IQuest> loadedQuests;
|
||||
private Map<UUID, NPCQuestInfo> questGiverInfo;
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
questsAPI = (QuestsAPI) Bukkit.getServer().getPluginManager().getPlugin("Quests");
|
||||
DynmapAPI dynmapAPI = DynmapCitizens.getInstance().getDynmapAPI();
|
||||
markerIcons = DynmapCitizens.getInstance().getMarkerIcons();
|
||||
if (questsAPI != null) {
|
||||
questMarkerSet = getMarkerSet(dynmapAPI, "quests", "Quests");
|
||||
questAreaMarkerSet = getMarkerSet(dynmapAPI, "quest_areas", "Quest areas");
|
||||
if (questMarkerSet != null && questAreaMarkerSet != null) {
|
||||
questMarkerSet.setHideByDefault(false);
|
||||
questAreaMarkerSet.setHideByDefault(true);
|
||||
questMarkerSet.setLayerPriority(3);
|
||||
questAreaMarkerSet.setLayerPriority(2);
|
||||
isEnabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
isEnabled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateRate getUpdateRate() {
|
||||
return UpdateRate.VERY_SLOW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMarkers() {
|
||||
if (questsAPI.isLoading()) {
|
||||
return;
|
||||
}
|
||||
|
||||
questGiverInfo = new HashMap<>();
|
||||
|
||||
//There is no point in updating if there has been no changes in quests
|
||||
boolean questsChanged = loadedQuests == null || !loadedQuests.equals(questsAPI.getLoadedQuests());
|
||||
loadedQuests = questsAPI.getLoadedQuests();
|
||||
|
||||
//Remove old quest markers
|
||||
questMarkerSet.getMarkers().forEach(GenericMarker::deleteMarker);
|
||||
|
||||
//Updates all quest area markers
|
||||
if (questsChanged) {
|
||||
updateQuestAreas();
|
||||
}
|
||||
|
||||
NPCRegistry registry = CitizensAPI.getNPCRegistry();
|
||||
|
||||
//Generation information about NPC's parts in each quest
|
||||
for (IQuest quest : questsAPI.getLoadedQuests()) {
|
||||
if (quest.getNpcStart() != null) {
|
||||
getInfo(quest.getNpcStart()).addQuestStart(quest);
|
||||
}
|
||||
for (IStage stage : quest.getStages()) {
|
||||
for (UUID npcId : stage.getNpcsToKill()) {
|
||||
getInfo(npcId).addQuestKill(quest);
|
||||
}
|
||||
for (UUID npcId : stage.getItemDeliveryTargets()) {
|
||||
getInfo(npcId).addQuestDeliver(quest);
|
||||
}
|
||||
for (UUID npcId : stage.getNpcsToInteract()) {
|
||||
getInfo(npcId).addQuestInteract(quest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Add markers for each NPC detected as part of a quest
|
||||
for (UUID npcId : questGiverInfo.keySet()) {
|
||||
NPCQuestInfo info = questGiverInfo.get(npcId);
|
||||
MarkerIcon icon = markerIcons.get(info.getNPCIcon());
|
||||
List<IQuest> questStarts = info.getQuestStarts();
|
||||
List<IQuest> questKills = info.getQuestKills();
|
||||
List<IQuest> questInteractions = info.getQuestInteractions();
|
||||
List<IQuest> questDeliveries = info.getQuestDeliveries();
|
||||
StringBuilder markerDescription = new StringBuilder();
|
||||
|
||||
markerDescription.append("<h2>").append(registry.getByUniqueId(npcId).getName()).append("</h2>");
|
||||
|
||||
if (!questStarts.isEmpty()) {
|
||||
markerDescription.append("<h3>Quests offered:</h3><ul>");
|
||||
for (IQuest quest : questStarts) {
|
||||
markerDescription.append("<li><h4><b>").append(quest.getName()).append("</b></h4><h5><b>- ");
|
||||
markerDescription.append(quest.getDescription()).append("</b></h5>").append(getQuestStagesInfo(quest));
|
||||
markerDescription.append(getQuestRewardsInfo(quest)).append(getQuestRequirementsInfo(quest));
|
||||
markerDescription.append(getQuestPlannerInfo(quest)).append("</li>");
|
||||
}
|
||||
markerDescription.append("</ul>");
|
||||
}
|
||||
|
||||
if (!questKills.isEmpty() || !questInteractions.isEmpty() || !questDeliveries.isEmpty()) {
|
||||
markerDescription.append("<h3>Involved in quests:</h3><ul>");
|
||||
|
||||
for (IQuest quest : new HashSet<>(questKills)) {
|
||||
markerDescription.append("<li>Killed in: ").append(quest.getName()).append("</li>");
|
||||
}
|
||||
for (IQuest quest : new HashSet<>(questDeliveries)) {
|
||||
markerDescription.append("<li>Delivery target in: ").append(quest.getName()).append("</li>");
|
||||
}
|
||||
for (IQuest quest : new HashSet<>(questInteractions)) {
|
||||
markerDescription.append("<li>Interacted with in quest: ").append(quest.getName()).append("</li>");
|
||||
}
|
||||
|
||||
markerDescription.append("</ul>");
|
||||
}
|
||||
|
||||
addNPCMarker(npcId, getMarkerTitle(info.getQuestNPCType()), markerDescription.toString(), icon, questMarkerSet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about the time-availability of a quest
|
||||
*
|
||||
* @param quest <p>The quest to get planner info from</p>
|
||||
* @return <p>Information about when the quest is available</p>
|
||||
*/
|
||||
private String getQuestPlannerInfo(IQuest quest) {
|
||||
Planner planner = quest.getPlanner();
|
||||
StringBuilder plannerInfo = new StringBuilder();
|
||||
plannerInfo.append("<b>Planner:</b><ul>");
|
||||
|
||||
//Quest can be repeated after a cool-down
|
||||
if (planner.hasCooldown()) {
|
||||
plannerInfo.append("<li>Quest repeatable after: ").append(getDurationString(planner.getCooldown() / 1000));
|
||||
plannerInfo.append("</li>");
|
||||
} else {
|
||||
plannerInfo.append("<li>Quest cannot be repeated!</li>");
|
||||
}
|
||||
|
||||
//Quest only becomes available after the start date
|
||||
if (planner.hasStart()) {
|
||||
DateFormat format = new SimpleDateFormat("dd MM yyyy HH:mm:ss");
|
||||
Date date = new Date(planner.getStartInMillis());
|
||||
plannerInfo.append("<li>Quest available from ").append(format.format(date)).append("</li>");
|
||||
}
|
||||
|
||||
//Quest is only available until the end date
|
||||
if (planner.hasEnd()) {
|
||||
DateFormat format = new SimpleDateFormat("dd MM yyyy HH:mm:ss");
|
||||
Date date = new Date(planner.getEndInMillis());
|
||||
plannerInfo.append("<li>Quest available until ").append(format.format(date)).append("</li>");
|
||||
}
|
||||
|
||||
//Quest availability repeats
|
||||
if (planner.hasRepeat()) {
|
||||
plannerInfo.append("<li>Quest will become available again after ");
|
||||
plannerInfo.append(getDurationString(planner.getRepeat() / 1000)).append("</li>");
|
||||
}
|
||||
|
||||
plannerInfo.append("</ul>");
|
||||
return plannerInfo.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string used for displaying this sign's duration
|
||||
*
|
||||
* @return <p>The string used for displaying this sign's duration</p>
|
||||
*/
|
||||
public String getDurationString(long duration) {
|
||||
if (duration == 0) {
|
||||
return "immediately";
|
||||
} else {
|
||||
double minute = 60;
|
||||
double hour = minute * 60;
|
||||
double day = hour * 24;
|
||||
double week = day * 7;
|
||||
double month = day * 30;
|
||||
double year = day * 365;
|
||||
double decade = year * 10;
|
||||
|
||||
Map<Double, String[]> timeUnits = new HashMap<>();
|
||||
timeUnits.put(decade, new String[]{"decade", "decades"});
|
||||
timeUnits.put(year, new String[]{"year", "years"});
|
||||
timeUnits.put(month, new String[]{"month", "months"});
|
||||
timeUnits.put(week, new String[]{"week", "weeks"});
|
||||
timeUnits.put(day, new String[]{"day", "days"});
|
||||
timeUnits.put(hour, new String[]{"hour", "hours"});
|
||||
timeUnits.put(minute, new String[]{"minute", "minutes"});
|
||||
timeUnits.put(1D, new String[]{"second", "seconds"});
|
||||
|
||||
List<Double> sortedUnits = new ArrayList<>(timeUnits.keySet());
|
||||
Collections.sort(sortedUnits);
|
||||
Collections.reverse(sortedUnits);
|
||||
|
||||
for (Double unit : sortedUnits) {
|
||||
if (duration / unit >= 1) {
|
||||
double units = round(duration / unit);
|
||||
return formatDurationString(units, timeUnits.get(unit)[units == 1 ? 0 : 1],
|
||||
(units * 10) % 10 == 0);
|
||||
}
|
||||
}
|
||||
return formatDurationString(duration, "seconds", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds a number to its last two digits
|
||||
*
|
||||
* @param number <p>The number to round</p>
|
||||
* @return <p>The rounded number</p>
|
||||
*/
|
||||
private double round(double number) {
|
||||
return Math.round(number * 100.0) / 100.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a duration string
|
||||
*
|
||||
* @param duration <p>The duration to display</p>
|
||||
* @param translatableMessage <p>The time unit to display</p>
|
||||
* @param castToInt <p>Whether to cast the duration to an int</p>
|
||||
* @return <p>The formatted duration string</p>
|
||||
*/
|
||||
private String formatDurationString(double duration, String translatableMessage, boolean castToInt) {
|
||||
String durationFormat = "{duration} {unit}";
|
||||
durationFormat = replacePlaceholder(durationFormat, "{unit}", translatableMessage);
|
||||
return replacePlaceholder(durationFormat, "{duration}", castToInt ? String.valueOf((int) duration) :
|
||||
String.valueOf(duration));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about all requirements for the given quest
|
||||
*
|
||||
* @param quest <p>The quest to get requirements for</p>
|
||||
* @return <p>Information about the quest's requirements</p>
|
||||
*/
|
||||
private String getQuestRequirementsInfo(IQuest quest) {
|
||||
Requirements requirements = quest.getRequirements();
|
||||
StringBuilder requirementInfo = new StringBuilder();
|
||||
if (!requirements.hasRequirement()) {
|
||||
return requirementInfo.toString();
|
||||
}
|
||||
|
||||
requirementInfo.append("<b>Requirements: </b><ul>");
|
||||
|
||||
if (requirements.getQuestPoints() > 0) {
|
||||
requirementInfo.append("<li>").append(requirements.getQuestPoints()).append(" quest points</li>");
|
||||
}
|
||||
|
||||
if (requirements.getExp() > 0) {
|
||||
requirementInfo.append("<li>").append(requirements.getExp()).append(" exp</li>");
|
||||
}
|
||||
|
||||
if (!requirements.getBlockQuests().isEmpty()) {
|
||||
requirementInfo.append("<li>Blocked by quests:<ul>");
|
||||
for (IQuest blockQuest : requirements.getBlockQuests()) {
|
||||
requirementInfo.append("<li>").append(blockQuest.getName()).append("</li>");
|
||||
}
|
||||
requirementInfo.append("</ul></li>");
|
||||
}
|
||||
|
||||
if (!requirements.getNeededQuests().isEmpty()) {
|
||||
requirementInfo.append("<li>Required quests:<ul>");
|
||||
for (IQuest neededQuest : requirements.getNeededQuests()) {
|
||||
requirementInfo.append("<li>").append(neededQuest.getName()).append("</li>");
|
||||
}
|
||||
requirementInfo.append("</ul></li>");
|
||||
}
|
||||
|
||||
if (!requirements.getItems().isEmpty()) {
|
||||
requirementInfo.append("<li>Required items:<ul>");
|
||||
for (ItemStack item : requirements.getItems()) {
|
||||
requirementInfo.append("<li>").append(uppercaseFirst(getItemStackString(item))).append("</li>");
|
||||
}
|
||||
requirementInfo.append("</ul></li>");
|
||||
}
|
||||
|
||||
if (!requirements.getMcmmoSkills().isEmpty()) {
|
||||
List<String> skills = requirements.getMcmmoSkills();
|
||||
List<Integer> amounts = requirements.getMcmmoAmounts();
|
||||
for (int i = 0; i < skills.size(); i++) {
|
||||
requirementInfo.append("<li>Requires mcMMO skill ").append(skills.get(i)).append(" at level ");
|
||||
requirementInfo.append(amounts.get(i)).append("</li>");
|
||||
}
|
||||
}
|
||||
|
||||
if (!requirements.getPermissions().isEmpty()) {
|
||||
requirementInfo.append("<li>Required permissions:<ul>");
|
||||
for (String permission : requirements.getPermissions()) {
|
||||
requirementInfo.append("<li>").append(permission).append("</li>");
|
||||
}
|
||||
requirementInfo.append("</ul></li>");
|
||||
}
|
||||
|
||||
Map<String, Map<String, Object>> customRequirementPlugins = requirements.getCustomRequirements();
|
||||
for (String plugin : customRequirementPlugins.keySet()) {
|
||||
requirementInfo.append("<li>").append(plugin).append(":<ul>");
|
||||
//Note: The format of custom requirements is kind of weird. First, you have the key for which plugin the
|
||||
// requirement belongs to. Getting the value of the key gives another map. The map contains as key, the type
|
||||
// of value, like "Skill Amount" or "Skill Type". The value is the actual value of whatever it is.
|
||||
Map<String, Object> customRequirementEntry = customRequirementPlugins.get(plugin);
|
||||
for (String requirementDescription : customRequirementEntry.keySet()) {
|
||||
requirementInfo.append("<li>").append(requirementDescription).append(" ").append(customRequirementEntry.get(requirementDescription)).append("</li>");
|
||||
}
|
||||
requirementInfo.append("</ul></li>");
|
||||
}
|
||||
|
||||
requirementInfo.append("</ul>");
|
||||
return requirementInfo.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about all rewards for the given quest
|
||||
*
|
||||
* @param quest <p>The quest to get reward information for</p>
|
||||
* @return <p>Information about the quest's rewards</p>
|
||||
*/
|
||||
private String getQuestRewardsInfo(IQuest quest) {
|
||||
Rewards reward = quest.getRewards();
|
||||
StringBuilder rewardInfo = new StringBuilder();
|
||||
rewardInfo.append("<b>Rewards:</b><ul>");
|
||||
|
||||
if (reward.getMoney() > 0) {
|
||||
rewardInfo.append("<li>").append(reward.getMoney()).append(" ").append(getCurrency(reward.getMoney())).append("</li>");
|
||||
}
|
||||
|
||||
if (reward.getExp() > 0) {
|
||||
rewardInfo.append("<li>").append(reward.getExp()).append(" exp").append("</li>");
|
||||
}
|
||||
|
||||
for (String permission : reward.getPermissions()) {
|
||||
rewardInfo.append("<li>").append("Permission: ").append(permission).append("</li>");
|
||||
}
|
||||
|
||||
for (ItemStack item : reward.getItems()) {
|
||||
rewardInfo.append("<li>").append(uppercaseFirst(getItemStackString(item))).append("</li>");
|
||||
}
|
||||
|
||||
for (String command : reward.getCommands()) {
|
||||
rewardInfo.append("<li>Command: ").append(command).append("</li>");
|
||||
}
|
||||
|
||||
rewardInfo.append("</ul>");
|
||||
return rewardInfo.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currency to print for the given amount of money
|
||||
*
|
||||
* @param money <p>The amount to pay/use</p>
|
||||
* @return <p>The currency name to use</p>
|
||||
*/
|
||||
private String getCurrency(double money) {
|
||||
VaultHandler vaultHandler = DynmapCitizens.getInstance().getVaultHandler();
|
||||
if (vaultHandler.isEnabled()) {
|
||||
return vaultHandler.getCurrency(money != 1);
|
||||
} else {
|
||||
return "money";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the marker title to use for the given quest NPC type
|
||||
*
|
||||
* @param type <p>The type of marker to get the title for</p>
|
||||
* @return <p>The title to use for the marker</p>
|
||||
*/
|
||||
private String getMarkerTitle(QuestNPCType type) {
|
||||
return switch (type) {
|
||||
case GIVER -> "Quest Start NPC: ";
|
||||
case INTERACT -> "Quest Interact NPC: ";
|
||||
case DELIVER -> "Quest Deliver NPC: ";
|
||||
case KILL -> "Quest Kill NPC: ";
|
||||
case CHAIN -> "Quest Chain NPC: ";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the info object for the given NPC
|
||||
*
|
||||
* @param npcId <p>The id of the NPC to get information about</p>
|
||||
* @return <p>The NPC's info object</p>
|
||||
*/
|
||||
private NPCQuestInfo getInfo(UUID npcId) {
|
||||
if (questGiverInfo.get(npcId) == null) {
|
||||
questGiverInfo.put(npcId, new NPCQuestInfo());
|
||||
}
|
||||
return questGiverInfo.get(npcId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all quest area markers
|
||||
*/
|
||||
private void updateQuestAreas() {
|
||||
questAreaMarkerSet.getCircleMarkers().forEach(GenericMarker::deleteMarker);
|
||||
for (IQuest quest : questsAPI.getLoadedQuests()) {
|
||||
for (IStage stage : quest.getStages()) {
|
||||
markKillLocations(quest, stage);
|
||||
markReachLocations(quest, stage);
|
||||
}
|
||||
}
|
||||
//TODO: Mark WorldGuard areas part of quests. Requires WorldGuard integration
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about a quest's stages
|
||||
*
|
||||
* @param quest <p>The quest to get information about</p>
|
||||
* @return <p>A string with information about the quest's stages</p>
|
||||
*/
|
||||
private String getQuestStagesInfo(IQuest quest) {
|
||||
StringBuilder questInfo = new StringBuilder();
|
||||
NPCRegistry registry = CitizensAPI.getNPCRegistry();
|
||||
for (IStage stage : quest.getStages()) {
|
||||
questInfo.append("<b>Tasks:</b><ul>");
|
||||
int mobTypes = stage.getMobsToKill().size();
|
||||
for (int i = 0; i < mobTypes; i++) {
|
||||
questInfo.append("<li>Kill ").append(normalizeName(stage.getMobsToKill().get(i).name())).append(
|
||||
" X ").append(stage.getMobNumToKill().get(i)).append("</li>");
|
||||
}
|
||||
int deliveries = stage.getItemDeliveryTargets().size();
|
||||
for (int i = 0; i < deliveries; i++) {
|
||||
NPC npc = registry.getByUniqueId(stage.getItemDeliveryTargets().get(i));
|
||||
questInfo.append("<li>Deliver ").append(getItemStackString(stage.getItemsToDeliver().get(i))).append(
|
||||
" to ").append(npc.getName()).append("</li>");
|
||||
}
|
||||
if (stage.getFishToCatch() != null) {
|
||||
questInfo.append("<li>Catch ").append(stage.getFishToCatch()).append(" fish").append("</li>");
|
||||
}
|
||||
for (UUID npcId : stage.getNpcsToKill()) {
|
||||
questInfo.append("<li>Kill NPC ").append(registry.getByUniqueId(npcId).getName()).append("</li>");
|
||||
}
|
||||
|
||||
questInfo.append(getQuestItemsTaskString(stage.getBlocksToBreak(), "<li>Break ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getBlocksToCut(), "<li>Cut ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getBlocksToDamage(), "<li>Damage ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getBlocksToUse(), "<li>Use ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getBlocksToPlace(), "<li>Place ")).append("</li>");
|
||||
|
||||
questInfo.append(getQuestItemsTaskString(stage.getItemsToBrew(), "<li>Brew ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getItemsToConsume(), "<li>Consume ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getItemsToCraft(), "<li>Craft ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getItemsToEnchant(), "<li>Enchant ")).append("</li>");
|
||||
questInfo.append(getQuestItemsTaskString(stage.getItemsToSmelt(), "<li>Smelt ")).append("</li>");
|
||||
|
||||
int sheepTypes = stage.getSheepToShear().size();
|
||||
for (int i = 0; i < sheepTypes; i++) {
|
||||
questInfo.append("<li>Shear ").append(stage.getSheepNumToShear().get(i)).append(" ").append(
|
||||
normalizeName(stage.getSheepToShear().get(i).name())).append(" sheep").append("</li>");
|
||||
}
|
||||
if (stage.getCowsToMilk() != null) {
|
||||
questInfo.append("<li>Milk ").append(stage.getCowsToMilk()).append(" cows").append("</li>");
|
||||
}
|
||||
|
||||
int mobTamingEntries = stage.getMobsToTame().size();
|
||||
for (int i = 0; i < mobTamingEntries; i++) {
|
||||
questInfo.append("<li>Tame ").append(stage.getMobNumToTame().get(i)).append(" ").append(
|
||||
normalizeName(stage.getMobsToTame().get(i).name())).append("</li>");
|
||||
}
|
||||
|
||||
questInfo.append("</ul>");
|
||||
}
|
||||
return questInfo.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string to display a quest task involving some action on an item
|
||||
*
|
||||
* @param items <p>The items that are part of the task</p>
|
||||
* @param explanation <p>The explanation of what the player needs to do with the items</p>
|
||||
* @return <p>A string describing the necessary tasks</p>
|
||||
*/
|
||||
private String getQuestItemsTaskString(List<ItemStack> items, String explanation) {
|
||||
StringBuilder questInfo = new StringBuilder();
|
||||
for (ItemStack itemStack : items) {
|
||||
questInfo.append(explanation).append(getItemStackString(itemStack));
|
||||
}
|
||||
return questInfo.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the proper string representation of an item stack
|
||||
*
|
||||
* @param itemStack <p>The item stack to print</p>
|
||||
* @return <p>The string representation of the item stack</p>
|
||||
*/
|
||||
private String getItemStackString(ItemStack itemStack) {
|
||||
return normalizeName(itemStack.getType().name()) + " X " + itemStack.getAmount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the first character in a string uppercase
|
||||
*
|
||||
* @param string <p>The string to run on</p>
|
||||
* @return <p>The same string, with the first character converted to uppercase</p>
|
||||
*/
|
||||
private String uppercaseFirst(String string) {
|
||||
return string.substring(0, 1).toUpperCase() + string.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes an internal name to make it human-readable
|
||||
*
|
||||
* @param name <p>The name to normalize</p>
|
||||
* @return <p>The normalized name</p>
|
||||
*/
|
||||
private String normalizeName(String name) {
|
||||
return name.toLowerCase().replace("_", " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks any reach locations found in the given stage
|
||||
*
|
||||
* @param quest <p>The quest the stage belongs to</p>
|
||||
* @param stage <p>The stage to search for reach locations</p>
|
||||
*/
|
||||
private void markReachLocations(IQuest quest, IStage stage) {
|
||||
markLocations(stage.getLocationsToReach(), stage.getRadiiToReachWithin(),
|
||||
"<b>Target location for:</b> " + quest.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks any kill locations found in the given stage
|
||||
*
|
||||
* @param quest <p>The quest the stage belongs to</p>
|
||||
* @param stage <p>The stage to search for kill locations</p>
|
||||
*/
|
||||
private void markKillLocations(IQuest quest, IStage stage) {
|
||||
markLocations(stage.getLocationsToKillWithin(), stage.getRadiiToKillWithin(),
|
||||
"<b>Kill location for:</b> " + quest.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given locations on the dynamic map
|
||||
*
|
||||
* @param locations <p>The locations to mark</p>
|
||||
* @param radii <p>The radius of each location's circle</p>
|
||||
* @param description <p>The description for what the location means</p>
|
||||
*/
|
||||
private void markLocations(List<Location> locations, List<Integer> radii, String description) {
|
||||
for (int i = 0; i < locations.size(); i++) {
|
||||
Location location = locations.get(i);
|
||||
int radius = radii.get(i);
|
||||
|
||||
//Skip if location is invalid
|
||||
World world = location.getWorld();
|
||||
if (world == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CircleMarker circleMarker = questAreaMarkerSet.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(0.3, 0x75AFD2);
|
||||
circleMarker.setLineStyle(1, 1.0, 0x36c90e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package net.knarcraft.dynmapcitizens.util;
|
||||
|
||||
import net.knarcraft.dynmapcitizens.DynmapCitizens;
|
||||
import net.knarcraft.dynmapcitizens.handler.VaultHandler;
|
||||
import net.knarcraft.dynmapcitizens.handler.trait.quests.QuestNPCType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* A helper class for various quests-related tasks
|
||||
*/
|
||||
public class QuestsHelper {
|
||||
|
||||
/**
|
||||
* Gets an item stack string with the first character upper-cased
|
||||
*
|
||||
* @param itemStack <p>The item stack to get the string for</p>
|
||||
* @return <p>A string describing the item stack</p>
|
||||
*/
|
||||
public static String getUpperCasedItemStackString(ItemStack itemStack) {
|
||||
return uppercaseFirst(getItemStackString(itemStack));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the proper string representation of an item stack
|
||||
*
|
||||
* @param itemStack <p>The item stack to print</p>
|
||||
* @return <p>The string representation of the item stack</p>
|
||||
*/
|
||||
public static String getItemStackString(ItemStack itemStack) {
|
||||
return normalizeName(itemStack.getType().name()) + " x " + itemStack.getAmount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the first character in a string uppercase
|
||||
*
|
||||
* @param string <p>The string to run on</p>
|
||||
* @return <p>The same string, with the first character converted to uppercase</p>
|
||||
*/
|
||||
private static String uppercaseFirst(String string) {
|
||||
return string.substring(0, 1).toUpperCase() + string.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes an internal name to make it human-readable
|
||||
*
|
||||
* @param name <p>The name to normalize</p>
|
||||
* @return <p>The normalized name</p>
|
||||
*/
|
||||
public static String normalizeName(String name) {
|
||||
return name.toLowerCase().replace("_", " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currency to print for the given amount of money
|
||||
*
|
||||
* @param money <p>The amount to pay/use</p>
|
||||
* @return <p>The currency name to use</p>
|
||||
*/
|
||||
public static String getCurrency(double money) {
|
||||
VaultHandler vaultHandler = DynmapCitizens.getInstance().getVaultHandler();
|
||||
if (vaultHandler.isEnabled()) {
|
||||
return vaultHandler.getCurrency(money != 1);
|
||||
} else {
|
||||
return "money";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the marker title to use for the given quest NPC type
|
||||
*
|
||||
* @param type <p>The type of marker to get the title for</p>
|
||||
* @return <p>The title to use for the marker</p>
|
||||
*/
|
||||
public static String getMarkerTitle(QuestNPCType type) {
|
||||
return switch (type) {
|
||||
case GIVER -> "Quest Start NPC: ";
|
||||
case INTERACT -> "Quest Interact NPC: ";
|
||||
case DELIVER -> "Quest Deliver NPC: ";
|
||||
case KILL -> "Quest Kill NPC: ";
|
||||
case CHAIN -> "Quest Chain NPC: ";
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package net.knarcraft.dynmapcitizens.util;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.knarcraft.blacksmith.formatting.StringFormatter.replacePlaceholder;
|
||||
|
||||
/**
|
||||
* A helper class for time formatting
|
||||
*/
|
||||
public class TimeFormatter {
|
||||
|
||||
/**
|
||||
* Gets a datetime string for the given timestamp
|
||||
*
|
||||
* @param timestamp <p>A timestamp in milliseconds</p>
|
||||
* @return <p>A datetime string</p>
|
||||
*/
|
||||
public static String formatTimestamp(long timestamp) {
|
||||
DateFormat format = new SimpleDateFormat("dd MM yyyy HH:mm:ss");
|
||||
Date date = new Date(timestamp);
|
||||
return format.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string used for displaying this sign's duration
|
||||
*
|
||||
* @return <p>The string used for displaying this sign's duration</p>
|
||||
*/
|
||||
public static String getDurationString(long duration) {
|
||||
if (duration == 0) {
|
||||
return "immediately";
|
||||
} else {
|
||||
double minute = 60;
|
||||
double hour = minute * 60;
|
||||
double day = hour * 24;
|
||||
double week = day * 7;
|
||||
double month = day * 30;
|
||||
double year = day * 365;
|
||||
double decade = year * 10;
|
||||
|
||||
Map<Double, String[]> timeUnits = new HashMap<>();
|
||||
timeUnits.put(decade, new String[]{"decade", "decades"});
|
||||
timeUnits.put(year, new String[]{"year", "years"});
|
||||
timeUnits.put(month, new String[]{"month", "months"});
|
||||
timeUnits.put(week, new String[]{"week", "weeks"});
|
||||
timeUnits.put(day, new String[]{"day", "days"});
|
||||
timeUnits.put(hour, new String[]{"hour", "hours"});
|
||||
timeUnits.put(minute, new String[]{"minute", "minutes"});
|
||||
timeUnits.put(1D, new String[]{"second", "seconds"});
|
||||
|
||||
List<Double> sortedUnits = new ArrayList<>(timeUnits.keySet());
|
||||
Collections.sort(sortedUnits);
|
||||
Collections.reverse(sortedUnits);
|
||||
|
||||
for (Double unit : sortedUnits) {
|
||||
if (duration / unit >= 1) {
|
||||
double units = round(duration / unit);
|
||||
return formatDurationString(units, timeUnits.get(unit)[units == 1 ? 0 : 1],
|
||||
(units * 10) % 10 == 0);
|
||||
}
|
||||
}
|
||||
return formatDurationString(duration, "seconds", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds a number to its last two digits
|
||||
*
|
||||
* @param number <p>The number to round</p>
|
||||
* @return <p>The rounded number</p>
|
||||
*/
|
||||
private static double round(double number) {
|
||||
return Math.round(number * 100.0) / 100.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a duration string
|
||||
*
|
||||
* @param duration <p>The duration to display</p>
|
||||
* @param translatableMessage <p>The time unit to display</p>
|
||||
* @param castToInt <p>Whether to cast the duration to an int</p>
|
||||
* @return <p>The formatted duration string</p>
|
||||
*/
|
||||
private static String formatDurationString(double duration, String translatableMessage, boolean castToInt) {
|
||||
String durationFormat = "{duration} {unit}";
|
||||
durationFormat = replacePlaceholder(durationFormat, "{unit}", translatableMessage);
|
||||
return replacePlaceholder(durationFormat, "{duration}", castToInt ? String.valueOf((int) duration) :
|
||||
String.valueOf(duration));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user