Adds quest area marker improvements

Adds missing information about reach area tasks to marker descriptions
Adds separate styling for reach locations and kill locations
Improves information for quest area markers, by using the proper location name, and listing mobs to kill within an area.
This commit is contained in:
Kristian Knarvik 2022-11-03 01:05:30 +01:00
parent 5cd3eac7ff
commit 3d78e16c59
3 changed files with 75 additions and 29 deletions

View File

@ -71,6 +71,8 @@ public abstract class AbstractTraitHandler implements CitizensTraitHandler {
return; return;
} }
//TODO: If marker already exists, and the NPC is in the same location, check if description has changed. If changed, update it. If not, do nothing.
Marker marker = markerSet.createMarker(npcId.toString(), markerName + npc.getName(), Marker marker = markerSet.createMarker(npcId.toString(), markerName + npc.getName(),
npcLocation.getWorld().getName(), npcLocation.getX(), npcLocation.getY(), npcLocation.getZ(), icon, npcLocation.getWorld().getName(), npcLocation.getX(), npcLocation.getY(), npcLocation.getZ(), icon,
false); false);

View File

@ -6,6 +6,7 @@ import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPCRegistry; import net.citizensnpcs.api.npc.NPCRegistry;
import net.knarcraft.dynmapcitizens.util.QuestsHelper; import net.knarcraft.dynmapcitizens.util.QuestsHelper;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.util.List; import java.util.List;
@ -41,9 +42,16 @@ public class QuestStagesInfoGenerator {
questInfo.append("<li><b>Stage ").append(stageCounter).append(" tasks:</b><ul>"); questInfo.append("<li><b>Stage ").append(stageCounter).append(" tasks:</b><ul>");
int mobTypes = stage.getMobsToKill().size(); int mobTypes = stage.getMobsToKill().size();
for (int i = 0; i < mobTypes; i++) { for (int i = 0; i < mobTypes; i++) {
questInfo.append("<li>Kill ").append(QuestsHelper.normalizeName(stage.getMobsToKill().get(i).name())).append( questInfo.append("<li>Kill ").append(QuestsHelper.normalizeName(stage.getMobsToKill().get(i).name()));
" x ").append(stage.getMobNumToKill().get(i)).append("</li>"); questInfo.append(" x ").append(stage.getMobNumToKill().get(i)).append("</li>");
} }
int reachLocations = stage.getLocationsToReach().size();
for (int i = 0; i < reachLocations; i++) {
questInfo.append("<li>Reach ").append(stage.getLocationNames().get(i)).append(", within ");
questInfo.append(stage.getRadiiToReachWithin().get(i)).append(" blocks of ");
questInfo.append(getLocationString(stage.getLocationsToReach().get(i))).append("</li>");
}
int deliveries = stage.getItemDeliveryTargets().size(); int deliveries = stage.getItemDeliveryTargets().size();
for (int i = 0; i < deliveries; i++) { for (int i = 0; i < deliveries; i++) {
NPC npc = registry.getByUniqueId(stage.getItemDeliveryTargets().get(i)); NPC npc = registry.getByUniqueId(stage.getItemDeliveryTargets().get(i));
@ -91,6 +99,20 @@ public class QuestStagesInfoGenerator {
return questInfo.toString(); return questInfo.toString();
} }
/**
* Gets a user-friendly string-representation of the given location
*
* @param location <p>The location to show</p>
* @return <p>A human-friendly location string</p>
*/
private String getLocationString(Location location) {
String locationString = location.getX() + "," + location.getY() + "," + location.getZ();
if (location.getWorld() != null) {
locationString += " in world \"" + location.getWorld().getName() + "\"";
}
return locationString;
}
/** /**
* Gets a string to display a quest task involving some action on an item * Gets a string to display a quest task involving some action on an item
* *

View File

@ -12,6 +12,7 @@ import net.knarcraft.dynmapcitizens.util.QuestsHelper;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.dynmap.DynmapAPI; import org.dynmap.DynmapAPI;
import org.dynmap.markers.CircleMarker; import org.dynmap.markers.CircleMarker;
import org.dynmap.markers.GenericMarker; import org.dynmap.markers.GenericMarker;
@ -205,6 +206,7 @@ public class QuestsHandler extends AbstractTraitHandler {
questAreaMarkerSet.getCircleMarkers().forEach(GenericMarker::deleteMarker); questAreaMarkerSet.getCircleMarkers().forEach(GenericMarker::deleteMarker);
for (IQuest quest : questsAPI.getLoadedQuests()) { for (IQuest quest : questsAPI.getLoadedQuests()) {
for (IStage stage : quest.getStages()) { for (IStage stage : quest.getStages()) {
//TODO: Put kill and reach locations in separate marker sets
markKillLocations(quest, stage); markKillLocations(quest, stage);
markReachLocations(quest, stage); markReachLocations(quest, stage);
} }
@ -219,8 +221,17 @@ public class QuestsHandler extends AbstractTraitHandler {
* @param stage <p>The stage to search for reach locations</p> * @param stage <p>The stage to search for reach locations</p>
*/ */
private void markReachLocations(IQuest quest, IStage stage) { private void markReachLocations(IQuest quest, IStage stage) {
markLocations(stage.getLocationsToReach(), stage.getRadiiToReachWithin(), for (int i = 0; i < stage.getLocationsToReach().size(); i++) {
"<b>Target location for:</b> " + quest.getName()); Location location = stage.getLocationsToReach().get(i);
int radius = stage.getRadiiToReachWithin().get(i);
String areaName = stage.getLocationNames().get(i);
String description = "";
if (areaName != null) {
description += "<b>" + areaName + "</b><br>";
}
description += "Target location for " + quest.getName();
markLocation(location, radius, description, "FFFF99", "36c90e");
}
} }
/** /**
@ -230,37 +241,48 @@ public class QuestsHandler extends AbstractTraitHandler {
* @param stage <p>The stage to search for kill locations</p> * @param stage <p>The stage to search for kill locations</p>
*/ */
private void markKillLocations(IQuest quest, IStage stage) { private void markKillLocations(IQuest quest, IStage stage) {
markLocations(stage.getLocationsToKillWithin(), stage.getRadiiToKillWithin(), for (int i = 0; i < stage.getLocationsToKillWithin().size(); i++) {
"<b>Kill location for:</b> " + quest.getName()); 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 += "<b>" + areaName + "</b><br>";
}
description += "Kill location for " + quest.getName() +
"<br>Kill " + QuestsHelper.normalizeName(mob.name()) + " x " + mobAmount;
markLocation(location, radius, description, "EDAFA0", "8B0000");
}
} }
/** /**
* Marks the given locations on the dynamic map * Marks a location on the dynamic map
* *
* @param locations <p>The locations to mark</p> * @param location <p>The location to mark</p>
* @param radii <p>The radius of each location's circle</p> * @param radius <p>The radius of the circular area to mark</p>
* @param description <p>The description for what the location means</p> * @param description <p>The description to put on the marker</p>
* @param fillColor <p>The color to use inside the marker area</p>
* @param lineColor <p>The color to use outside the marker area</p>
*/ */
private void markLocations(List<Location> locations, List<Integer> radii, String description) { private void markLocation(Location location, Integer radius, String description, String fillColor, String lineColor) {
for (int i = 0; i < locations.size(); i++) { //Skip if location is invalid
Location location = locations.get(i); World world = location.getWorld();
int radius = radii.get(i); if (world == null) {
return;
}
//Skip if location is invalid CircleMarker circleMarker = questAreaMarkerSet.createCircleMarker(null, description, true,
World world = location.getWorld(); world.getName(), location.getX(), location.getY(), location.getZ(), radius, radius, false);
if (world == null) { if (circleMarker == null) {
continue; DynmapCitizens.getInstance().getLogger().log(Level.WARNING, "Unable to create circle marker at " +
} location + " with radius " + radius);
} else {
CircleMarker circleMarker = questAreaMarkerSet.createCircleMarker(null, description, true, //TODO: Make colors configurable
world.getName(), location.getX(), location.getY(), location.getZ(), radius, radius, false); circleMarker.setFillStyle(0.3, Integer.parseInt(fillColor, 16));
if (circleMarker == null) { circleMarker.setLineStyle(2, 1.0, Integer.parseInt(lineColor, 16));
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);
}
} }
} }