Make it possible to configure which mobs count towards promotions.

master
James T. Martin 2020-11-17 21:46:13 -08:00
parent 826e014117
commit 3955aba2ed
Signed by: james
GPG Key ID: 4B7F3DA9351E577C
9 changed files with 246 additions and 43 deletions

View File

@ -7,6 +7,7 @@ import java.util.logging.Level;
import me.jamestmartin.wasteland.commands.CommandOfficial;
import me.jamestmartin.wasteland.commands.CommandRank;
import me.jamestmartin.wasteland.commands.CommandRankEligibleMobs;
import me.jamestmartin.wasteland.commands.CommandRanks;
import me.jamestmartin.wasteland.commands.CommandSetKills;
import me.jamestmartin.wasteland.config.WastelandConfig;
@ -77,15 +78,16 @@ public class Wasteland extends JavaPlugin {
}
private void registerCommands() {
this.getCommand("rank").setExecutor(new CommandRank());
this.getCommand("rank").setExecutor(new CommandRank(config.eligibleMobsName()));
this.getCommand("rankeligiblemobs").setExecutor(new CommandRankEligibleMobs(config.eligibleMobsName(), config.eligibleMobs()));
this.getCommand("ranks").setExecutor(new CommandRanks());
this.getCommand("setkills").setExecutor(new CommandSetKills());
this.getCommand("official").setExecutor(new CommandOfficial());
this.getCommand("ranks").setExecutor(new CommandRanks());
}
private void registerListeners() {
PluginManager manager = this.getServer().getPluginManager();
rankListener = new RankListener();
rankListener = new RankListener(config.eligibleMobs());
manager.registerEvents(rankListener, this);
manager.registerEvents(new ChatListener(), this);
}

View File

