mirror of
				https://github.com/SunNetservers/MiniGames.git
				synced 2025-11-04 03:33:47 +01:00 
			
		
		
		
	Implements several configuration options #15
This commit is contained in:
		@@ -1,5 +1,6 @@
 | 
				
			|||||||
package net.knarcraft.dropper;
 | 
					package net.knarcraft.dropper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaData;
 | 
					import net.knarcraft.dropper.arena.DropperArenaData;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
					import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaHandler;
 | 
					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.ReloadCommand;
 | 
				
			||||||
import net.knarcraft.dropper.command.RemoveArenaCommand;
 | 
					import net.knarcraft.dropper.command.RemoveArenaCommand;
 | 
				
			||||||
import net.knarcraft.dropper.command.RemoveArenaTabCompleter;
 | 
					import net.knarcraft.dropper.command.RemoveArenaTabCompleter;
 | 
				
			||||||
 | 
					import net.knarcraft.dropper.config.DropperConfiguration;
 | 
				
			||||||
import net.knarcraft.dropper.container.SerializableMaterial;
 | 
					import net.knarcraft.dropper.container.SerializableMaterial;
 | 
				
			||||||
import net.knarcraft.dropper.container.SerializableUUID;
 | 
					import net.knarcraft.dropper.container.SerializableUUID;
 | 
				
			||||||
import net.knarcraft.dropper.listener.CommandListener;
 | 
					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.MoveListener;
 | 
				
			||||||
import net.knarcraft.dropper.listener.PlayerLeaveListener;
 | 
					import net.knarcraft.dropper.listener.PlayerLeaveListener;
 | 
				
			||||||
import net.knarcraft.dropper.placeholder.DropperRecordExpansion;
 | 
					import net.knarcraft.dropper.placeholder.DropperRecordExpansion;
 | 
				
			||||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
					 | 
				
			||||||
import org.bukkit.Bukkit;
 | 
					import org.bukkit.Bukkit;
 | 
				
			||||||
import org.bukkit.command.CommandExecutor;
 | 
					import org.bukkit.command.CommandExecutor;
 | 
				
			||||||
import org.bukkit.command.PluginCommand;
 | 
					import org.bukkit.command.PluginCommand;
 | 
				
			||||||
@@ -49,8 +50,10 @@ import java.util.logging.Level;
 | 
				
			|||||||
public final class Dropper extends JavaPlugin {
 | 
					public final class Dropper extends JavaPlugin {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static Dropper instance;
 | 
					    private static Dropper instance;
 | 
				
			||||||
 | 
					    private DropperConfiguration configuration;
 | 
				
			||||||
    private DropperArenaHandler arenaHandler;
 | 
					    private DropperArenaHandler arenaHandler;
 | 
				
			||||||
    private DropperArenaPlayerRegistry playerRegistry;
 | 
					    private DropperArenaPlayerRegistry playerRegistry;
 | 
				
			||||||
 | 
					    private DropperRecordExpansion dropperRecordExpansion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Gets an instance of this plugin
 | 
					     * Gets an instance of this plugin
 | 
				
			||||||
@@ -79,6 +82,25 @@ public final class Dropper extends JavaPlugin {
 | 
				
			|||||||
        return this.playerRegistry;
 | 
					        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
 | 
					     * Reloads all configurations and data from disk
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@@ -86,6 +108,13 @@ public final class Dropper extends JavaPlugin {
 | 
				
			|||||||
        // Load all arenas again
 | 
					        // Load all arenas again
 | 
				
			||||||
        this.arenaHandler.loadArenas();
 | 
					        this.arenaHandler.loadArenas();
 | 
				
			||||||
        this.arenaHandler.loadGroups();
 | 
					        this.arenaHandler.loadGroups();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Reload configuration
 | 
				
			||||||
 | 
					        this.reloadConfig();
 | 
				
			||||||
 | 
					        configuration.load();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Clear record caches
 | 
				
			||||||
 | 
					        dropperRecordExpansion.clearCaches();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
@@ -106,6 +135,8 @@ public final class Dropper extends JavaPlugin {
 | 
				
			|||||||
    public void onEnable() {
 | 
					    public void onEnable() {
 | 
				
			||||||
        // Plugin startup logic
 | 
					        // Plugin startup logic
 | 
				
			||||||
        instance = this;
 | 
					        instance = this;
 | 
				
			||||||
 | 
					        this.saveDefaultConfig();
 | 
				
			||||||
 | 
					        this.configuration = new DropperConfiguration(this.getConfig());
 | 
				
			||||||
        this.playerRegistry = new DropperArenaPlayerRegistry();
 | 
					        this.playerRegistry = new DropperArenaPlayerRegistry();
 | 
				
			||||||
        this.arenaHandler = new DropperArenaHandler();
 | 
					        this.arenaHandler = new DropperArenaHandler();
 | 
				
			||||||
        this.arenaHandler.loadArenas();
 | 
					        this.arenaHandler.loadArenas();
 | 
				
			||||||
@@ -113,7 +144,7 @@ public final class Dropper extends JavaPlugin {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        PluginManager pluginManager = getServer().getPluginManager();
 | 
					        PluginManager pluginManager = getServer().getPluginManager();
 | 
				
			||||||
        pluginManager.registerEvents(new DamageListener(), this);
 | 
					        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 PlayerLeaveListener(), this);
 | 
				
			||||||
        pluginManager.registerEvents(new CommandListener(), this);
 | 
					        pluginManager.registerEvents(new CommandListener(), this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -122,14 +153,15 @@ public final class Dropper extends JavaPlugin {
 | 
				
			|||||||
        registerCommand("dropperList", new ListArenaCommand(), null);
 | 
					        registerCommand("dropperList", new ListArenaCommand(), null);
 | 
				
			||||||
        registerCommand("dropperJoin", new JoinArenaCommand(), new JoinArenaTabCompleter());
 | 
					        registerCommand("dropperJoin", new JoinArenaCommand(), new JoinArenaTabCompleter());
 | 
				
			||||||
        registerCommand("dropperLeave", new LeaveArenaCommand(), null);
 | 
					        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("dropperRemove", new RemoveArenaCommand(), new RemoveArenaTabCompleter());
 | 
				
			||||||
        registerCommand("dropperGroupSet", new GroupSetCommand(), null);
 | 
					        registerCommand("dropperGroupSet", new GroupSetCommand(), null);
 | 
				
			||||||
        registerCommand("dropperGroupSwap", new GroupSwapCommand(), null);
 | 
					        registerCommand("dropperGroupSwap", new GroupSwapCommand(), null);
 | 
				
			||||||
        registerCommand("dropperGroupList", new GroupListCommand(), null);
 | 
					        registerCommand("dropperGroupList", new GroupListCommand(), null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != 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!");
 | 
					                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.NotNull;
 | 
				
			||||||
import org.jetbrains.annotations.Nullable;
 | 
					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.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
package net.knarcraft.dropper.property;
 | 
					package net.knarcraft.dropper.arena;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package net.knarcraft.dropper.arena;
 | 
					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 net.knarcraft.dropper.util.StringSanitizer;
 | 
				
			||||||
import org.bukkit.Location;
 | 
					import org.bukkit.Location;
 | 
				
			||||||
import org.bukkit.Material;
 | 
					import org.bukkit.Material;
 | 
				
			||||||
@@ -102,12 +103,13 @@ public class DropperArena {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public DropperArena(@NotNull String arenaName, @NotNull Location spawnLocation,
 | 
					    public DropperArena(@NotNull String arenaName, @NotNull Location spawnLocation,
 | 
				
			||||||
                        @NotNull DropperArenaHandler arenaHandler) {
 | 
					                        @NotNull DropperArenaHandler arenaHandler) {
 | 
				
			||||||
 | 
					        DropperConfiguration configuration = Dropper.getInstance().getDropperConfiguration();
 | 
				
			||||||
        this.arenaId = UUID.randomUUID();
 | 
					        this.arenaId = UUID.randomUUID();
 | 
				
			||||||
        this.arenaName = arenaName;
 | 
					        this.arenaName = arenaName;
 | 
				
			||||||
        this.spawnLocation = spawnLocation;
 | 
					        this.spawnLocation = spawnLocation;
 | 
				
			||||||
        this.exitLocation = null;
 | 
					        this.exitLocation = null;
 | 
				
			||||||
        this.playerVerticalVelocity = 3.92;
 | 
					        this.playerVerticalVelocity = configuration.getVerticalVelocity();
 | 
				
			||||||
        this.playerHorizontalVelocity = 1;
 | 
					        this.playerHorizontalVelocity = configuration.getHorizontalVelocity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Map<ArenaGameMode, DropperArenaRecordsRegistry> recordRegistries = new HashMap<>();
 | 
					        Map<ArenaGameMode, DropperArenaRecordsRegistry> recordRegistries = new HashMap<>();
 | 
				
			||||||
        for (ArenaGameMode arenaGameMode : ArenaGameMode.values()) {
 | 
					        for (ArenaGameMode arenaGameMode : ArenaGameMode.values()) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@ package net.knarcraft.dropper.arena;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.dropper.Dropper;
 | 
					import net.knarcraft.dropper.Dropper;
 | 
				
			||||||
import net.knarcraft.dropper.container.SerializableUUID;
 | 
					import net.knarcraft.dropper.container.SerializableUUID;
 | 
				
			||||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
					 | 
				
			||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
					import org.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@ package net.knarcraft.dropper.arena;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.dropper.Dropper;
 | 
					import net.knarcraft.dropper.Dropper;
 | 
				
			||||||
import net.knarcraft.dropper.container.SerializableUUID;
 | 
					import net.knarcraft.dropper.container.SerializableUUID;
 | 
				
			||||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
					 | 
				
			||||||
import net.knarcraft.dropper.util.StringSanitizer;
 | 
					import net.knarcraft.dropper.util.StringSanitizer;
 | 
				
			||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
					import org.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
package net.knarcraft.dropper.arena;
 | 
					package net.knarcraft.dropper.arena;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.dropper.Dropper;
 | 
					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.property.RecordResult;
 | 
				
			||||||
import net.knarcraft.dropper.util.PlayerTeleporter;
 | 
					import net.knarcraft.dropper.util.PlayerTeleporter;
 | 
				
			||||||
import org.bukkit.Location;
 | 
					import org.bukkit.Location;
 | 
				
			||||||
@@ -37,7 +37,10 @@ public class DropperArenaSession {
 | 
				
			|||||||
        this.deaths = 0;
 | 
					        this.deaths = 0;
 | 
				
			||||||
        this.startTime = System.currentTimeMillis();
 | 
					        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
 | 
					        // Make the player fly to improve mobility in the air
 | 
				
			||||||
        this.entryState.setArenaState(this.arena.getPlayerHorizontalVelocity());
 | 
					        this.entryState.setArenaState(this.arena.getPlayerHorizontalVelocity());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -68,7 +71,12 @@ public class DropperArenaSession {
 | 
				
			|||||||
        stopSession();
 | 
					        stopSession();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Check for, and display, records
 | 
					        // 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
 | 
					        // Mark the arena as cleared
 | 
				
			||||||
        if (this.arena.getData().addCompleted(this.gameMode, this.player)) {
 | 
					        if (this.arena.getData().addCompleted(this.gameMode, this.player)) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
package net.knarcraft.dropper.arena;
 | 
					package net.knarcraft.dropper.arena;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
					 | 
				
			||||||
import org.bukkit.GameMode;
 | 
					import org.bukkit.GameMode;
 | 
				
			||||||
import org.bukkit.Location;
 | 
					import org.bukkit.Location;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
@@ -22,6 +21,8 @@ public class PlayerEntryState {
 | 
				
			|||||||
    private final boolean originalInvulnerable;
 | 
					    private final boolean originalInvulnerable;
 | 
				
			||||||
    private final boolean originalIsSwimming;
 | 
					    private final boolean originalIsSwimming;
 | 
				
			||||||
    private final boolean originalCollideAble;
 | 
					    private final boolean originalCollideAble;
 | 
				
			||||||
 | 
					    private final boolean makePlayerInvisible;
 | 
				
			||||||
 | 
					    private final boolean disableHitCollision;
 | 
				
			||||||
    private final ArenaGameMode arenaGameMode;
 | 
					    private final ArenaGameMode arenaGameMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -29,7 +30,8 @@ public class PlayerEntryState {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param player <p>The player whose state should be stored</p>
 | 
					     * @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.player = player;
 | 
				
			||||||
        this.entryLocation = player.getLocation().clone();
 | 
					        this.entryLocation = player.getLocation().clone();
 | 
				
			||||||
        this.originalFlySpeed = player.getFlySpeed();
 | 
					        this.originalFlySpeed = player.getFlySpeed();
 | 
				
			||||||
@@ -40,6 +42,8 @@ public class PlayerEntryState {
 | 
				
			|||||||
        this.originalIsSwimming = player.isSwimming();
 | 
					        this.originalIsSwimming = player.isSwimming();
 | 
				
			||||||
        this.arenaGameMode = arenaGameMode;
 | 
					        this.arenaGameMode = arenaGameMode;
 | 
				
			||||||
        this.originalCollideAble = player.isCollidable();
 | 
					        this.originalCollideAble = player.isCollidable();
 | 
				
			||||||
 | 
					        this.makePlayerInvisible = makePlayerInvisible;
 | 
				
			||||||
 | 
					        this.disableHitCollision = disableHitCollision;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -52,8 +56,13 @@ public class PlayerEntryState {
 | 
				
			|||||||
        this.player.setFlying(true);
 | 
					        this.player.setFlying(true);
 | 
				
			||||||
        this.player.setGameMode(GameMode.ADVENTURE);
 | 
					        this.player.setGameMode(GameMode.ADVENTURE);
 | 
				
			||||||
        this.player.setSwimming(false);
 | 
					        this.player.setSwimming(false);
 | 
				
			||||||
        this.player.setCollidable(false);
 | 
					        if (this.disableHitCollision) {
 | 
				
			||||||
        this.player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, PotionEffect.INFINITE_DURATION, 3));
 | 
					            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 playing on the inverted game-mode, negate the horizontal velocity to swap the controls
 | 
				
			||||||
        if (arenaGameMode == ArenaGameMode.INVERTED) {
 | 
					        if (arenaGameMode == ArenaGameMode.INVERTED) {
 | 
				
			||||||
@@ -73,8 +82,12 @@ public class PlayerEntryState {
 | 
				
			|||||||
        this.player.setFlySpeed(this.originalFlySpeed);
 | 
					        this.player.setFlySpeed(this.originalFlySpeed);
 | 
				
			||||||
        this.player.setInvulnerable(this.originalInvulnerable);
 | 
					        this.player.setInvulnerable(this.originalInvulnerable);
 | 
				
			||||||
        this.player.setSwimming(this.originalIsSwimming);
 | 
					        this.player.setSwimming(this.originalIsSwimming);
 | 
				
			||||||
        this.player.setCollidable(this.originalCollideAble);
 | 
					        if (this.disableHitCollision) {
 | 
				
			||||||
        this.player.removePotionEffect(PotionEffectType.INVISIBILITY);
 | 
					            this.player.setCollidable(this.originalCollideAble);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.makePlayerInvisible) {
 | 
				
			||||||
 | 
					            this.player.removePotionEffect(PotionEffectType.INVISIBILITY);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,9 @@
 | 
				
			|||||||
package net.knarcraft.dropper.command;
 | 
					package net.knarcraft.dropper.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.dropper.Dropper;
 | 
					import net.knarcraft.dropper.Dropper;
 | 
				
			||||||
 | 
					import net.knarcraft.dropper.arena.ArenaEditableProperty;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
					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.Location;
 | 
				
			||||||
import org.bukkit.Material;
 | 
					import org.bukkit.Material;
 | 
				
			||||||
import org.bukkit.command.Command;
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
@@ -16,6 +17,17 @@ import org.jetbrains.annotations.NotNull;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class EditArenaCommand implements CommandExecutor {
 | 
					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
 | 
					    @Override
 | 
				
			||||||
    public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
 | 
					    public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
 | 
				
			||||||
                             @NotNull String[] arguments) {
 | 
					                             @NotNull String[] arguments) {
 | 
				
			||||||
@@ -92,7 +104,7 @@ public class EditArenaCommand implements CommandExecutor {
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            velocity = Double.parseDouble(velocityString);
 | 
					            velocity = Double.parseDouble(velocityString);
 | 
				
			||||||
        } catch (NumberFormatException exception) {
 | 
					        } catch (NumberFormatException exception) {
 | 
				
			||||||
            velocity = 3.92;
 | 
					            velocity = configuration.getVerticalVelocity();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Require at least speed of 0.001, and at most 75 blocks/s
 | 
					        // Require at least speed of 0.001, and at most 75 blocks/s
 | 
				
			||||||
@@ -111,12 +123,7 @@ public class EditArenaCommand implements CommandExecutor {
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            velocity = Float.parseFloat(velocityString);
 | 
					            velocity = Float.parseFloat(velocityString);
 | 
				
			||||||
        } catch (NumberFormatException exception) {
 | 
					        } catch (NumberFormatException exception) {
 | 
				
			||||||
            velocity = 1;
 | 
					            velocity = configuration.getHorizontalVelocity();
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Make sure the velocity isn't exactly 0
 | 
					 | 
				
			||||||
        if (velocity == 0) {
 | 
					 | 
				
			||||||
            velocity = 0.5f;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If outside bonds, choose the most extreme value
 | 
					        // If outside bonds, choose the most extreme value
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,12 @@
 | 
				
			|||||||
package net.knarcraft.dropper.command;
 | 
					package net.knarcraft.dropper.command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.dropper.Dropper;
 | 
					import net.knarcraft.dropper.Dropper;
 | 
				
			||||||
 | 
					import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
					import net.knarcraft.dropper.arena.DropperArena;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
					import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaPlayerRegistry;
 | 
					import net.knarcraft.dropper.arena.DropperArenaPlayerRegistry;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaSession;
 | 
					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 net.knarcraft.dropper.util.PlayerTeleporter;
 | 
				
			||||||
import org.bukkit.command.Command;
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
import org.bukkit.command.CommandExecutor;
 | 
					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
 | 
					        // 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)) {
 | 
					                specifiedArena.getData().hasNotCompleted(ArenaGameMode.DEFAULT, player)) {
 | 
				
			||||||
            player.sendMessage("You must complete this arena in normal mode first!");
 | 
					            player.sendMessage("You must complete this arena in normal mode first!");
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
@@ -113,16 +115,17 @@ public class JoinArenaCommand implements CommandExecutor {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private boolean doGroupChecks(@NotNull DropperArena dropperArena, @NotNull DropperArenaGroup arenaGroup,
 | 
					    private boolean doGroupChecks(@NotNull DropperArena dropperArena, @NotNull DropperArenaGroup arenaGroup,
 | 
				
			||||||
                                  @NotNull ArenaGameMode arenaGameMode, @NotNull Player player) {
 | 
					                                  @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
 | 
					        // Require that players beat all arenas in the group in the normal game-mode before trying challenge modes
 | 
				
			||||||
        if (arenaGameMode != ArenaGameMode.DEFAULT) {
 | 
					        if (configuration.mustDoNormalModeFirst() && arenaGameMode != ArenaGameMode.DEFAULT &&
 | 
				
			||||||
            if (!arenaGroup.hasBeatenAll(ArenaGameMode.DEFAULT, player)) {
 | 
					                !arenaGroup.hasBeatenAll(ArenaGameMode.DEFAULT, player)) {
 | 
				
			||||||
                player.sendMessage("You have not yet beaten all arenas in this group!");
 | 
					            player.sendMessage("You have not yet beaten all arenas in this group!");
 | 
				
			||||||
                return false;
 | 
					            return false;
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Require that the player has beaten the previous arena on the same game-mode before trying this one
 | 
					        // 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!");
 | 
					            player.sendMessage("You have not yet beaten the previous arena!");
 | 
				
			||||||
            return false;
 | 
					            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;
 | 
					package net.knarcraft.dropper.listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.dropper.Dropper;
 | 
					import net.knarcraft.dropper.Dropper;
 | 
				
			||||||
 | 
					import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaPlayerRegistry;
 | 
					import net.knarcraft.dropper.arena.DropperArenaPlayerRegistry;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaSession;
 | 
					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.Location;
 | 
				
			||||||
import org.bukkit.Material;
 | 
					import org.bukkit.Material;
 | 
				
			||||||
import org.bukkit.Tag;
 | 
					 | 
				
			||||||
import org.bukkit.block.Block;
 | 
					import org.bukkit.block.Block;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.bukkit.event.EventHandler;
 | 
					import org.bukkit.event.EventHandler;
 | 
				
			||||||
@@ -24,6 +24,17 @@ import java.util.Set;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class MoveListener implements Listener {
 | 
					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
 | 
					    @EventHandler
 | 
				
			||||||
    public void onPlayerMove(PlayerMoveEvent event) {
 | 
					    public void onPlayerMove(PlayerMoveEvent event) {
 | 
				
			||||||
        // Ignore if no actual movement is happening
 | 
					        // 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>
 | 
					     * @return <p>True if a special block has been hit</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private boolean checkForSpecialBlock(DropperArenaSession arenaSession, Location toLocation) {
 | 
					    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
 | 
					        double liquidDepth = configuration.getLiquidHitBoxDepth();
 | 
				
			||||||
           it is, the more accurate it will seem to the player, but the likelihood of not detecting the hit decreases */
 | 
					        double solidDepth = configuration.getSolidHitBoxDistance();
 | 
				
			||||||
        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;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Check if the player enters water
 | 
					        // Check if the player enters water
 | 
				
			||||||
        Material winBlockType = arenaSession.getArena().getWinBlockType();
 | 
					        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
 | 
					        // 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)) {
 | 
					        for (Block block : getBlocksBeneathLocation(toLocation, solidDepth)) {
 | 
				
			||||||
            Material blockType = block.getType();
 | 
					            Material blockType = block.getType();
 | 
				
			||||||
            if (!blockType.isAir() && blockType != Material.STRUCTURE_VOID && blockType != Material.WATER &&
 | 
					            if (!blockType.isAir() && !whitelisted.contains(blockType)) {
 | 
				
			||||||
                    blockType != Material.LAVA && !Tag.WALL_SIGNS.isTagged(blockType)) {
 | 
					 | 
				
			||||||
                arenaSession.triggerLoss();
 | 
					                arenaSession.triggerLoss();
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -118,11 +125,14 @@ public class MoveListener implements Listener {
 | 
				
			|||||||
     * @param session <p>The session to update the velocity for</p>
 | 
					     * @param session <p>The session to update the velocity for</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void updatePlayerVelocity(@NotNull DropperArenaSession session) {
 | 
					    private void updatePlayerVelocity(@NotNull DropperArenaSession session) {
 | 
				
			||||||
        Player player = session.getPlayer();
 | 
					        // Override the vertical velocity, if enabled
 | 
				
			||||||
        Vector playerVelocity = player.getVelocity();
 | 
					        if (configuration.overrideVerticalVelocity()) {
 | 
				
			||||||
        double arenaVelocity = session.getArena().getPlayerVerticalVelocity();
 | 
					            Player player = session.getPlayer();
 | 
				
			||||||
        Vector newVelocity = new Vector(playerVelocity.getX(), -arenaVelocity, playerVelocity.getZ());
 | 
					            Vector playerVelocity = player.getVelocity();
 | 
				
			||||||
        player.setVelocity(newVelocity);
 | 
					            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
 | 
					        // Toggle the direction of the player's flying, as necessary
 | 
				
			||||||
        toggleFlyInversion(session);
 | 
					        toggleFlyInversion(session);
 | 
				
			||||||
@@ -139,7 +149,7 @@ public class MoveListener implements Listener {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        Player player = session.getPlayer();
 | 
					        Player player = session.getPlayer();
 | 
				
			||||||
        float horizontalVelocity = session.getArena().getPlayerHorizontalVelocity();
 | 
					        float horizontalVelocity = session.getArena().getPlayerHorizontalVelocity();
 | 
				
			||||||
        float secondsBetweenToggle = 7;
 | 
					        float secondsBetweenToggle = configuration.getRandomlyInvertedTimer();
 | 
				
			||||||
        int seconds = Calendar.getInstance().get(Calendar.SECOND);
 | 
					        int seconds = Calendar.getInstance().get(Calendar.SECOND);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,15 +2,15 @@ package net.knarcraft.dropper.placeholder;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
 | 
					import me.clip.placeholderapi.expansion.PlaceholderExpansion;
 | 
				
			||||||
import net.knarcraft.dropper.Dropper;
 | 
					import net.knarcraft.dropper.Dropper;
 | 
				
			||||||
 | 
					import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
					import net.knarcraft.dropper.arena.DropperArena;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
					import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaHandler;
 | 
					import net.knarcraft.dropper.arena.DropperArenaHandler;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaRecordsRegistry;
 | 
					import net.knarcraft.dropper.arena.DropperArenaRecordsRegistry;
 | 
				
			||||||
import net.knarcraft.dropper.arena.record.ArenaRecord;
 | 
					import net.knarcraft.dropper.arena.record.ArenaRecord;
 | 
				
			||||||
import net.knarcraft.dropper.placeholder.parsing.InfoType;
 | 
					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.placeholder.parsing.SelectionType;
 | 
				
			||||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
					import net.knarcraft.dropper.property.RecordType;
 | 
				
			||||||
import net.knarcraft.dropper.util.DropperGroupRecordHelper;
 | 
					import net.knarcraft.dropper.util.DropperGroupRecordHelper;
 | 
				
			||||||
import org.bukkit.Bukkit;
 | 
					import org.bukkit.Bukkit;
 | 
				
			||||||
import org.bukkit.OfflinePlayer;
 | 
					import org.bukkit.OfflinePlayer;
 | 
				
			||||||
@@ -97,6 +97,14 @@ public class DropperRecordExpansion extends PlaceholderExpansion {
 | 
				
			|||||||
        return Objects.requireNonNullElse(info, parameters);
 | 
					        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
 | 
					     * Gets a piece of record information from a dropper arena group
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
package net.knarcraft.dropper.placeholder;
 | 
					package net.knarcraft.dropper.placeholder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
				
			||||||
import net.knarcraft.dropper.arena.record.ArenaRecord;
 | 
					import net.knarcraft.dropper.arena.record.ArenaRecord;
 | 
				
			||||||
import net.knarcraft.dropper.placeholder.parsing.RecordType;
 | 
					import net.knarcraft.dropper.property.RecordType;
 | 
				
			||||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
					 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Set;
 | 
					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.NotNull;
 | 
				
			||||||
import org.jetbrains.annotations.Nullable;
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
@@ -1,14 +1,14 @@
 | 
				
			|||||||
package net.knarcraft.dropper.util;
 | 
					package net.knarcraft.dropper.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.dropper.Dropper;
 | 
					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.DropperArena;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaData;
 | 
					import net.knarcraft.dropper.arena.DropperArenaData;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
					import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaRecordsRegistry;
 | 
					import net.knarcraft.dropper.arena.DropperArenaRecordsRegistry;
 | 
				
			||||||
import net.knarcraft.dropper.container.SerializableMaterial;
 | 
					import net.knarcraft.dropper.container.SerializableMaterial;
 | 
				
			||||||
import net.knarcraft.dropper.container.SerializableUUID;
 | 
					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.Location;
 | 
				
			||||||
import org.bukkit.Material;
 | 
					import org.bukkit.Material;
 | 
				
			||||||
import org.bukkit.configuration.ConfigurationSection;
 | 
					import org.bukkit.configuration.ConfigurationSection;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,12 @@
 | 
				
			|||||||
package net.knarcraft.dropper.util;
 | 
					package net.knarcraft.dropper.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.dropper.Dropper;
 | 
					import net.knarcraft.dropper.Dropper;
 | 
				
			||||||
 | 
					import net.knarcraft.dropper.arena.ArenaGameMode;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
					import net.knarcraft.dropper.arena.DropperArena;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
					import net.knarcraft.dropper.arena.DropperArenaGroup;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArenaHandler;
 | 
					import net.knarcraft.dropper.arena.DropperArenaHandler;
 | 
				
			||||||
import net.knarcraft.dropper.arena.record.ArenaRecord;
 | 
					import net.knarcraft.dropper.arena.record.ArenaRecord;
 | 
				
			||||||
import net.knarcraft.dropper.arena.record.SummableArenaRecord;
 | 
					import net.knarcraft.dropper.arena.record.SummableArenaRecord;
 | 
				
			||||||
import net.knarcraft.dropper.property.ArenaGameMode;
 | 
					 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
package net.knarcraft.dropper.util;
 | 
					package net.knarcraft.dropper.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.dropper.Dropper;
 | 
					import net.knarcraft.dropper.Dropper;
 | 
				
			||||||
 | 
					import net.knarcraft.dropper.arena.ArenaEditableProperty;
 | 
				
			||||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
					import net.knarcraft.dropper.arena.DropperArena;
 | 
				
			||||||
import net.knarcraft.dropper.property.ArenaEditableProperty;
 | 
					 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					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