mirror of
				https://github.com/SunNetservers/MiniGames.git
				synced 2025-11-03 19:23:46 +01:00 
			
		
		
		
	Implements several configuration options #15
This commit is contained in:
		@@ -1,5 +1,6 @@
 | 
			
		||||
package net.knarcraft.dropper;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaData;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaHandler;
 | 
			
		||||
@@ -21,6 +22,7 @@ import net.knarcraft.dropper.command.ListArenaCommand;
 | 
			
		||||
import net.knarcraft.dropper.command.ReloadCommand;
 | 
			
		||||
import net.knarcraft.dropper.command.RemoveArenaCommand;
 | 
			
		||||
import net.knarcraft.dropper.command.RemoveArenaTabCompleter;
 | 
			
		||||
import net.knarcraft.dropper.config.DropperConfiguration;
 | 
			
		||||
import net.knarcraft.dropper.container.SerializableMaterial;
 | 
			
		||||
import net.knarcraft.dropper.container.SerializableUUID;
 | 
			
		||||
import net.knarcraft.dropper.listener.CommandListener;
 | 
			
		||||
@@ -28,7 +30,6 @@ import net.knarcraft.dropper.listener.DamageListener;
 | 
			
		||||
import net.knarcraft.dropper.listener.MoveListener;
 | 
			
		||||
import net.knarcraft.dropper.listener.PlayerLeaveListener;
 | 
			
		||||
import net.knarcraft.dropper.placeholder.DropperRecordExpansion;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.command.CommandExecutor;
 | 
			
		||||
import org.bukkit.command.PluginCommand;
 | 
			
		||||
@@ -49,8 +50,10 @@ import java.util.logging.Level;
 | 
			
		||||
public final class Dropper extends JavaPlugin {
 | 
			
		||||
 | 
			
		||||
    private static Dropper instance;
 | 
			
		||||
    private DropperConfiguration configuration;
 | 
			
		||||
    private DropperArenaHandler arenaHandler;
 | 
			
		||||
    private DropperArenaPlayerRegistry playerRegistry;
 | 
			
		||||
    private DropperRecordExpansion dropperRecordExpansion;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets an instance of this plugin
 | 
			
