Adds information about kill and delivery tasks to the quest start description

This commit is contained in:
Kristian Knarvik 2022-10-20 20:40:17 +02:00
parent 607a054464
commit a0266f30f3
4 changed files with 101 additions and 11 deletions

View File

@ -77,4 +77,14 @@ public abstract class AbstractTraitHandler implements CitizensTraitHandler {
} }
} }
/**
* Gets whether the given NPC is currently moving
*
* @param npc <p>The NPC to check</p>
* @return <p>True if the NPC is currently moving about</p>
*/
protected boolean isMoving(NPC npc) {
return npc.getNavigator().getTargetAsLocation() != null;
}
} }

View File

@ -34,6 +34,7 @@ public class BlacksmithHandler extends AbstractTraitHandler {
blacksmithSet = getMarkerSet(dynmapAPI, "blacksmiths", "Blacksmiths"); blacksmithSet = getMarkerSet(dynmapAPI, "blacksmiths", "Blacksmiths");
if (blacksmithSet != null) { if (blacksmithSet != null) {
blacksmithSet.setHideByDefault(false); blacksmithSet.setHideByDefault(false);
blacksmithSet.setLayerPriority(3);
isEnabled = true; isEnabled = true;
return; return;
} }

View File

@ -3,18 +3,22 @@ package net.knarcraft.dynmapcitizens.trait;
import me.blackvein.quests.QuestsAPI; import me.blackvein.quests.QuestsAPI;
import me.blackvein.quests.quests.IQuest; import me.blackvein.quests.quests.IQuest;
import me.blackvein.quests.quests.IStage; import me.blackvein.quests.quests.IStage;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC;
import net.knarcraft.dynmapcitizens.DynmapCitizens; import net.knarcraft.dynmapcitizens.DynmapCitizens;
import net.knarcraft.dynmapcitizens.Icon; import net.knarcraft.dynmapcitizens.Icon;
import net.knarcraft.dynmapcitizens.UpdateRate; import net.knarcraft.dynmapcitizens.UpdateRate;
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.inventory.ItemStack;
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;
import org.dynmap.markers.MarkerIcon; import org.dynmap.markers.MarkerIcon;
import org.dynmap.markers.MarkerSet; import org.dynmap.markers.MarkerSet;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -29,6 +33,7 @@ public class QuestsHandler extends AbstractTraitHandler {
private MarkerSet questMarkerSet; private MarkerSet questMarkerSet;
private MarkerSet questAreaMarkerSet; private MarkerSet questAreaMarkerSet;
private Map<Icon, MarkerIcon> markerIcons; private Map<Icon, MarkerIcon> markerIcons;
private Collection<IQuest> loadedQuests;
@Override @Override
public void initialize() { public void initialize() {
@ -41,6 +46,8 @@ public class QuestsHandler extends AbstractTraitHandler {
if (questMarkerSet != null && questAreaMarkerSet != null) { if (questMarkerSet != null && questAreaMarkerSet != null) {
questMarkerSet.setHideByDefault(false); questMarkerSet.setHideByDefault(false);
questAreaMarkerSet.setHideByDefault(true); questAreaMarkerSet.setHideByDefault(true);
questMarkerSet.setLayerPriority(3);
questAreaMarkerSet.setLayerPriority(2);
isEnabled = true; isEnabled = true;
return; return;
} }
@ -59,24 +66,97 @@ public class QuestsHandler extends AbstractTraitHandler {
return; 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 //Remove old quest markers
questMarkerSet.getMarkers().forEach(GenericMarker::deleteMarker); questMarkerSet.getMarkers().forEach(GenericMarker::deleteMarker);
questAreaMarkerSet.getCircleMarkers().forEach(GenericMarker::deleteMarker);
//Updates all quest area markers
if (questsChanged) {
updateQuestAreas();
}
for (IQuest quest : questsAPI.getLoadedQuests()) { for (IQuest quest : questsAPI.getLoadedQuests()) {
UUID npcStartId = quest.getNpcStart(); UUID npcStartId = quest.getNpcStart();
//TODO: Store locations of NPCs and see if they've moved?
// there should probably be a priority and a combination for NPC markers.
// Use the npc ID as the marker id. If it already exists, try and add additional information. Use priority
// to decide if icon needs to be changed.
if (npcStartId != null) { if (npcStartId != null) {
String markerDescription = "<b>Quest name:</b> " + quest.getName() + "<br><b>Quest description:</b> " + quest.getDescription(); String markerDescription = "<b>Quest name:</b> " + quest.getName() + "<br><b>Quest description:</b> " +
addNPCMarker(npcStartId, "Quest Start NPC: ", markerDescription, markerIcons.get(Icon.QUEST_GIVER), questMarkerSet); quest.getDescription() + getQuestStagesInfo(quest);
addNPCMarker(npcStartId, "Quest Start NPC: ", markerDescription,
markerIcons.get(Icon.QUEST_GIVER), questMarkerSet);
} }
//TODO: Perhaps display requirements and rewards as part of the description
//Mark NPCs related to this quest
for (IStage stage : quest.getStages()) { for (IStage stage : quest.getStages()) {
markNPCsInQuest(quest, stage, npcStartId); markNPCsInQuest(quest, stage, npcStartId);
}
}
}
/**
* 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); markKillLocations(quest, stage);
markReachLocations(quest, stage); markReachLocations(quest, stage);
}
}
//TODO: Mark WorldGuard areas part of quests. Requires WorldGuard integration //TODO: Mark WorldGuard areas part of quests. Requires WorldGuard integration
//TODO: See if there is anything to do against overlapping markers //TODO: See if there is anything to do against overlapping markers
} }
/**
* 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();
for (IStage stage : quest.getStages()) {
questInfo.append("<br><b>Tasks:</b> ");
int mobTypes = stage.getMobsToKill().size();
for (int i = 0; i < mobTypes; i++) {
questInfo.append("<br>Kill ").append(stage.getMobNumToKill().get(i)).append(" ").append(
normalizeName(stage.getMobsToKill().get(i).name()));
} }
int deliveries = stage.getItemDeliveryTargets().size();
for (int i = 0; i < deliveries; i++) {
NPC npc = CitizensAPI.getNPCRegistry().getByUniqueId(stage.getItemDeliveryTargets().get(i));
questInfo.append("<br>Deliver ").append(getItemStackString(stage.getItemsToDeliver().get(i))).append(
" to ").append(npc.getName());
}
}
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 itemStack.getAmount() + " " + normalizeName(itemStack.getType().name());
}
/**
* 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("_", " ");
} }
/** /**
@ -87,8 +167,7 @@ public class QuestsHandler extends AbstractTraitHandler {
*/ */
private void markReachLocations(IQuest quest, IStage stage) { private void markReachLocations(IQuest quest, IStage stage) {
markLocations(stage.getLocationsToReach(), stage.getRadiiToReachWithin(), markLocations(stage.getLocationsToReach(), stage.getRadiiToReachWithin(),
"<b>Target location for:</b> " + quest.getName() + "<br><b>Description:</b> " + "<b>Target location for:</b> " + quest.getName());
quest.getDescription());
} }
/** /**
@ -99,8 +178,7 @@ public class QuestsHandler extends AbstractTraitHandler {
*/ */
private void markKillLocations(IQuest quest, IStage stage) { private void markKillLocations(IQuest quest, IStage stage) {
markLocations(stage.getLocationsToKillWithin(), stage.getRadiiToKillWithin(), markLocations(stage.getLocationsToKillWithin(), stage.getRadiiToKillWithin(),
"<b>Kill location for:</b> " + quest.getName() + "<br><b>Description:</b> " + "<b>Kill location for:</b> " + quest.getName());
quest.getDescription());
} }
/** /**

View File

@ -28,6 +28,7 @@ public class SentinelHandler extends AbstractTraitHandler {
sentinelSet = getMarkerSet(dynmapAPI, "sentinels", "Sentinels"); sentinelSet = getMarkerSet(dynmapAPI, "sentinels", "Sentinels");
if (sentinelSet != null) { if (sentinelSet != null) {
sentinelSet.setHideByDefault(false); sentinelSet.setHideByDefault(false);
sentinelSet.setLayerPriority(1);
isEnabled = true; isEnabled = true;
return; return;
} }