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;
}
//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(),
npcLocation.getWorld().getName(), npcLocation.getX(), npcLocation.getY(), npcLocation.getZ(), icon,
false);

View File

@ -6,6 +6,7 @@ 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.Location;
import org.bukkit.inventory.ItemStack;
import java.util.List;
@ -41,9 +42,16 @@ public class QuestStagesInfoGenerator {
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>");
questInfo.append("<li>Kill ").append(QuestsHelper.normalizeName(stage.getMobsToKill().get(i).name()));
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();
for (int i = 0; i < deliveries; i++) {
NPC npc = registry.getByUniqueId(stage.getItemDeliveryTargets().get(i));
@ -91,6 +99,20 @@ public class QuestStagesInfoGenerator {
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
*

View File

@ -12,6 +12,7 @@ import net.knarcraft.dynmapcitizens.util.QuestsHelper;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.dynmap.DynmapAPI;
import org.dynmap.markers.CircleMarker;
import org.dynmap.markers.GenericMarker;
@ -205,6 +206,7 @@ public class QuestsHandler extends AbstractTraitHandler {
questAreaMarkerSet.getCircleMarkers().forEach(GenericMarker::deleteMarker);
for (IQuest quest : questsAPI.getLoadedQuests()) {
for (IStage stage : quest.getStages()) {
//TODO: Put kill and reach locations in separate marker sets
markKillLocations(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>
*/
private void markReachLocations(IQuest quest, IStage stage) {
markLocations(stage.getLocationsToReach(), stage.getRadiiToReachWithin(),
"<b>Target location for:</b> " + quest.getName());
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 += "<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>
*/
private void markKillLocations(IQuest quest, IStage stage) {
markLocations(stage.getLocationsToKillWithin(), stage.getRadiiToKillWithin(),
"<b>Kill location for:</b> " + quest.getName());
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 += "<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 radii <p>The radius of each location's circle</p>
* @param description <p>The description for what the location means</p>
* @param location <p>The location to mark</p>
* @param radius <p>The radius of the circular area to mark</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) {
for (int i = 0; i < locations.size(); i++) {
Location location = locations.get(i);
int radius = radii.get(i);
private void markLocation(Location location, Integer radius, String description, String fillColor, String lineColor) {
//Skip if location is invalid
World world = location.getWorld();
if (world == null) {
return;
}
//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);
}
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 {
//TODO: Make colors configurable
circleMarker.setFillStyle(0.3, Integer.parseInt(fillColor, 16));
circleMarker.setLineStyle(2, 1.0, Integer.parseInt(lineColor, 16));
}
}