@ -13,6 +13,12 @@ import me.jamestmartin.wasteland.Wasteland;
import me.jamestmartin.wasteland.ranks.EnlistedRank;
public class CommandRank implements CommandExecutor {
private final String eligibleMobsName;
public CommandRank(String eligibleMobsName) {
this.eligibleMobsName = eligibleMobsName;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length > 1) {
@ -70,7 +76,7 @@ public class CommandRank implements CommandExecutor {
sender.sendMessage(playerName + is + "rank " + rank.get().formatFull() + ".");
}
if (seeKills) {
String hasKilled = playerName + has + "killed " + kills + " zombies";
String hasKilled = playerName + has + "killed " + kills + " " + eligibleMobsName;
String andHasToGo;
if (nextRank.isPresent()) {
int moreZombies = nextRank.get().getKills().get() - kills;

View File

@ -0,0 +1,34 @@
package me.jamestmartin.wasteland.commands;
import java.util.Collection;
import java.util.stream.Collectors;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
public class CommandRankEligibleMobs implements CommandExecutor {
private final String eligibleMobsName;
private final Collection<EntityType> eligibleMobs;
public CommandRankEligibleMobs(String eligibleMobsName, Collection<EntityType> eligibleMobs) {
this.eligibleMobsName = eligibleMobsName;
this.eligibleMobs = eligibleMobs;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length > 0) {
sender.sendMessage("Too many arguments!");
sender.sendMessage(command.getUsage());
return false;
}
sender.sendMessage("Killing " + eligibleMobsName + " will count towards your next promotion.");
sender.sendMessage("Specifically, any of these mobs will work: " +
eligibleMobs.stream().map(Object::toString).sorted().collect(Collectors.joining(", ")));
return true;
}
}

View File

@ -66,9 +66,12 @@ public class CommandSetKills implements CommandExecutor {
}
try {
int previousKills = Wasteland.getInstance().getDatabase().getPlayerKills(subject);
Wasteland.getInstance().getDatabase().setPlayerKills(subject, kills);
Wasteland.getInstance().updatePlayerRank(subject);
sender.sendMessage(playerNowHas + " " + kills + " kills.");
Wasteland.getInstance().getLogger().info(sender.getName() + " has changed the number of kills " + subject.getName() + " has from " + previousKills + " to " + kills);
} catch (SQLException e) {
Wasteland.getInstance().getLogger().log(Level.SEVERE, "Failed to set player kills.", e);
sender.sendMessage("ERROR: Failed to update player kills. Please notify a server administrator.");

View File

@ -0,0 +1,115 @@
package me.jamestmartin.wasteland.config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import org.bukkit.entity.EntityType;
class EntityTypes {
private static final EntityType[] BOSSES = {
EntityType.ENDER_DRAGON,
EntityType.WITHER,
};
private static final EntityType[] HOSTILES = {
EntityType.BLAZE,
EntityType.CREEPER,
EntityType.DROWNED,
EntityType.ELDER_GUARDIAN,
EntityType.ENDER_DRAGON,
EntityType.ENDERMITE,
EntityType.EVOKER,
EntityType.GHAST,
EntityType.GUARDIAN,
EntityType.HOGLIN,
EntityType.HUSK,
EntityType.ILLUSIONER,
EntityType.MAGMA_CUBE,
EntityType.PHANTOM,
EntityType.PIGLIN_BRUTE,
EntityType.PILLAGER,
EntityType.RAVAGER,
EntityType.SHULKER,
EntityType.SILVERFISH,
EntityType.SKELETON,
EntityType.SLIME,
EntityType.STRAY,
EntityType.VEX,
EntityType.VINDICATOR,
EntityType.WITCH,
EntityType.WITHER,
EntityType.WITHER_SKELETON,
EntityType.ZOGLIN,
EntityType.ZOMBIE,
EntityType.ZOMBIE_VILLAGER,
};
private static final EntityType[] NEUTRALS = {
EntityType.BEE,
EntityType.CAVE_SPIDER,
EntityType.DOLPHIN,
EntityType.ENDERMAN,
EntityType.IRON_GOLEM,
EntityType.LLAMA,
EntityType.PIGLIN,
EntityType.PANDA,
EntityType.POLAR_BEAR,
EntityType.PUFFERFISH,
EntityType.SPIDER,
EntityType.WOLF,
EntityType.ZOMBIFIED_PIGLIN,
};
/**
* Monsters which are eligible for the monster hunter achievement but are not hostile.
* All hostile monsters are eligable.
*/
private static final EntityType[] NON_HOSTILE_MONSTERS = {
EntityType.CAVE_SPIDER,
EntityType.ENDERMAN,
EntityType.SPIDER,
EntityType.ZOMBIFIED_PIGLIN,
};
private static final EntityType[] SPIDERS = {
EntityType.CAVE_SPIDER,
EntityType.SPIDER,
};
private static final EntityType[] ZOMBIES = {
EntityType.GIANT,
EntityType.ZOGLIN,
EntityType.ZOMBIE,
EntityType.ZOMBIE_VILLAGER,
EntityType.ZOMBIE_HORSE,
EntityType.ZOMBIFIED_PIGLIN,
};
public static EntityType[] lookupEntityType(String typeName) {
switch(typeName) {
case "bosses":
return BOSSES;
case "hostiles":
return HOSTILES;
case "monsters":
HashSet<EntityType> monsters = new HashSet<>();
monsters.addAll(Arrays.asList(HOSTILES));
monsters.addAll(Arrays.asList(NON_HOSTILE_MONSTERS));
return monsters.toArray(EntityType[]::new);
case "neutrals":
return NEUTRALS;
case "spiders":
return SPIDERS;
case "zombies":
return ZOMBIES;
default:
EntityType type = EntityType.valueOf(typeName);
if (type == null) {
throw new IllegalArgumentException("Unknown entity type: " + typeName);
}
EntityType[] rv = { type };
return rv;
}
};
}

View File

@ -1,11 +1,16 @@
package me.jamestmartin.wasteland.config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.EntityType;
import me.jamestmartin.wasteland.ranks.EnlistedRank;
import me.jamestmartin.wasteland.ranks.Rank;
@ -21,6 +26,9 @@ public class WastelandConfig {
private final Collection<Rank> officerRanks;
private final Optional<Rank> consoleRank;
private final Set<EntityType> eligibleMobs;
private final String eligibleMobsName;
/** Orphaned method. */
public static Optional<ChatColor> readColor(ConfigurationSection c, String path) {
return (Optional<ChatColor>) Optional.ofNullable(c.getString(path)).map(ChatColor::valueOf);
@ -34,7 +42,6 @@ public class WastelandConfig {
this.bracketChatRank = c.getBoolean("bracketChatRank", true);
this.nameUsesRankColor = c.getBoolean("nameUsesRankColor", false);
ConfigurationSection ers = c.getConfigurationSection("enlistedRanks");
ArrayList<EnlistedRank> enlistedRanks = new ArrayList<>();
this.enlistedRanks = enlistedRanks;
@ -75,6 +82,14 @@ public class WastelandConfig {
} else {
this.consoleRank = Optional.of(new Rank(Optional.empty(), Optional.empty(), crs));
}
List<String> eligibleMobTypes = c.getStringList("eligibleMobs");
this.eligibleMobs = new HashSet<>();
for (String mobType : eligibleMobTypes) {
this.eligibleMobs.addAll(Arrays.asList(EntityTypes.lookupEntityType(mobType)));
}
this.eligibleMobsName = c.getString("eligibleMobsName");
}
public String databaseFile() { return this.databaseFile; }
@ -89,4 +104,9 @@ public class WastelandConfig {
public Collection<EnlistedRank> enlistedRanks() { return this.enlistedRanks; }
public Collection<Rank> officerRanks() { return this.officerRanks; }
public Optional<Rank> consoleRank() { return this.consoleRank; }
/** The entity types which, if killed, will count towards your enlisted rank. */
public Set<EntityType> eligibleMobs() { return this.eligibleMobs; }
/** The term for the eligible mobs, e.g. "zombies" or "hostile mobs". */
public String eligibleMobsName() { return this.eligibleMobsName; }
}

View File

@ -1,6 +1,7 @@
package me.jamestmartin.wasteland.listeners;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@ -8,6 +9,7 @@ import java.util.UUID;
import java.util.logging.Level;
import org.bukkit.ChatColor;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -22,8 +24,11 @@ import me.jamestmartin.wasteland.ranks.EnlistedRank;
public class RankListener implements Listener, AutoCloseable {
private Map<UUID, PermissionAttachment> attachments = new HashMap<>();
private final Collection<EntityType> eligibleMobs;
public RankListener() {
public RankListener(Collection<EntityType> eligibleMobs) {
this.eligibleMobs = eligibleMobs;
for (Player player : Wasteland.getInstance().getServer().getOnlinePlayers()) {
try {
initializePlayer(player);
@ -73,41 +78,33 @@ public class RankListener implements Listener, AutoCloseable {
public void onEntityDeath(EntityDeathEvent event) {
Player player = event.getEntity().getKiller();
if (player == null) return;
switch (event.getEntityType()) {
case HUSK:
case ZOMBIFIED_PIGLIN:
case ZOMBIE:
case ZOMBIE_VILLAGER:
case ZOGLIN:
try {
Wasteland.getInstance().getDatabase().incrementPlayerKills(player);
Optional<EnlistedRank> oldRank = EnlistedRank.getEnlistedRank(player);
updatePlayerRank(player);
Optional<EnlistedRank> newRank = EnlistedRank.getEnlistedRank(player);
if (newRank.isPresent()) {
final String formatString;
if (oldRank.isPresent()) {
if (!newRank.get().equals(oldRank.get())) {
formatString = "%s" + ChatColor.RESET + " has been promoted from %s " + ChatColor.RESET + "to %s" + ChatColor.RESET + "!";
player.getServer().broadcastMessage(
String.format(formatString, player.getDisplayName(),
oldRank.get().formatFull(), newRank.get().formatFull()));
}
} else {
formatString = "%s" + ChatColor.RESET + " has been promoted to %s" + ChatColor.RESET + "!";
player.getServer().broadcastMessage(
String.format(formatString, player.getDisplayName(), newRank.get()));
}
}
} catch (SQLException e) {
Wasteland.getInstance().getLogger().log(Level.SEVERE, "Failed to increment player kills.", e);
}
default:
break;
}
if (!eligibleMobs.contains(event.getEntityType())) return;
try {
Wasteland.getInstance().getDatabase().incrementPlayerKills(player);
Optional<EnlistedRank> oldRank = EnlistedRank.getEnlistedRank(player);
updatePlayerRank(player);
Optional<EnlistedRank> newRank = EnlistedRank.getEnlistedRank(player);
if (newRank.isPresent()) {
final String formatString;
if (oldRank.isPresent()) {
if (!newRank.get().equals(oldRank.get())) {
formatString = "%s" + ChatColor.RESET + " has been promoted from %s " + ChatColor.RESET + "to %s" + ChatColor.RESET + "!";
player.getServer().broadcastMessage(
String.format(formatString, player.getDisplayName(),
oldRank.get().formatFull(), newRank.get().formatFull()));
}
} else {
formatString = "%s" + ChatColor.RESET + " has been promoted to %s" + ChatColor.RESET + "!";
player.getServer().broadcastMessage(
String.format(formatString, player.getDisplayName(), newRank.get()));
}
}
} catch (SQLException e) {
Wasteland.getInstance().getLogger().log(Level.SEVERE, "Failed to increment player kills.", e);
}
}
@EventHandler(priority = EventPriority.MONITOR)
@ -118,6 +115,7 @@ public class RankListener implements Listener, AutoCloseable {
@Override
public void close() {
// Trying to remove attachments throws an error. Perhaps it's done automatically?
/*for(Map.Entry<UUID, PermissionAttachment> attachment : attachments.entrySet()) {
Wasteland.getInstance().getServer().getPlayer(attachment.getKey())
.removeAttachment(attachment.getValue());

View File

@ -194,4 +194,19 @@ consoleRank:
description: The server console.
color: GOLD
decoration: BOLD
# The entity types which, if killed, will count towards your enlisted rank.
# Each value must be a valid Bukkit EntityType (e.g. `WITHER_SKELETON` or `ENDERMAN`),
# or one of my built-in entity collections (`bosses`, hostiles`, `monsters`, `neutrals`, `zombies`, `spiders`).
# Beware that `hostiles` does not include endermen, spiders, or zombified piglins,
# although they are included in `monsters`.
#
# The wiki lists which mobs are bosses, hostile, or neutral: https://minecraft.gamepedia.com/Mob#List_of_mobs
# Monsters are defined as the mobs which are eligible for the Monster Hunter achievement
# (all hostile mobs plus endermen, spiders, and zombified piglins).
eligibleMobs: [monsters]
eligibleMobsName: monsters

View File

@ -9,9 +9,14 @@ softdepend: [Towny]
commands:
rank:
description: View your rank and how many monsters you have killed.
usage: "Usage: /rank [<player>]"
usage: "Usage: /<command> [player]"
permission: wasteland.view-rank
permission-message: You do not have permission to view your rank.
rankeligiblemobs:
description: View a list of monsters which you can kill to get promoted.
usage: "Usage: /<command>"
permission: wasteland.view-eligible-mobs
permission-message: You cannot view the list of promotion-eligible monsters.
ranks:
description: List the server ranks.
usage: "Usage: /<command>"
@ -55,4 +60,9 @@ permissions:
description: Allows you to set player kills using /setkills.
default: op
children:
wasteland.view-rank.other.kills: true
wasteland.view-rank.other.kills: true
wasteland.view-eligible-mobs:
description: Allows you to see the specific list of what mobs count towards promotion with /rankeligiblemobs.
default: true