Merge branch 'scoreboard-dev' into development
This commit is contained in:
commit
d2f2ae22ce
6 changed files with 176 additions and 3 deletions
|
|
@ -0,0 +1,151 @@
|
|||
package io.github.J0hnL0cke.egghunt.Controller;
|
||||
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.Instant;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.scoreboard.Criteria;
|
||||
import org.bukkit.scoreboard.Objective;
|
||||
import org.bukkit.scoreboard.RenderType;
|
||||
import org.bukkit.scoreboard.Score;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
import org.bukkit.scoreboard.ScoreboardManager;
|
||||
|
||||
import io.github.J0hnL0cke.egghunt.Model.Configuration;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Data;
|
||||
import io.github.J0hnL0cke.egghunt.Model.LogHandler;
|
||||
|
||||
/**
|
||||
* Handles interactions with the scoreboard api
|
||||
*/
|
||||
public class ScoreboardController {
|
||||
|
||||
private static ScoreboardController thisHandler;
|
||||
|
||||
private Data data;
|
||||
private Configuration config;
|
||||
private LogHandler logger;
|
||||
private ScoreboardManager manager;
|
||||
private Scoreboard board;
|
||||
private Objective eggMinutes;
|
||||
private Objective eggSeconds;
|
||||
private Instant lastUpdate;
|
||||
private static final String EGG_MINUTES_KEY = "eggOwnedMinutes";
|
||||
private static final String EGG_SECONDS_KEY = "eggOwnedSeconds";
|
||||
|
||||
public static ScoreboardController getScoreboardHandler(Data data, Configuration configuration, LogHandler logger) {
|
||||
if (thisHandler == null) {
|
||||
thisHandler = new ScoreboardController(data, configuration, logger);
|
||||
}
|
||||
return thisHandler;
|
||||
}
|
||||
|
||||
private ScoreboardController(Data data, Configuration config, LogHandler logger) {
|
||||
this.data = data;
|
||||
this.config = config;
|
||||
this.logger = logger;
|
||||
|
||||
if (config.getKeepScore()) {
|
||||
logger.log("Scorekeeping is enabled, loading scoreboard...");
|
||||
loadData();
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveData(LogHandler logger) {
|
||||
if (thisHandler == null) {
|
||||
logger.warning("ScoreboardController has not been initalized before attempting to save!");
|
||||
} else {
|
||||
thisHandler.updateScores();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadData() {
|
||||
manager = Bukkit.getScoreboardManager();
|
||||
board = manager.getMainScoreboard(); //possibly switch to new board? would need to save/load independently of server
|
||||
|
||||
eggSeconds = getOrMakeObjective(EGG_SECONDS_KEY, "Seconds owning egg");
|
||||
eggMinutes = getOrMakeObjective(EGG_MINUTES_KEY, "Minutes owning egg");
|
||||
|
||||
lastUpdate = Instant.now();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the score for the current egg owner
|
||||
*
|
||||
* For accurate scoring, this should be updated at least every time egg ownership changes, and
|
||||
* every time the plugin is enabled/disabled
|
||||
* @param data
|
||||
*/
|
||||
public void updateScores() {
|
||||
if (config.getKeepScore() && data.getEggType()!= Data.Egg_Storage_Type.DNE) {
|
||||
logger.log("Updating scoreboard");
|
||||
|
||||
if (data.getEggType() == Data.Egg_Storage_Type.ENTITY) {
|
||||
Entity eggEntity = data.getEggEntity();
|
||||
if (config.getNamedEntitiesGetScore()) {
|
||||
if (eggEntity.getCustomName() != null) {
|
||||
incrementScoring(eggEntity.getCustomName()); //prioritize the named entity for scoring
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OfflinePlayer owner = data.getEggOwner();
|
||||
if (owner != null) {
|
||||
incrementScoring(owner.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void incrementScoring(String entityName) {
|
||||
//YOU WILL REMEMBER ME! REMEMBER ME FOR
|
||||
//ChronoUnit.CENTURIES
|
||||
|
||||
Instant newUpdate = Instant.now(); //when writing tests, switch this to using an injected Clock instance
|
||||
|
||||
long seconds = ChronoUnit.SECONDS.between(lastUpdate, newUpdate); //this is the floored duration in minutes
|
||||
int convertedSeconds = Long.valueOf(seconds).intValue();
|
||||
|
||||
addScore(entityName, eggSeconds, convertedSeconds); //add to eggSeconds
|
||||
|
||||
int mins = Math.floorDiv(getScore(entityName, eggSeconds), 60); //convert seconds into minutes
|
||||
setScore(entityName, eggMinutes, mins); //update eggMinutes
|
||||
|
||||
lastUpdate = newUpdate; //update lastUpdate time
|
||||
}
|
||||
|
||||
public Objective getOrMakeObjective(String key, String displayName) {
|
||||
Objective obj = board.getObjective(key);
|
||||
if (obj == null) {
|
||||
logger.info(String.format("No scoreboard objective \"%s\" found, creating new objective", key));
|
||||
obj = board.registerNewObjective(key, Criteria.DUMMY, displayName, RenderType.INTEGER);
|
||||
}
|
||||
|
||||
if (!obj.isModifiable()) {
|
||||
String msg = "Could not modify objective \"%s\"! Make sure objective criteria is set to dummy!";
|
||||
logger.warning(String.format(msg, obj.getName()));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private void addScore(String name, Objective obj, int score) {
|
||||
if (score != 0) { //avoid adding the entity to the scoreboard if adding 0
|
||||
Score s = obj.getScore(name);
|
||||
s.setScore(s.getScore() + score);
|
||||
}
|
||||
}
|
||||
|
||||
private void setScore(String name, Objective obj, int score) {
|
||||
Score s = obj.getScore(name);
|
||||
s.setScore(score);
|
||||
}
|
||||
|
||||
private int getScore(String name, Objective obj) {
|
||||
Score s = obj.getScore(name);
|
||||
return s.getScore();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,6 +18,8 @@ public class Configuration {
|
|||
private boolean dropEnderchestedEgg; /** whether an existing egg already in an ender chest should be forced out or stuck there */
|
||||
private boolean canPackageEgg; /** whether the egg can be stored in a shulker box or bundle */
|
||||
private boolean tagOwner; /** whether to apply a tag to the owner of the egg */
|
||||
private boolean keepScore; /** whether to create and increment a scoreboard for time holding the egg */
|
||||
private boolean namedEntitiesGetScore; /** whether entities with custom names are counted on the scoreboard when holding the egg */
|
||||
private World endWorld; /** the name of the world that counts as the end on this server */
|
||||
private String ownerTagName; /** the name of the tag to apply to the owner, if enabled */
|
||||
|
||||
|
|
@ -42,6 +44,8 @@ public class Configuration {
|
|||
dropEnderchestedEgg = fileDao.readBool("drop_enderchested_egg");
|
||||
canPackageEgg = fileDao.readBool("can_package_egg");
|
||||
tagOwner = fileDao.readBool("tag_owner");
|
||||
keepScore = fileDao.readBool("keep_score");
|
||||
namedEntitiesGetScore = fileDao.readBool("named_entities_keep_score");
|
||||
|
||||
ownerTagName = fileDao.read("owner_tag_name", null);
|
||||
endWorld = Bukkit.getServer().getWorld(fileDao.read("end", DEFAULT_END));
|
||||
|
|
@ -79,11 +83,18 @@ public class Configuration {
|
|||
return false; //canPackageEgg; TODO implement checks for this
|
||||
}
|
||||
|
||||
|
||||
public boolean getTagOwner() {
|
||||
return tagOwner;
|
||||
}
|
||||
|
||||
public boolean getKeepScore() {
|
||||
return keepScore;
|
||||
}
|
||||
|
||||
public boolean getNamedEntitiesGetScore() {
|
||||
return namedEntitiesGetScore;
|
||||
}
|
||||
|
||||
public String getOwnerTagName(){
|
||||
return ownerTagName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import org.bukkit.inventory.InventoryHolder;
|
|||
|
||||
import io.github.J0hnL0cke.egghunt.Controller.Announcement;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.EggController;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.ScoreboardController;
|
||||
import io.github.J0hnL0cke.egghunt.Persistence.DataFileDAO;
|
||||
|
||||
/**
|
||||
|
|
@ -221,6 +222,8 @@ public class Data {
|
|||
}
|
||||
|
||||
public void saveData() {
|
||||
ScoreboardController.saveData(logger);
|
||||
|
||||
dataDao.writeUUID("owner", owner);
|
||||
dataDao.writeLocation("block", serializeBlock(block));
|
||||
dataDao.writeUUID("entity", serializeEntity(entity));
|
||||
|
|
@ -244,6 +247,7 @@ public class Data {
|
|||
|
||||
private void setEggOwner(UUID playerUUID, Configuration config) {
|
||||
if (!playerUUID.equals(owner)) { //only update if the egg has actually changed posession
|
||||
ScoreboardController.saveData(logger);
|
||||
UUID oldOwner = owner;
|
||||
owner = playerUUID; //set new owner
|
||||
String ownerName = Bukkit.getOfflinePlayer(owner).getName();
|
||||
|
|
@ -270,6 +274,7 @@ public class Data {
|
|||
}
|
||||
|
||||
public void resetEggOwner(boolean announce, Configuration config) {
|
||||
ScoreboardController.saveData(logger);
|
||||
if (owner != null) {
|
||||
Player oldOwner = Bukkit.getPlayer(owner);
|
||||
if (announce) { //TODO move announcements somewhere else?
|
||||
|
|
|
|||
|
|
@ -143,7 +143,9 @@ public class Egg {
|
|||
if (entity instanceof LivingEntity) {
|
||||
LivingEntity mob = (((LivingEntity) entity));
|
||||
EntityEquipment inv = mob.getEquipment();
|
||||
if (Egg.hasEgg(inv.getArmorContents())) { //TODO check if includes main/offhand
|
||||
if (Egg.hasEgg(inv.getArmorContents())) {
|
||||
return true;
|
||||
} else if (Egg.hasEgg(inv.getItemInMainHand()) || Egg.hasEgg(inv.getItemInOffHand())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import io.github.J0hnL0cke.egghunt.Controller.CommandHandler;
|
|||
import io.github.J0hnL0cke.egghunt.Controller.EggController;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.EggDestroyListener;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.MiscListener;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.ScoreboardController;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.EventScheduler;
|
||||
import io.github.J0hnL0cke.egghunt.Controller.InventoryListener;
|
||||
import io.github.J0hnL0cke.egghunt.Model.Configuration;
|
||||
|
|
@ -45,6 +46,7 @@ public final class egghunt extends JavaPlugin {
|
|||
logger.setDebug(config.getDebugEnabled());
|
||||
|
||||
//create controller instances
|
||||
ScoreboardController scoreboardController = ScoreboardController.getScoreboardHandler(data, config, logger);
|
||||
MiscListener miscListener = new MiscListener(logger, config, data);
|
||||
InventoryListener inventoryListener = new InventoryListener(logger, config, data);
|
||||
EggDestroyListener destroyListener = new EggDestroyListener(logger, config, data);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#If enabled, logs extra debugging information to the console. This information will appear in logs regardless of debug setting.
|
||||
debug: false
|
||||
debug: true
|
||||
|
||||
#Name of your end world, usually to "world_the_end" on spigot
|
||||
end: world_the_end
|
||||
|
|
@ -13,11 +13,13 @@ egg_inv: false
|
|||
resp_egg: true
|
||||
#Whether the egg respawns immediately (true) or after a new dragon is spawned and killed (false) after the egg is destroyed
|
||||
resp_imm: false
|
||||
|
||||
#Whether to drop any eggs that players have in their ender chest onto the ground.
|
||||
#Setting this to false will prevent the player from removing that egg from their ender chest.
|
||||
drop_enderchested_egg: false
|
||||
|
||||
#Whether to apply an entity tag to the egg owner (works like `/tag <playerName> add <tagName>`)
|
||||
#Tag is updated when egg ownership changes and on player login
|
||||
tag_owner: true
|
||||
#The name of the tag to apply. Selected like: `/tell @a[tag=<tagName>] <message>`
|
||||
#If changing this while the egg is claimed, remove the old tag by running `/tag <playerName> remove <oldTagName>`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue