mirror of
https://github.com/SunNetservers/MiniGames.git
synced 2024-12-05 00:43:15 +01:00
Implements several configuration options #15
This commit is contained in:
parent
3bbf41206c
commit
50978d8baf
@ -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
|
Loading…
Reference in New Issue
Block a user