Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 35 additions & 8 deletions src/main/java/wolfcraft/randomspawn/PlayerListener.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
package wolfcraft.randomspawn;

import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.scheduler.BukkitRunnable;

public class PlayerListener implements Listener {
private final RandomSpawn plugin;
private final SpawnManager spawnManager;

private final Set<UUID> fallingSpawnedPlayers;

public PlayerListener(RandomSpawn plugin, SpawnManager spawnManager) {
this.plugin = plugin;
this.spawnManager = spawnManager;
this.fallingSpawnedPlayers = new HashSet<>();
}

@EventHandler(priority = EventPriority.HIGH)
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();

// Only teleport on first join
if (!player.hasPlayedBefore() && spawnManager.isFirstJoinEnabled()) {
// Delay the teleport to ensure the player is fully loaded
Expand All @@ -35,29 +41,50 @@ public void run() {
}.runTaskLater(plugin, 5L); // 5 ticks = 0.25 seconds
}
}

@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerRespawn(PlayerRespawnEvent event) {
// Don't override if player has a bed or anchor respawn
if (!event.isBedSpawn() && !event.isAnchorSpawn() && spawnManager.isRespawnOnDeathEnabled()) {
Player player = event.getPlayer();

// Only apply to worlds that are enabled
if (spawnManager.isWorldEnabled(player.getWorld().getName())) {
Location randomLocation = spawnManager.getRandomSpawnLocation(player);

if (randomLocation != null) {
event.setRespawnLocation(randomLocation);
setFallingPlayer(player);
}
}
}
}


@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();

if (spawnManager.isPreventFallDamageEnabled() && fallingSpawnedPlayers.contains(uuid) && player.isOnGround()) {
// The player has fall damage prevention enabled, is currently falling after a spawn,
// but has now touched ground, so we need to negate the fall damage and remove them from the falling players list
player.setFallDistance(0f);
fallingSpawnedPlayers.remove(uuid);
}
}

private void teleportToRandomSpawn(Player player) {
Location randomLocation = spawnManager.getRandomSpawnLocation(player);

if (randomLocation != null) {
player.teleport(randomLocation);
setFallingPlayer(player);
}
}

private void setFallingPlayer(Player player) {
if (spawnManager.isPreventFallDamageEnabled()) {
fallingSpawnedPlayers.add(player.getUniqueId());
}
}
}
24 changes: 12 additions & 12 deletions src/main/java/wolfcraft/randomspawn/RandomSpawn.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,27 @@ public class RandomSpawn extends JavaPlugin {
private FileConfiguration config;
private SpawnManager spawnManager;
private final String PREFIX = ChatColor.GOLD + "[RandomSpawn] " + ChatColor.RESET;

@Override
public void onEnable() {
// Save default config if it doesn't exist
saveDefaultConfig();
config = getConfig();

// Initialize spawn manager
spawnManager = new SpawnManager(this);

// Register event listeners
getServer().getPluginManager().registerEvents(new PlayerListener(this, spawnManager), this);

getLogger().info("RandomSpawn has been enabled!");
}

@Override
public void onDisable() {
getLogger().info("RandomSpawn has been disabled!");
}

@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
// Handle both command aliases: /rd and /random
Expand All @@ -44,36 +44,36 @@ public boolean onCommand(CommandSender sender, Command cmd, String label, String
showHelp(sender);
return true;
}

if (args[0].equalsIgnoreCase("reload")) {
// Check permission
if (!sender.hasPermission("randomspawn.reload")) {
sender.sendMessage(PREFIX + ChatColor.RED + "You don't have permission to use this command!");
return true;
}

// Reload config
reloadConfig();
config = getConfig();
spawnManager.reloadConfig();
sender.sendMessage(PREFIX + ChatColor.GREEN + "Configuration reloaded successfully!");
return true;
}

// Unknown argument, show help
showHelp(sender);
return true;
}

return false;
}

