Initial commit

This commit is contained in:
2022-10-19 02:44:44 +02:00
commit c3c5263425
6 changed files with 565 additions and 0 deletions

View File

@ -0,0 +1,99 @@
package net.knarcraft.questsdynmap;
import me.blackvein.quests.QuestsAPI;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.dynmap.DynmapAPI;
import org.dynmap.markers.MarkerAPI;
import org.dynmap.markers.MarkerIcon;
import org.dynmap.markers.MarkerSet;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
@SuppressWarnings("unused")
public final class DynmapCitizens extends JavaPlugin {
private static DynmapCitizens instance;
@Override
public void onEnable() {
instance = this;
//Initialize quest and dynmap APIs
PluginManager pluginManager = Bukkit.getPluginManager();
Plugin dynmapPlugin = pluginManager.getPlugin("dynmap");
if (!(dynmapPlugin instanceof DynmapAPI dynmapAPI) || dynmapAPI.getMarkerAPI() == null) {
this.getLogger().log(Level.SEVERE, "Could not initialize Dynmap");
this.onDisable();
return;
}
QuestsAPI questsAPI = (QuestsAPI) Bukkit.getServer().getPluginManager().getPlugin("Quests");
MarkerSet questMarkerSet = getMarkerSet(dynmapAPI, "quests", "Quests");
MarkerSet questAreaMarkerSet = getMarkerSet(dynmapAPI, "quest_areas", "Quest areas");
MarkerSet blacksmithSet = getMarkerSet(dynmapAPI, "blacksmiths", "Blacksmiths");
if (questMarkerSet == null || questAreaMarkerSet == null || blacksmithSet == null) {
return;
}
//TODO: Perhaps make this configurable
questMarkerSet.setHideByDefault(false);
questAreaMarkerSet.setHideByDefault(true);
blacksmithSet.setHideByDefault(false);
//TODO: Make every icon configurable
MarkerAPI markerAPI = dynmapAPI.getMarkerAPI();
Map<Icon, MarkerIcon> markerIcons = new HashMap<>();
markerIcons.put(Icon.QUEST_GIVER, markerAPI.getMarkerIcon("exclamation"));
markerIcons.put(Icon.QUEST_DELIVER, markerAPI.getMarkerIcon("basket"));
markerIcons.put(Icon.QUEST_KILL, markerAPI.getMarkerIcon("skull"));
markerIcons.put(Icon.QUEST_INTERACT, markerAPI.getMarkerIcon("comment"));
markerIcons.put(Icon.BLACKSMITH, markerAPI.getMarkerIcon("hammer"));
DynmapDrawer.initialize(questsAPI, questMarkerSet, questAreaMarkerSet, blacksmithSet, markerIcons);
Bukkit.getScheduler().runTaskTimer(this, this::updateIcons, 10 * 20, 120 * 20);
}
@Override
public void onDisable() {
// Plugin shutdown logic
}
/**
* Gets an instance of this plugin
*
* @return <p>An instance of this plugin</p>
*/
public static DynmapCitizens getInstance() {
return instance;
}
/**
* Gets the given marker set (and creates it if necessary)
*
* @param dynmapAPI <p>A reference to dynmap's API</p>
* @param setId <p>The id of the marker set to get</p>
* @param label <p>The label of the marker set if creation is necessary</p>
* @return <p>The marker set, or null if something went wrong</p>
*/
private MarkerSet getMarkerSet(DynmapAPI dynmapAPI, String setId, String label) {
MarkerSet markerSet = dynmapAPI.getMarkerAPI().getMarkerSet(setId);
if (markerSet == null) {
markerSet = dynmapAPI.getMarkerAPI().createMarkerSet(setId, label, null, false);
if (markerSet == null) {
this.getLogger().log(Level.SEVERE, "Unable to get or create " + setId + " marker set");
this.onDisable();
return null;
}
}
return markerSet;
}
private void updateIcons() {
DynmapDrawer.updateCitizensMarkers();
}
}

View File