		||||
@@ -79,6 +82,25 @@ public final class Dropper extends JavaPlugin {
 | 
			
		||||
        return this.playerRegistry;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the dropper configuration
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The dropper configuration</p>
 | 
			
		||||
     */
 | 
			
		||||
    public DropperConfiguration getDropperConfiguration() {
 | 
			
		||||
        return this.configuration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Logs a message
 | 
			
		||||
     *
 | 
			
		||||
     * @param level   <p>The message level to log at</p>
 | 
			
		||||
     * @param message <p>The message to log</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static void log(Level level, String message) {
 | 
			
		||||
        Dropper.getInstance().getLogger().log(level, message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reloads all configurations and data from disk
 | 
			
		||||
     */
 | 
			
		||||
@@ -86,6 +108,13 @@ public final class Dropper extends JavaPlugin {
 | 
			
		||||
        // Load all arenas again
 | 
			
		||||
        this.arenaHandler.loadArenas();
 | 
			
		||||
        this.arenaHandler.loadGroups();
 | 
			
		||||
 | 
			
		||||
        // Reload configuration
 | 
			
		||||
        this.reloadConfig();
 | 
			
		||||
        configuration.load();
 | 
			
		||||
 | 
			
		||||
        // Clear record caches
 | 
			
		||||
        dropperRecordExpansion.clearCaches();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -106,6 +135,8 @@ public final class Dropper extends JavaPlugin {
 | 
			
		||||
    public void onEnable() {
 | 
			
		||||
        // Plugin startup logic
 | 
			
		||||
        instance = this;
 | 
			
		||||
        this.saveDefaultConfig();
 | 
			
		||||
        this.configuration = new DropperConfiguration(this.getConfig());
 | 
			
		||||
        this.playerRegistry = new DropperArenaPlayerRegistry();
 | 
			
		||||
        this.arenaHandler = new DropperArenaHandler();
 | 
			
		||||
        this.arenaHandler.loadArenas();
 | 
			
		||||
@@ -113,7 +144,7 @@ public final class Dropper extends JavaPlugin {
 | 
			
		||||
 | 
			
		||||
        PluginManager pluginManager = getServer().getPluginManager();
 | 
			
		||||
        pluginManager.registerEvents(new DamageListener(), this);
 | 
			
		||||
        pluginManager.registerEvents(new MoveListener(), this);
 | 
			
		||||
        pluginManager.registerEvents(new MoveListener(this.configuration), this);
 | 
			
		||||
        pluginManager.registerEvents(new PlayerLeaveListener(), this);
 | 
			
		||||
        pluginManager.registerEvents(new CommandListener(), this);
 | 
			
		||||
 | 
			
		||||
@@ -122,14 +153,15 @@ public final class Dropper extends JavaPlugin {
 | 
			
		||||
        registerCommand("dropperList", new ListArenaCommand(), null);
 | 
			
		||||
        registerCommand("dropperJoin", new JoinArenaCommand(), new JoinArenaTabCompleter());
 | 
			
		||||
        registerCommand("dropperLeave", new LeaveArenaCommand(), null);
 | 
			
		||||
        registerCommand("dropperEdit", new EditArenaCommand(), new EditArenaTabCompleter());
 | 
			
		||||
        registerCommand("dropperEdit", new EditArenaCommand(this.configuration), new EditArenaTabCompleter());
 | 
			
		||||
        registerCommand("dropperRemove", new RemoveArenaCommand(), new RemoveArenaTabCompleter());
 | 
			
		||||
        registerCommand("dropperGroupSet", new GroupSetCommand(), null);
 | 
			
		||||
        registerCommand("dropperGroupSwap", new GroupSwapCommand(), null);
 | 
			
		||||
        registerCommand("dropperGroupList", new GroupListCommand(), null);
 | 
			
		||||
 | 
			
		||||
        if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
 | 
			
		||||
            if (!new DropperRecordExpansion(this).register()) {
 | 
			
		||||
            this.dropperRecordExpansion = new DropperRecordExpansion(this);
 | 
			
		||||
            if (!this.dropperRecordExpansion.register()) {
 | 
			
		||||
                getLogger().log(Level.WARNING, "Unable to register PlaceholderAPI expansion!");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
package net.knarcraft.dropper.property;
 | 
			
		||||
package net.knarcraft.dropper.arena;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package net.knarcraft.dropper.property;
 | 
			
		||||
package net.knarcraft.dropper.arena;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package net.knarcraft.dropper.property;
 | 
			
		||||
package net.knarcraft.dropper.arena;
 | 
			
		||||
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
package net.knarcraft.dropper.arena;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.config.DropperConfiguration;
 | 
			
		||||
import net.knarcraft.dropper.util.StringSanitizer;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
@@ -102,12 +103,13 @@ public class DropperArena {
 | 
			
		||||
     */
 | 
			
		||||
    public DropperArena(@NotNull String arenaName, @NotNull Location spawnLocation,
 | 
			
		||||
                        @NotNull DropperArenaHandler arenaHandler) {
 | 
			
		||||
        DropperConfiguration configuration = Dropper.getInstance().getDropperConfiguration();
 | 
			
		||||
        this.arenaId = UUID.randomUUID();
 | 
			
		||||
        this.arenaName = arenaName;
 | 
			
		||||
        this.spawnLocation = spawnLocation;
 | 
			
		||||
        this.exitLocation = null;
 | 
			
		||||
        this.playerVerticalVelocity = 3.92;
 | 
			
		||||
        this.playerHorizontalVelocity = 1;
 | 
			
		||||
        this.playerVerticalVelocity = configuration.getVerticalVelocity();
 | 
			
		||||
        this.playerHorizontalVelocity = configuration.getHorizontalVelocity();
 | 
			
		||||
 | 
			
		||||
        Map<ArenaGameMode, DropperArenaRecordsRegistry> recordRegistries = new HashMap<>();
 | 
			
		||||
        for (ArenaGameMode arenaGameMode : ArenaGameMode.values()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ package net.knarcraft.dropper.arena;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.container.SerializableUUID;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ package net.knarcraft.dropper.arena;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.container.SerializableUUID;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.util.StringSanitizer;
 | 
			
		||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
package net.knarcraft.dropper.arena;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.config.DropperConfiguration;
 | 
			
		||||
import net.knarcraft.dropper.property.RecordResult;
 | 
			
		||||
import net.knarcraft.dropper.util.PlayerTeleporter;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
@@ -37,7 +37,10 @@ public class DropperArenaSession {
 | 
			
		||||
        this.deaths = 0;
 | 
			
		||||
        this.startTime = System.currentTimeMillis();
 | 
			
		||||
 | 
			
		||||
        this.entryState = new PlayerEntryState(player, gameMode);
 | 
			
		||||
        DropperConfiguration configuration = Dropper.getInstance().getDropperConfiguration();
 | 
			
		||||
        boolean makeInvisible = configuration.makePlayersInvisible();
 | 
			
		||||
        boolean disableCollision = configuration.disableHitCollision();
 | 
			
		||||
        this.entryState = new PlayerEntryState(player, gameMode, makeInvisible, disableCollision);
 | 
			
		||||
        // Make the player fly to improve mobility in the air
 | 
			
		||||
        this.entryState.setArenaState(this.arena.getPlayerHorizontalVelocity());
 | 
			
		||||
    }
 | 
			
		||||
@@ -68,7 +71,12 @@ public class DropperArenaSession {
 | 
			
		||||
        stopSession();
 | 
			
		||||
 | 
			
		||||
        // Check for, and display, records
 | 
			
		||||
        registerRecord();
 | 
			
		||||
        Dropper dropper = Dropper.getInstance();
 | 
			
		||||
        boolean ignore = dropper.getDropperConfiguration().ignoreRecordsUntilGroupBeatenOnce();
 | 
			
		||||
        DropperArenaGroup group = dropper.getArenaHandler().getGroup(this.arena.getArenaId());
 | 
			
		||||
        if (!ignore || group == null || group.hasBeatenAll(this.gameMode, this.player)) {
 | 
			
		||||
            registerRecord();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Mark the arena as cleared
 | 
			
		||||
        if (this.arena.getData().addCompleted(this.gameMode, this.player)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
package net.knarcraft.dropper.arena;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import org.bukkit.GameMode;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
@@ -22,6 +21,8 @@ public class PlayerEntryState {
 | 
			
		||||
    private final boolean originalInvulnerable;
 | 
			
		||||
    private final boolean originalIsSwimming;
 | 
			
		||||
    private final boolean originalCollideAble;
 | 
			
		||||
    private final boolean makePlayerInvisible;
 | 
			
		||||
    private final boolean disableHitCollision;
 | 
			
		||||
    private final ArenaGameMode arenaGameMode;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -29,7 +30,8 @@ public class PlayerEntryState {
 | 
			
		||||
     *
 | 
			
		||||
     * @param player <p>The player whose state should be stored</p>
 | 
			
		||||
     */
 | 
			
		||||
    public PlayerEntryState(@NotNull Player player, @NotNull ArenaGameMode arenaGameMode) {
 | 
			
		||||
    public PlayerEntryState(@NotNull Player player, @NotNull ArenaGameMode arenaGameMode, boolean makePlayerInvisible,
 | 
			
		||||
                            boolean disableHitCollision) {
 | 
			
		||||
        this.player = player;
 | 
			
		||||
        this.entryLocation = player.getLocation().clone();
 | 
			
		||||
        this.originalFlySpeed = player.getFlySpeed();
 | 
			
		||||
@@ -40,6 +42,8 @@ public class PlayerEntryState {
 | 
			
		||||
        this.originalIsSwimming = player.isSwimming();
 | 
			
		||||
        this.arenaGameMode = arenaGameMode;
 | 
			
		||||
        this.originalCollideAble = player.isCollidable();
 | 
			
		||||
        this.makePlayerInvisible = makePlayerInvisible;
 | 
			
		||||
        this.disableHitCollision = disableHitCollision;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -52,8 +56,13 @@ public class PlayerEntryState {
 | 
			
		||||
        this.player.setFlying(true);
 | 
			
		||||
        this.player.setGameMode(GameMode.ADVENTURE);
 | 
			
		||||
        this.player.setSwimming(false);
 | 
			
		||||
        this.player.setCollidable(false);
 | 
			
		||||
        this.player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, PotionEffect.INFINITE_DURATION, 3));
 | 
			
		||||
        if (this.disableHitCollision) {
 | 
			
		||||
            this.player.setCollidable(false);
 | 
			
		||||
        }
 | 
			
		||||
        if (this.makePlayerInvisible) {
 | 
			
		||||
            this.player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY,
 | 
			
		||||
                    PotionEffect.INFINITE_DURATION, 3));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If playing on the inverted game-mode, negate the horizontal velocity to swap the controls
 | 
			
		||||
        if (arenaGameMode == ArenaGameMode.INVERTED) {
 | 
			
		||||
@@ -73,8 +82,12 @@ public class PlayerEntryState {
 | 
			
		||||
        this.player.setFlySpeed(this.originalFlySpeed);
 | 
			
		||||
        this.player.setInvulnerable(this.originalInvulnerable);
 | 
			
		||||
        this.player.setSwimming(this.originalIsSwimming);
 | 
			
		||||
        this.player.setCollidable(this.originalCollideAble);
 | 
			
		||||
        this.player.removePotionEffect(PotionEffectType.INVISIBILITY);
 | 
			
		||||
        if (this.disableHitCollision) {
 | 
			
		||||
            this.player.setCollidable(this.originalCollideAble);
 | 
			
		||||
        }
 | 
			
		||||
        if (this.makePlayerInvisible) {
 | 
			
		||||
            this.player.removePotionEffect(PotionEffectType.INVISIBILITY);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,9 @@
 | 
			
		||||
package net.knarcraft.dropper.command;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.arena.ArenaEditableProperty;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaEditableProperty;
 | 
			
		||||
import net.knarcraft.dropper.config.DropperConfiguration;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.command.Command;
 | 
			
		||||
@@ -16,6 +17,17 @@ import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 */
 | 
			
		||||
public class EditArenaCommand implements CommandExecutor {
 | 
			
		||||
 | 
			
		||||
    private final DropperConfiguration configuration;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new edit arena command
 | 
			
		||||
     *
 | 
			
		||||
     * @param configuration <p>The configuration to use</p>
 | 
			
		||||
     */
 | 
			
		||||
    public EditArenaCommand(DropperConfiguration configuration) {
 | 
			
		||||
        this.configuration = configuration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
 | 
			
		||||
                             @NotNull String[] arguments) {
 | 
			
		||||
@@ -92,7 +104,7 @@ public class EditArenaCommand implements CommandExecutor {
 | 
			
		||||
        try {
 | 
			
		||||
            velocity = Double.parseDouble(velocityString);
 | 
			
		||||
        } catch (NumberFormatException exception) {
 | 
			
		||||
            velocity = 3.92;
 | 
			
		||||
            velocity = configuration.getVerticalVelocity();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Require at least speed of 0.001, and at most 75 blocks/s
 | 
			
		||||
@@ -111,12 +123,7 @@ public class EditArenaCommand implements CommandExecutor {
 | 
			
		||||
        try {
 | 
			
		||||
            velocity = Float.parseFloat(velocityString);
 | 
			
		||||
        } catch (NumberFormatException exception) {
 | 
			
		||||
            velocity = 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Make sure the velocity isn't exactly 0
 | 
			
		||||
        if (velocity == 0) {
 | 
			
		||||
            velocity = 0.5f;
 | 
			
		||||
            velocity = configuration.getHorizontalVelocity();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If outside bonds, choose the most extreme value
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
package net.knarcraft.dropper.command;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaPlayerRegistry;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaSession;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.config.DropperConfiguration;
 | 
			
		||||
import net.knarcraft.dropper.util.PlayerTeleporter;
 | 
			
		||||
import org.bukkit.command.Command;
 | 
			
		||||
import org.bukkit.command.CommandExecutor;
 | 
			
		||||
@@ -77,7 +78,8 @@ public class JoinArenaCommand implements CommandExecutor {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Make sure the player has beaten the arena once in normal mode before playing another mode
 | 
			
		||||
        if (gameMode != ArenaGameMode.DEFAULT &&
 | 
			
		||||
        if (Dropper.getInstance().getDropperConfiguration().mustDoNormalModeFirst() &&
 | 
			
		||||
                gameMode != ArenaGameMode.DEFAULT &&
 | 
			
		||||
                specifiedArena.getData().hasNotCompleted(ArenaGameMode.DEFAULT, player)) {
 | 
			
		||||
            player.sendMessage("You must complete this arena in normal mode first!");
 | 
			
		||||
            return false;
 | 
			
		||||
@@ -113,16 +115,17 @@ public class JoinArenaCommand implements CommandExecutor {
 | 
			
		||||
     */
 | 
			
		||||
    private boolean doGroupChecks(@NotNull DropperArena dropperArena, @NotNull DropperArenaGroup arenaGroup,
 | 
			
		||||
                                  @NotNull ArenaGameMode arenaGameMode, @NotNull Player player) {
 | 
			
		||||
        DropperConfiguration configuration = Dropper.getInstance().getDropperConfiguration();
 | 
			
		||||
        // Require that players beat all arenas in the group in the normal game-mode before trying challenge modes
 | 
			
		||||
        if (arenaGameMode != ArenaGameMode.DEFAULT) {
 | 
			
		||||
            if (!arenaGroup.hasBeatenAll(ArenaGameMode.DEFAULT, player)) {
 | 
			
		||||
                player.sendMessage("You have not yet beaten all arenas in this group!");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        if (configuration.mustDoNormalModeFirst() && arenaGameMode != ArenaGameMode.DEFAULT &&
 | 
			
		||||
                !arenaGroup.hasBeatenAll(ArenaGameMode.DEFAULT, player)) {
 | 
			
		||||
            player.sendMessage("You have not yet beaten all arenas in this group!");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Require that the player has beaten the previous arena on the same game-mode before trying this one
 | 
			
		||||
        if (!arenaGroup.canPlay(arenaGameMode, player, dropperArena.getArenaId())) {
 | 
			
		||||
        if (configuration.mustDoGroupedInSequence() &&
 | 
			
		||||
                !arenaGroup.canPlay(arenaGameMode, player, dropperArena.getArenaId())) {
 | 
			
		||||
            player.sendMessage("You have not yet beaten the previous arena!");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,226 @@
 | 
			
		||||
package net.knarcraft.dropper.config;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.NamespacedKey;
 | 
			
		||||
import org.bukkit.Tag;
 | 
			
		||||
import org.bukkit.configuration.file.FileConfiguration;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
import java.util.regex.Matcher;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
public class DropperConfiguration {
 | 
			
		||||
 | 
			
		||||
    private final FileConfiguration configuration;
 | 
			
		||||
 | 
			
		||||
    private double verticalVelocity;
 | 
			
		||||
    private float horizontalVelocity;
 | 
			
		||||
    private int randomlyInvertedTimer;
 | 
			
		||||
    private boolean mustDoGroupedInSequence;
 | 
			
		||||
    private boolean ignoreRecordsUntilGroupBeatenOnce;
 | 
			
		||||
    private boolean mustDoNormalModeFirst;
 | 
			
		||||
    private boolean makePlayersInvisible;
 | 
			
		||||
    private boolean disableHitCollision;
 | 
			
		||||
    private boolean overrideVerticalVelocity;
 | 
			
		||||
    private double liquidHitBoxDepth;
 | 
			
		||||
    private double solidHitBoxDistance;
 | 
			
		||||
    private Set<Material> blockWhitelist;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new dropper configuration
 | 
			
		||||
     *
 | 
			
		||||
     * @param configuration <p>The YAML configuration to use internally</p>
 | 
			
		||||
     */
 | 
			
		||||
    public DropperConfiguration(FileConfiguration configuration) {
 | 
			
		||||
        this.configuration = configuration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether vertical velocity should be overridden
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>Whether vertical velocity should be overridden</p>
 | 
			
		||||
     */
 | 
			
		||||
    public boolean overrideVerticalVelocity() {
 | 
			
		||||
        return this.overrideVerticalVelocity;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the default vertical velocity
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The default vertical velocity</p>
 | 
			
		||||
     */
 | 
			
		||||
    public double getVerticalVelocity() {
 | 
			
		||||
        return this.verticalVelocity;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the default horizontal velocity
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The default horizontal velocity</p>
 | 
			
		||||
     */
 | 
			
		||||
    public float getHorizontalVelocity() {
 | 
			
		||||
        return this.horizontalVelocity;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the number of seconds before the randomly inverted game-mode toggles
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>Number of seconds before the inversion toggles</p>
 | 
			
		||||
     */
 | 
			
		||||
    public int getRandomlyInvertedTimer() {
 | 
			
		||||
        return this.randomlyInvertedTimer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether grouped arenas must be done in the set sequence
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>Whether grouped arenas must be done in sequence</p>
 | 
			
		||||
     */
 | 
			
		||||
    public boolean mustDoGroupedInSequence() {
 | 
			
		||||
        return this.mustDoGroupedInSequence;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether the normal/default mode must be beaten before playing another game-mode
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>Whether the normal game-mode must be beaten first</p>
 | 
			
		||||
     */
 | 
			
		||||
    public boolean mustDoNormalModeFirst() {
 | 
			
		||||
        return this.mustDoNormalModeFirst;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the types of block which should not trigger a loss
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The materials that should not trigger a loss</p>
 | 
			
		||||
     */
 | 
			
		||||
    public Set<Material> getBlockWhitelist() {
 | 
			
		||||
        return new HashSet<>(this.blockWhitelist);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether records should be discarded, unless the player has already beaten all arenas in the group
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>Whether to ignore records on the first play-through</p>
 | 
			
		||||
     */
 | 
			
		||||
    public boolean ignoreRecordsUntilGroupBeatenOnce() {
 | 
			
		||||
        return this.ignoreRecordsUntilGroupBeatenOnce;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether players should be made invisible while in an arena
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>Whether players should be made invisible</p>
 | 
			
		||||
     */
 | 
			
		||||
    public boolean makePlayersInvisible() {
 | 
			
		||||
        return this.makePlayersInvisible;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether entity hit-collision of players in an arena should be disabled
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>Whether to disable hit collision</p>
 | 
			
		||||
     */
 | 
			
		||||
    public boolean disableHitCollision() {
 | 
			
		||||
        return this.disableHitCollision;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the negative depth a player must reach in a liquid block for fail/win detection to trigger
 | 
			
		||||
     *
 | 
			
		||||
     * <p>This decides how far inside a non-solid block the player must go before detection triggers. The closer to -1
 | 
			
		||||
     * it is, the more accurate it will seem to the player, but the likelihood of not detecting the hit increases.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The liquid hit box depth to use</p>
 | 
			
		||||
     */
 | 
			
		||||
    public double getLiquidHitBoxDepth() {
 | 
			
		||||
        return this.liquidHitBoxDepth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the positive distance a player must at most be from a block for fail/win detection to trigger
 | 
			
		||||
     *
 | 
			
		||||
     * <p>This decides the distance the player must be from a block below them before a hit triggers. If too low, the
 | 
			
		||||
     * likelihood of detecting the hit decreases, but it won't look like the player hit the block without being near.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The solid hit box distance to use</p>
 | 
			
		||||
     */
 | 
			
		||||
    public double getSolidHitBoxDistance() {
 | 
			
		||||
        return this.solidHitBoxDistance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Loads all configuration values from disk
 | 
			
		||||
     */
 | 
			
		||||
    public void load() {
 | 
			
		||||
        this.verticalVelocity = configuration.getDouble("verticalVelocity", 1.0);
 | 
			
		||||
        this.horizontalVelocity = (float) configuration.getDouble("horizontalVelocity", 1.0);
 | 
			
		||||
        this.randomlyInvertedTimer = configuration.getInt("randomlyInvertedTimer", 7);
 | 
			
		||||
        this.mustDoGroupedInSequence = configuration.getBoolean("mustDoGroupedInSequence", true);
 | 
			
		||||
        this.ignoreRecordsUntilGroupBeatenOnce = configuration.getBoolean("ignoreRecordsUntilGroupBeatenOnce", false);
 | 
			
		||||
        this.mustDoNormalModeFirst = configuration.getBoolean("mustDoNormalModeFirst", true);
 | 
			
		||||
        this.makePlayersInvisible = configuration.getBoolean("makePlayersInvisible", false);
 | 
			
		||||
        this.disableHitCollision = configuration.getBoolean("disableHitCollision", true);
 | 
			
		||||
        this.overrideVerticalVelocity = configuration.getBoolean("overrideVerticalVelocity", true);
 | 
			
		||||
        this.liquidHitBoxDepth = configuration.getDouble("liquidHitBoxDepth", -0.8);
 | 
			
		||||
        this.solidHitBoxDistance = configuration.getDouble("solidHitBoxDistance", 0.2);
 | 
			
		||||
 | 
			
		||||
        loadBlockWhitelist();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Loads the materials specified in the block whitelist
 | 
			
		||||
     */
 | 
			
		||||
    private void loadBlockWhitelist() {
 | 
			
		||||
        this.blockWhitelist = new HashSet<>();
 | 
			
		||||
        List<?> blockWhitelist = configuration.getList("blockWhiteList", new ArrayList<>());
 | 
			
		||||
        for (Object value : blockWhitelist) {
 | 
			
		||||
            if (!(value instanceof String string)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Try to parse a material tag first
 | 
			
		||||
            if (parseMaterialTag(string)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Try to parse a material name
 | 
			
		||||
            Material matched = Material.matchMaterial(string);
 | 
			
		||||
            if (matched != null) {
 | 
			
		||||
                this.blockWhitelist.add(matched);
 | 
			
		||||
            } else {
 | 
			
		||||
                Dropper.log(Level.WARNING, "Unable to parse: " + string);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Tries to parse the material tag in the specified material name
 | 
			
		||||
     *
 | 
			
		||||
     * @param materialName <p>The material name that might be a material tag</p>
 | 
			
		||||
     * @return <p>True if a tag was found</p>
 | 
			
		||||
     */
 | 
			
		||||
    private boolean parseMaterialTag(String materialName) {
 | 
			
		||||
        Pattern pattern = Pattern.compile("^\\+([a-zA-Z_]+)");
 | 
			
		||||
        Matcher matcher = pattern.matcher(materialName);
 | 
			
		||||
        if (matcher.find()) {
 | 
			
		||||
            // The material is a material tag
 | 
			
		||||
            Tag<Material> tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, NamespacedKey.minecraft(
 | 
			
		||||
                    matcher.group(1).toLowerCase()), Material.class);
 | 
			
		||||
            if (tag != null) {
 | 
			
		||||
                this.blockWhitelist.addAll(tag.getValues());
 | 
			
		||||
            } else {
 | 
			
		||||
                Dropper.log(Level.WARNING, "Unable to parse: " + materialName);
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
package net.knarcraft.dropper.listener;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaPlayerRegistry;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaSession;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.config.DropperConfiguration;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.Tag;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
@@ -24,6 +24,17 @@ import java.util.Set;
 | 
			
		||||
 */
 | 
			
		||||
public class MoveListener implements Listener {
 | 
			
		||||
 | 
			
		||||
    private final DropperConfiguration configuration;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new move listener
 | 
			
		||||
     *
 | 
			
		||||
     * @param configuration <p>The configuration to use</p>
 | 
			
		||||
     */
 | 
			
		||||
    public MoveListener(DropperConfiguration configuration) {
 | 
			
		||||
        this.configuration = configuration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void onPlayerMove(PlayerMoveEvent event) {
 | 
			
		||||
        // Ignore if no actual movement is happening
 | 
			
		||||
@@ -65,12 +76,8 @@ public class MoveListener implements Listener {
 | 
			
		||||
     * @return <p>True if a special block has been hit</p>
 | 
			
		||||
     */
 | 
			
		||||
    private boolean checkForSpecialBlock(DropperArenaSession arenaSession, Location toLocation) {
 | 
			
		||||
        /* This decides how far inside a non-solid block the player must go before detection triggers. The closer to -1
 | 
			
		||||
           it is, the more accurate it will seem to the player, but the likelihood of not detecting the hit decreases */
 | 
			
		||||
        double liquidDepth = -0.8;
 | 
			
		||||
        /* This decides the distance the player must be from the block below before a hit triggers. If too low, the 
 | 
			
		||||
           likelihood of detecting the hit decreases, but the immersion increases. */
 | 
			
		||||
        double solidDepth = 0.2;
 | 
			
		||||
        double liquidDepth = configuration.getLiquidHitBoxDepth();
 | 
			
		||||
        double solidDepth = configuration.getSolidHitBoxDistance();
 | 
			
		||||
 | 
			
		||||
        // Check if the player enters water
 | 
			
		||||
        Material winBlockType = arenaSession.getArena().getWinBlockType();
 | 
			
		||||
@@ -84,10 +91,10 @@ public class MoveListener implements Listener {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check if the player is about to hit a non-air and non-liquid block
 | 
			
		||||
        Set<Material> whitelisted = configuration.getBlockWhitelist();
 | 
			
		||||
        for (Block block : getBlocksBeneathLocation(toLocation, solidDepth)) {
 | 
			
		||||
            Material blockType = block.getType();
 | 
			
		||||
            if (!blockType.isAir() && blockType != Material.STRUCTURE_VOID && blockType != Material.WATER &&
 | 
			
		||||
                    blockType != Material.LAVA && !Tag.WALL_SIGNS.isTagged(blockType)) {
 | 
			
		||||
            if (!blockType.isAir() && !whitelisted.contains(blockType)) {
 | 
			
		||||
                arenaSession.triggerLoss();
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
@@ -118,11 +125,14 @@ public class MoveListener implements Listener {
 | 
			
		||||
     * @param session <p>The session to update the velocity for</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void updatePlayerVelocity(@NotNull DropperArenaSession session) {
 | 
			
		||||
        Player player = session.getPlayer();
 | 
			
		||||
        Vector playerVelocity = player.getVelocity();
 | 
			
		||||
        double arenaVelocity = session.getArena().getPlayerVerticalVelocity();
 | 
			
		||||
        Vector newVelocity = new Vector(playerVelocity.getX(), -arenaVelocity, playerVelocity.getZ());
 | 
			
		||||
        player.setVelocity(newVelocity);
 | 
			
		||||
        // Override the vertical velocity, if enabled
 | 
			
		||||
        if (configuration.overrideVerticalVelocity()) {
 | 
			
		||||
            Player player = session.getPlayer();
 | 
			
		||||
            Vector playerVelocity = player.getVelocity();
 | 
			
		||||
            double arenaVelocity = session.getArena().getPlayerVerticalVelocity();
 | 
			
		||||
            Vector newVelocity = new Vector(playerVelocity.getX(), -arenaVelocity, playerVelocity.getZ());
 | 
			
		||||
            player.setVelocity(newVelocity);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Toggle the direction of the player's flying, as necessary
 | 
			
		||||
        toggleFlyInversion(session);
 | 
			
		||||
@@ -139,7 +149,7 @@ public class MoveListener implements Listener {
 | 
			
		||||
        }
 | 
			
		||||
        Player player = session.getPlayer();
 | 
			
		||||
        float horizontalVelocity = session.getArena().getPlayerHorizontalVelocity();
 | 
			
		||||
        float secondsBetweenToggle = 7;
 | 
			
		||||
        float secondsBetweenToggle = configuration.getRandomlyInvertedTimer();
 | 
			
		||||
        int seconds = Calendar.getInstance().get(Calendar.SECOND);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,15 @@ package net.knarcraft.dropper.placeholder;
 | 
			
		||||
 | 
			
		||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaHandler;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaRecordsRegistry;
 | 
			
		||||
import net.knarcraft.dropper.arena.record.ArenaRecord;
 | 
			
		||||
import net.knarcraft.dropper.placeholder.parsing.InfoType;
 | 
			
		||||
import net.knarcraft.dropper.placeholder.parsing.RecordType;
 | 
			
		||||
import net.knarcraft.dropper.placeholder.parsing.SelectionType;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.property.RecordType;
 | 
			
		||||
import net.knarcraft.dropper.util.DropperGroupRecordHelper;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.OfflinePlayer;
 | 
			
		||||
@@ -97,6 +97,14 @@ public class DropperRecordExpansion extends PlaceholderExpansion {
 | 
			
		||||
        return Objects.requireNonNullElse(info, parameters);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Clears all record caches
 | 
			
		||||
     */
 | 
			
		||||
    public void clearCaches() {
 | 
			
		||||
        this.groupRecordDeathsCache.clear();
 | 
			
		||||
        this.groupRecordTimeCache.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets a piece of record information from a dropper arena group
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
package net.knarcraft.dropper.placeholder;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.arena.record.ArenaRecord;
 | 
			
		||||
import net.knarcraft.dropper.placeholder.parsing.RecordType;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.property.RecordType;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package net.knarcraft.dropper.placeholder.parsing;
 | 
			
		||||
package net.knarcraft.dropper.property;
 | 
			
		||||
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
package net.knarcraft.dropper.util;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.arena.ArenaStorageKey;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaData;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaRecordsRegistry;
 | 
			
		||||
import net.knarcraft.dropper.container.SerializableMaterial;
 | 
			
		||||
import net.knarcraft.dropper.container.SerializableUUID;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaStorageKey;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.configuration.ConfigurationSection;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
package net.knarcraft.dropper.util;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaHandler;
 | 
			
		||||
import net.knarcraft.dropper.arena.record.ArenaRecord;
 | 
			
		||||
import net.knarcraft.dropper.arena.record.SummableArenaRecord;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
package net.knarcraft.dropper.util;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.arena.ArenaEditableProperty;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaEditableProperty;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										50
									
								
								src/main/resources/config.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/main/resources/config.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
# Configuration values for droppers
 | 
			
		||||
dropper:
 | 
			
		||||
  # Whether the vertical velocity should be overridden, and thus changeable. If not enabled, all horizontalVelocity 
 | 
			
		||||
  # settings, both the global one and per-arena, will be ignored.
 | 
			
		||||
  overrideVerticalVelocity: true
 | 
			
		||||
  
 | 
			
		||||
  # The vertical velocity used as default for all arenas. Must be greater than 0. 3.92 is the max speed of a falling
 | 
			
		||||
  # player.
 | 
			
		||||
  verticalVelocity: 1.0
 | 
			
		||||
  
 | 
			
		||||
  # The horizontal velocity used as default for all arenas (technically fly-speed). Must be between 0 (exclusive) and 1 
 | 
			
		||||
  # (inclusive).
 | 
			
		||||
  horizontalVelocity: 1.0
 | 
			
		||||
  
 | 
			
		||||
  # The number of seconds before the randomly inverted game-mode switches between normal and inverted movement
 | 
			
		||||
  randomlyInvertedTimer: 7
 | 
			
		||||
  
 | 
			
		||||
  # Whether grouped dropper arenas must be played in the correct sequence
 | 
			
		||||
  mustDoGroupedInSequence: true
 | 
			
		||||
  
 | 
			
		||||
  # Whether records won't be registered unless the player has already beaten all arenas in a group. That means players
 | 
			
		||||
  # are required to do a second play-through to register a record for a grouped arena.
 | 
			
		||||
  ignoreRecordsUntilGroupBeatenOnce: false
 | 
			
		||||
  
 | 
			
		||||
  # Whether a player must do the normal/default game-mode before playing any other game-modes
 | 
			
		||||
  mustDoNormalModeFirst: true
 | 
			
		||||
  
 | 
			
		||||
  # Whether players should be made invisible while playing in a dropper arena
 | 
			
		||||
  makePlayersInvisible: false
 | 
			
		||||
  
 | 
			
		||||
  # Whether players should have their entity hit collision disabled while in an arena. This prevents players from 
 | 
			
		||||
  # pushing each-other if in the same arena.
 | 
			
		||||
  disableHitCollision: true
 | 
			
		||||
  
 | 
			
		||||
  # This decides how far inside a non-solid block the player must go before detection triggers. The closer to -1
 | 
			
		||||
  # it is, the more accurate it will seem to the player, but the likelihood of not detecting the hit increases.
 | 
			
		||||
  liquidHitBoxDepth: -0.8
 | 
			
		||||
  
 | 
			
		||||
  # This decides the distance the player must be from a block below them before a hit triggers. If too low, the 
 | 
			
		||||
  # likelihood of detecting the hit decreases, but it won't look like the player hit the block without being near.
 | 
			
		||||
  solidHitBoxDistance: 0.2
 | 
			
		||||
  
 | 
			
		||||
  # A whitelist for which blocks won't trigger a loss when hit/passed through. The win block check happens before the
 | 
			
		||||
  # loss check, so even blocks on the whitelist can be used as the win-block. "+" denotes a material tag.
 | 
			
		||||
  blockWhitelist:
 | 
			
		||||
    - WATER
 | 
			
		||||
    - LAVA
 | 
			
		||||
    - +WALL_SIGNS
 | 
			
		||||
    - +STANDING_SIGNS
 | 
			
		||||
    - STRUCTURE_VOID
 | 
			
		||||
		Reference in New Issue
	
	Block a user