private void showHelp(CommandSender sender) {
sender.sendMessage(ChatColor.YELLOW + "=== RandomSpawn Help ===");
sender.sendMessage(ChatColor.GOLD + "/rd reload " + ChatColor.WHITE + "- Reload the configuration");
sender.sendMessage(ChatColor.GOLD + "/random reload " + ChatColor.WHITE + "- Reload the configuration");
}

public void reloadPluginConfig() {
reloadConfig();
config = getConfig();
Expand Down
18 changes: 13 additions & 5 deletions src/main/java/wolfcraft/randomspawn/SpawnManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class SpawnManager {
private int zMin;
private int zMax;
private boolean forceGroundSpawn;
private boolean allowMidairSpawn;
private boolean preventFallDamage;
private boolean enableFirstJoinSpawn;
private boolean enableRespawnOnDeath;
private int maxTries;
Expand All @@ -49,6 +51,8 @@ public void reloadConfig() {
zMin = config.getInt("spawn.z.min", -1000);
zMax = config.getInt("spawn.z.max", 1000);
forceGroundSpawn = config.getBoolean("spawn.force-ground-spawn", true);
allowMidairSpawn = config.getBoolean("spawn.allow-midair-spawn", false);
preventFallDamage = config.getBoolean("spawn.prevent-fall-damage", false);
enableFirstJoinSpawn = config.getBoolean("events.first-join", true);
enableRespawnOnDeath = config.getBoolean("events.respawn-on-death", true);
maxTries = config.getInt("spawn.max-tries", 50);
Expand All @@ -73,6 +77,10 @@ public boolean isRespawnOnDeathEnabled() {
return enableRespawnOnDeath;
}

public boolean isPreventFallDamageEnabled() {
return preventFallDamage;
}

public boolean isWorldEnabled(String worldName) {
return enabledWorlds.contains(worldName);
}
Expand Down Expand Up @@ -134,8 +142,8 @@ private Location findSafeYPosition(Location location) {
Block blockAbove = world.getBlockAt(x, y + 1, z);
Block blockTwoAbove = world.getBlockAt(x, y + 2, z);

if (!block.getType().isAir() &&
blockAbove.getType().isAir() &&
if (!block.getType().isAir() &&
blockAbove.getType().isAir() &&
blockTwoAbove.getType().isAir() &&
!block.isLiquid() &&
!isFatalBlock(block.getType().toString())) {
Expand All @@ -157,9 +165,9 @@ private boolean isSafeLocation(Location location) {
Block blockAbove = location.clone().add(0, 1, 0).getBlock();

if (!forceGroundSpawn) {
return block.getType().isAir() &&
return block.getType().isAir() &&
blockAbove.getType().isAir() &&
!blockBelow.getType().isAir() &&
(!blockBelow.getType().isAir() || allowMidairSpawn) &&
!blockBelow.isLiquid() &&
!isFatalBlock(blockBelow.getType().toString());
}
Expand Down Expand Up @@ -188,7 +196,7 @@ private void cacheLocation(String worldName, Location location) {
locations.remove(locArray[random.nextInt(locArray.length)]);
}
}

private int randomBetween(int min, int max) {
if (min > max) {
int temp = min;
Expand Down
8 changes: 7 additions & 1 deletion src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ spawn:
# If true, players will always spawn on the surface
# This will disable the Y coordinate range setting above
force-ground-spawn: true

# If true, players can spawn in midair
# This might result in fall damage if prevent-fall-damage is false
allow-midair-spawn: false

# If true, prevents fall damage from the player's first landing after being spawned
prevent-fall-damage: false

# Maximum number of attempts to find a safe spawn location
max-tries: 50
Expand Down Expand Up @@ -56,4 +63,3 @@ messages:
prefix: "&6[RandomSpawn] &r"
reload: "&aConfiguration reloaded successfully!"
no-permission: "&cYou don't have permission to use this command!"