mirror of
https://github.com/garbagemule/MobArena.git
synced 2024-11-22 10:36:00 +01:00
Use arena class slugs for class selection.
This commit is a minor refactoring of the class selection functionality plugin-wide. Instead of selecting classes based on the "lowercase name" of a class, commands and listeners are now "slug aware", as it were. The ArenaClass class now uses its slug instead of its "lowercase name" for equality and hash codes. The `/ma class` command now tab completes slugs, but it still supports class names as they appear in the config-file when executing the command itself. The same applies to the `/ma classchest` command. The sign handling in ArenaListener slugifies sign text instead of just lowercasing and stripping spaces.
This commit is contained in:
parent
519886cf3e
commit
5bcab8fa46
@ -24,6 +24,7 @@ These changes will (most likely) be included in the next version.
|
||||
- New command `/ma addreward <player> <thing>` can be used to add a reward to an arena player's reward list. This can be useful for hooking into the rewards system from scripts or other plugins.
|
||||
- The Root Target ability now uses potion effects (slowness, slow falling, and negative jump boost) instead of repeated teleports. This should make for a smoother root experience.
|
||||
- Permissions for arenas and classes are now based on "slugs". It is now possible to configure permissions for arenas and classes with multi-word names (including "My Items"). Check the Permissions page on the wiki for details.
|
||||
- Commands that resolve class names now consistently resolve and tab complete "slugs" instead of arbitrarily "squashed" names. This greatly improves support for multi-word names.
|
||||
- Using `spectate-on-death: true` no longer forces players out to their join location/exit warp before moving them to the spectator area. This should prevent "jumpy" behavior in multi-world setups.
|
||||
- Players should now properly respawn at the spectator area rather than at world spawn on servers with plugins that override respawn locations.
|
||||
- Config-files with missing `pet-items` nodes no longer errors. A missing `pet-items` node in `global-settings` is treated as empty, i.e. no pet items will be registered.
|
||||
|
@ -16,7 +16,7 @@ import java.util.stream.IntStream;
|
||||
|
||||
public class ArenaClass
|
||||
{
|
||||
private String configName, lowercaseName;
|
||||
private String configName;
|
||||
private String slug;
|
||||
private Thing helmet, chestplate, leggings, boots, offhand;
|
||||
private List<Thing> armor;
|
||||
@ -35,7 +35,6 @@ public class ArenaClass
|
||||
public ArenaClass(String name, Thing price, boolean unbreakableWeapons, boolean unbreakableArmor) {
|
||||
this.configName = name;
|
||||
this.slug = Slugs.create(name);
|
||||
this.lowercaseName = name.toLowerCase().replace(" ", "");
|
||||
|
||||
this.items = new ArrayList<>();
|
||||
this.armor = new ArrayList<>(4);
|
||||
@ -72,7 +71,7 @@ public class ArenaClass
|
||||
*/
|
||||
@Deprecated
|
||||
public String getLowercaseName() {
|
||||
return lowercaseName;
|
||||
return slug;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,12 +237,12 @@ public class ArenaClass
|
||||
if (!this.getClass().equals(o.getClass())) return false;
|
||||
|
||||
ArenaClass other = (ArenaClass) o;
|
||||
return other.lowercaseName.equals(this.lowercaseName);
|
||||
return other.slug.equals(this.slug);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return lowercaseName.hashCode();
|
||||
return slug.hashCode();
|
||||
}
|
||||
|
||||
public static class MyItems extends ArenaClass {
|
||||
|
@ -757,7 +757,8 @@ public class ArenaImpl implements Arena
|
||||
if (defaultClass != null) {
|
||||
// Assign default class if applicable
|
||||
if (!ClassChests.assignClassFromStoredClassChest(this, p, defaultClass)) {
|
||||
assignClass(p, defaultClass.getLowercaseName());
|
||||
String slug = defaultClass.getSlug();
|
||||
assignClass(p, slug);
|
||||
messenger.tell(p, Msg.LOBBY_CLASS_PICKED, defaultClass.getConfigName());
|
||||
}
|
||||
}
|
||||
@ -1319,10 +1320,10 @@ public class ArenaImpl implements Arena
|
||||
}
|
||||
|
||||
int index = MobArena.random.nextInt(classes.size());
|
||||
String className = classes.get(index).getConfigName();
|
||||
String slug = classes.get(index).getSlug();
|
||||
|
||||
assignClass(p, className);
|
||||
messenger.tell(p, Msg.LOBBY_CLASS_PICKED, this.classes.get(className).getConfigName());
|
||||
assignClass(p, slug);
|
||||
messenger.tell(p, Msg.LOBBY_CLASS_PICKED, this.classes.get(slug).getConfigName());
|
||||
}
|
||||
|
||||
private void addClassPermissions(Player player) {
|
||||
|
@ -17,6 +17,7 @@ import com.garbagemule.MobArena.things.ExperienceThing;
|
||||
import com.garbagemule.MobArena.things.Thing;
|
||||
import com.garbagemule.MobArena.things.ThingPicker;
|
||||
import com.garbagemule.MobArena.util.ClassChests;
|
||||
import com.garbagemule.MobArena.util.Slugs;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
@ -1114,15 +1115,16 @@ public class ArenaListener
|
||||
|
||||
private void handleSign(Sign sign, Player p) {
|
||||
// Check if the first line is a class name.
|
||||
String className = ChatColor.stripColor(sign.getLine(0)).toLowerCase().replace(" ", "");
|
||||
String className = ChatColor.stripColor(sign.getLine(0));
|
||||
String slug = Slugs.create(className);
|
||||
|
||||
if (!arena.getClasses().containsKey(className) && !className.equals("random"))
|
||||
if (!arena.getClasses().containsKey(slug) && !slug.equals("random"))
|
||||
return;
|
||||
|
||||
ArenaClass newAC = arena.getClasses().get(className);
|
||||
ArenaClass newAC = arena.getClasses().get(slug);
|
||||
|
||||
// Check for permission.
|
||||
if (!newAC.hasPermission(p) && !className.equals("random")) {
|
||||
if (!newAC.hasPermission(p) && !slug.equals("random")) {
|
||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PERMISSION);
|
||||
return;
|
||||
}
|
||||
@ -1154,7 +1156,7 @@ public class ArenaListener
|
||||
classLimits.playerPickedClass(newAC, p);
|
||||
|
||||
// Delay the inventory stuff to ensure that right-clicking works.
|
||||
delayAssignClass(p, className, price, sign);
|
||||
delayAssignClass(p, slug, price, sign);
|
||||
}
|
||||
|
||||
/*private boolean cansPlayerJoinClass(ArenaClass ac, Player p) {
|
||||
@ -1169,12 +1171,12 @@ public class ArenaListener
|
||||
return true;
|
||||
}*/
|
||||
|
||||
private void delayAssignClass(final Player p, final String className, final Thing price, final Sign sign) {
|
||||
private void delayAssignClass(final Player p, final String slug, final Thing price, final Sign sign) {
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin,new Runnable() {
|
||||
public void run() {
|
||||
if (!className.equalsIgnoreCase("random")) {
|
||||
if (!slug.equalsIgnoreCase("random")) {
|
||||
if (useClassChests) {
|
||||
ArenaClass ac = plugin.getArenaMaster().getClasses().get(className.toLowerCase().replace(" ", ""));
|
||||
ArenaClass ac = plugin.getArenaMaster().getClasses().get(slug);
|
||||
if (ClassChests.assignClassFromStoredClassChest(arena, p, ac)) {
|
||||
return;
|
||||
}
|
||||
@ -1183,8 +1185,8 @@ public class ArenaListener
|
||||
}
|
||||
// Otherwise just fall through and use the items from the config-file
|
||||
}
|
||||
arena.assignClass(p, className);
|
||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(className).getConfigName());
|
||||
arena.assignClass(p, slug);
|
||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(slug).getConfigName());
|
||||
if (price != null) {
|
||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PRICE, price.toString());
|
||||
}
|
||||
|
@ -337,14 +337,13 @@ public class ArenaMasterImpl implements ArenaMaster
|
||||
private ArenaClass loadClass(String classname) {
|
||||
FileConfiguration config = plugin.getConfig();
|
||||
ConfigurationSection section = config.getConfigurationSection("classes." + classname);
|
||||
String lowercase = classname.toLowerCase().replace(" ", "");
|
||||
|
||||
// If the section doesn't exist, the class doesn't either.
|
||||
if (section == null) {
|
||||
// We may not have a class entry for My Items, but that's fine
|
||||
if (classname.equals("My Items")) {
|
||||
ArenaClass myItems = new ArenaClass.MyItems(null, false, false, this);
|
||||
classes.put(lowercase, myItems);
|
||||
classes.put(myItems.getSlug(), myItems);
|
||||
return myItems;
|
||||
}
|
||||
plugin.getLogger().severe("Failed to load class '" + classname + "'.");
|
||||
@ -393,7 +392,7 @@ public class ArenaMasterImpl implements ArenaMaster
|
||||
}
|
||||
|
||||
// Finally add the class to the classes map.
|
||||
classes.put(lowercase, arenaClass);
|
||||
classes.put(arenaClass.getSlug(), arenaClass);
|
||||
return arenaClass;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import com.garbagemule.MobArena.commands.Command;
|
||||
import com.garbagemule.MobArena.commands.CommandInfo;
|
||||
import com.garbagemule.MobArena.commands.Commands;
|
||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||
import com.garbagemule.MobArena.util.Slugs;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -37,7 +38,8 @@ public class ClassChestCommand implements Command {
|
||||
// Require a class name
|
||||
if (args.length != 1) return false;
|
||||
|
||||
ArenaClass ac = am.getClasses().get(args[0].toLowerCase());
|
||||
String slug = Slugs.create(args[0]);
|
||||
ArenaClass ac = am.getClasses().get(slug);
|
||||
if (ac == null) {
|
||||
am.getGlobalMessenger().tell(sender, "Class not found.");
|
||||
return true;
|
||||
@ -69,13 +71,13 @@ public class ClassChestCommand implements Command {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
String prefix = args[0].toLowerCase();
|
||||
String prefix = Slugs.create(args[0]);
|
||||
|
||||
Collection<ArenaClass> classes = am.getClasses().values();
|
||||
|
||||
return classes.stream()
|
||||
.filter(cls -> cls.getConfigName().toLowerCase().startsWith(prefix))
|
||||
.map(ArenaClass::getConfigName)
|
||||
.filter(cls -> cls.getSlug().startsWith(prefix))
|
||||
.map(ArenaClass::getSlug)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.framework.ArenaMaster;
|
||||
import com.garbagemule.MobArena.things.Thing;
|
||||
import com.garbagemule.MobArena.util.ClassChests;
|
||||
import com.garbagemule.MobArena.util.Slugs;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -51,15 +52,15 @@ public class PickClassCommand implements Command
|
||||
}
|
||||
|
||||
// Grab the ArenaClass, if it exists
|
||||
String lowercase = args[0].toLowerCase();
|
||||
ArenaClass ac = am.getClasses().get(lowercase);
|
||||
String slug = Slugs.create(args[0]);
|
||||
ArenaClass ac = am.getClasses().get(slug);
|
||||
if (ac == null) {
|
||||
arena.getMessenger().tell(p, Msg.LOBBY_NO_SUCH_CLASS, lowercase);
|
||||
arena.getMessenger().tell(p, Msg.LOBBY_NO_SUCH_CLASS, slug);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for permission.
|
||||
if (!ac.hasPermission(p) && !lowercase.equals("random")) {
|
||||
if (!ac.hasPermission(p) && !slug.equals("random")) {
|
||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PERMISSION);
|
||||
return true;
|
||||
}
|
||||
@ -88,15 +89,15 @@ public class PickClassCommand implements Command
|
||||
clm.playerLeftClass(oldAC, p);
|
||||
clm.playerPickedClass(ac, p);
|
||||
|
||||
if (!lowercase.equalsIgnoreCase("random")) {
|
||||
if (!slug.equalsIgnoreCase("random")) {
|
||||
if (arena.getSettings().getBoolean("use-class-chests", false)) {
|
||||
if (ClassChests.assignClassFromStoredClassChest(arena, p, ac)) {
|
||||
return true;
|
||||
}
|
||||
// No linked chest? Fall through to config-file
|
||||
}
|
||||
arena.assignClass(p, lowercase);
|
||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(lowercase).getConfigName());
|
||||
arena.assignClass(p, slug);
|
||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(slug).getConfigName());
|
||||
if (price != null) {
|
||||
arena.getMessenger().tell(p, Msg.LOBBY_CLASS_PRICE, price.toString());
|
||||
}
|
||||
@ -118,9 +119,9 @@ public class PickClassCommand implements Command
|
||||
Collection<ArenaClass> classes = am.getClasses().values();
|
||||
|
||||
return classes.stream()
|
||||
.filter(cls -> cls.getConfigName().toLowerCase().startsWith(prefix))
|
||||
.filter(cls -> cls.getSlug().startsWith(prefix))
|
||||
.filter(cls -> cls.hasPermission(player))
|
||||
.map(ArenaClass::getConfigName)
|
||||
.map(ArenaClass::getSlug)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ public class ClassChests {
|
||||
}
|
||||
|
||||
private static void assignClassAndGrantChestItems(Arena arena, Player player, ArenaClass ac, Block block) {
|
||||
String classname = ac.getLowercaseName();
|
||||
String slug = ac.getSlug();
|
||||
InventoryHolder holder = (InventoryHolder) block.getState();
|
||||
ItemStack[] contents = holder.getInventory().getContents();
|
||||
|
||||
@ -106,8 +106,8 @@ public class ClassChests {
|
||||
System.arraycopy(contents, 0, newContents, 0, 36);
|
||||
contents = newContents;
|
||||
}
|
||||
arena.assignClassGiveInv(player, classname, contents);
|
||||
arena.getMessenger().tell(player, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(classname).getConfigName());
|
||||
arena.assignClassGiveInv(player, slug, contents);
|
||||
arena.getMessenger().tell(player, Msg.LOBBY_CLASS_PICKED, arena.getClasses().get(slug).getConfigName());
|
||||
|
||||
Thing price = ac.getPrice();
|
||||
if (price != null) {
|
||||
|
Loading…
Reference in New Issue
Block a user