Adds information about a quests time-limitations

This commit is contained in:
Kristian Knarvik 2022-11-01 16:35:51 +01:00
parent b81742b1bb
commit 7767a3f3eb

View File

@ -3,6 +3,7 @@ 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;
@ -22,7 +23,12 @@ 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;
@ -30,6 +36,8 @@ 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
*/
@ -124,11 +132,11 @@ public class QuestsHandler extends AbstractTraitHandler {
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)).append("</li>");
markerDescription.append(getQuestRewardsInfo(quest)).append(getQuestRequirementsInfo(quest));
markerDescription.append(getQuestPlannerInfo(quest)).append("</li>");
}
markerDescription.append("</ul>");
}
//TODO: Get information about the planner (repeatable and/or limited)
if (!questKills.isEmpty() || !questInteractions.isEmpty() || !questDeliveries.isEmpty()) {
markerDescription.append("<h3>Involved in quests:</h3><ul>");
@ -150,6 +158,112 @@ public class QuestsHandler extends AbstractTraitHandler {
}
}
/**
* 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 is repeatable
if (planner.hasRepeat()) {
plannerInfo.append("<li>Can be repeated after ").append(getDurationString(planner.getRepeat() / 1000));
}
//Quest has cool-down
if (planner.hasCooldown()) {
plannerInfo.append("<li>Cool-down: ").append(getDurationString(planner.getCooldown() / 1000)).append("</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>");
}
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
*
@ -308,7 +422,6 @@ public class QuestsHandler extends AbstractTraitHandler {
}
}
//TODO: Mark WorldGuard areas part of quests. Requires WorldGuard integration
//TODO: See if there is anything to do against overlapping markers
}
/**