@ -0,0 +1,211 @@
package net.knarcraft.questsdynmap;
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.NPC;
import net.citizensnpcs.api.trait.Trait;
import org.bukkit.Location;
import org.bukkit.World;
import org.dynmap.markers.CircleMarker;
import org.dynmap.markers.GenericMarker;
import org.dynmap.markers.Marker;
import org.dynmap.markers.MarkerIcon;
import org.dynmap.markers.MarkerSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
/**
* A class for rendering icons and areas on dynmap
*/
public class DynmapDrawer {
private static MarkerSet questMarkerSet;
private static MarkerSet questAreaMarkerSet;
private static MarkerSet blacksmithSet;
private static QuestsAPI questsAPI;
private static Map<Icon, MarkerIcon> markerIcons;
private DynmapDrawer() {
}
/**
* Initializes the dynmap drawer
*
* @param questsAPI <p>The quests API to get quest information from</p>
* @param questMarkerSet <p>The marker set for quests</p>
* @param questAreaMarkerSet <p>The marker set for quest areas</p>
* @param blacksmithSet <p>The marker set for blacksmiths</p>
* @param markerIcons <p>The marker icons to use</p>
*/
public static void initialize(QuestsAPI questsAPI, MarkerSet questMarkerSet, MarkerSet questAreaMarkerSet,
MarkerSet blacksmithSet, Map<Icon, MarkerIcon> markerIcons) {
if (DynmapDrawer.questsAPI != null || DynmapDrawer.questMarkerSet != null ||
DynmapDrawer.questAreaMarkerSet != null || DynmapDrawer.markerIcons != null) {
throw new IllegalStateException("The dynmap drawer has already been initialized");
}
DynmapDrawer.questsAPI = questsAPI;
DynmapDrawer.questMarkerSet = questMarkerSet;
DynmapDrawer.questAreaMarkerSet = questAreaMarkerSet;
DynmapDrawer.blacksmithSet = blacksmithSet;
DynmapDrawer.markerIcons = new HashMap<>(markerIcons);
}
/**
* Updates markers for all quests
*/
public static void updateCitizensMarkers() {
if (questsAPI.isLoading()) {
return;
}
//Remove old quest markers
questMarkerSet.getMarkers().forEach(GenericMarker::deleteMarker);
blacksmithSet.getMarkers().forEach(GenericMarker::deleteMarker);
questAreaMarkerSet.getCircleMarkers().forEach(GenericMarker::deleteMarker);
for (IQuest quest : questsAPI.getLoadedQuests()) {
UUID npcStartId = quest.getNpcStart();
if (npcStartId != null) {
String markerDescription = "<b>Quest name:</b> " + quest.getName() + "<br><b>Quest description:</b> " + quest.getDescription();
addNPCMarker(npcStartId, "Quest Start NPC: ", markerDescription, markerIcons.get(Icon.QUEST_GIVER), questMarkerSet);
}
for (IStage stage : quest.getStages()) {
markNPCsInQuest(quest, stage, npcStartId);
markKillLocations(quest, stage);
markReachLocations(quest, stage);
//TODO: Mark WorldGuard areas part of quests. Requires WorldGuard integration
//TODO: See if there is anything to do against overlapping markers
}
}
//Mark all blacksmiths on the map
Class<? extends Trait> blacksmithTrait = CitizensAPI.getTraitFactory().getTraitClass("blacksmith");
for (NPC npc : CitizensAPI.getNPCRegistry()) {
if (npc.hasTrait(blacksmithTrait)) {
addNPCMarker(npc.getUniqueId(), "Blacksmith NPC: ", "",
markerIcons.get(Icon.BLACKSMITH), blacksmithSet);
}
}
}
/**
* 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 static void markReachLocations(IQuest quest, IStage stage) {
markLocations(stage.getLocationsToReach(), stage.getRadiiToReachWithin(),
"<b>Target location for:</b> " + quest.getName() + "<br><b>Description:</b> " +
quest.getDescription());
}
/**
* 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 static void markKillLocations(IQuest quest, IStage stage) {
markLocations(stage.getLocationsToKillWithin(), stage.getRadiiToKillWithin(),
"<b>Kill location for:</b> " + quest.getName() + "<br><b>Description:</b> " +
quest.getDescription());
}
/**
* 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 static 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);
}
}
}
/**
* Marks all NPCs which has interactions as part of this stage
*
* @param quest <p>The quest to mark NPCs for</p>
* @param stage <p>The quest stage to mark NPCs for</p>
* @param npcStartId <p>The id of the quest's start NPC</p>
*/
private static void markNPCsInQuest(IQuest quest, IStage stage, UUID npcStartId) {
String markerDescription = "Part of quest: " + quest.getName();
//Mark all interaction targets
for (UUID interactNpcId : stage.getNpcsToInteract()) {
addNPCMarker(interactNpcId, "Quest Interact NPC: ", markerDescription,
markerIcons.get(Icon.QUEST_INTERACT), questMarkerSet);
}
//Mark all kill targets
for (UUID killNPCId : stage.getNpcsToKill()) {
addNPCMarker(killNPCId, "Quest Kill NPC: ", markerDescription, markerIcons.get(Icon.QUEST_KILL),
questMarkerSet);
}
//Mark all delivery targets
for (UUID deliveryTargetNPCId : stage.getItemDeliveryTargets()) {
if (!deliveryTargetNPCId.equals(npcStartId)) {
addNPCMarker(deliveryTargetNPCId, "Quest Delivery NPC: ", markerDescription,
markerIcons.get(Icon.QUEST_DELIVER), questMarkerSet);
}
}
}
/**
* Adds a marker for an NPC
*
* @param npcId <p>The if of the NPC</p>
* @param markerName <p>The name of the NPC marker</p>
* @param markerDescription <p>The description of the NPC marker</p>
* @param icon <p>The icon used for the marker</p>
* @param markerSet <p>The marker set to add the marker to</p>
*/
private static void addNPCMarker(UUID npcId, String markerName, String markerDescription, MarkerIcon icon, MarkerSet markerSet) {
NPC npc = CitizensAPI.getNPCRegistry().getByUniqueId(npcId);
//If the NPC has been removed, abort
if (npc == null) {
return;
}
//Skip if not a proper location
Location npcLocation = npc.getStoredLocation();
World world = npcLocation.getWorld();
if (world == null) {
return;
}
Marker marker = markerSet.createMarker(null, markerName + npc.getName(), npcLocation.getWorld().getName(),
npcLocation.getX(), npcLocation.getY(), npcLocation.getZ(), icon, false);
if (marker != null) {
marker.setDescription(markerDescription);
}
}
}

View File

@ -0,0 +1,11 @@
package net.knarcraft.questsdynmap;
public enum Icon {
QUEST_GIVER,
QUEST_INTERACT,
QUEST_KILL,
QUEST_DELIVER,
BLACKSMITH
}

View File

@ -0,0 +1,8 @@
name: DynmapCitizens
version: '${project.version}'
main: net.knarcraft.questsdynmap.DynmapCitizens
api-version: 1.19
prefix: DynmapCitizens
depend: [ dynmap, Quests, Citizens, Blacksmith ]
authors: [ EpicKnarvik97 ]
description: A plugin for displaying citizens info on the dynmap map