mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2025-01-25 09:41:23 +01:00
Implement proper spawn location
This commit is contained in:
parent
dc75e87223
commit
f524c5bdde
@ -26,10 +26,13 @@ import com.onarandombox.MultiverseCore.utils.TestingMode;
|
||||
import com.onarandombox.MultiverseCore.utils.metrics.MetricsConfigurator;
|
||||
import com.onarandombox.MultiverseCore.world.WorldProperties;
|
||||
import com.onarandombox.MultiverseCore.worldnew.WorldManager;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.NullLocation;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.SpawnLocation;
|
||||
import io.vavr.control.Try;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Provider;
|
||||
import me.main__.util.SerializationConfig.SerializationConfig;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
@ -102,6 +105,8 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
initializeDependencyInjection();
|
||||
ConfigurationSerialization.registerClass(NullLocation.class);
|
||||
ConfigurationSerialization.registerClass(SpawnLocation.class);
|
||||
|
||||
// Load our configs first as we need them for everything else.
|
||||
var config = configProvider.get();
|
||||
|
@ -73,7 +73,7 @@ public class CreateCommand extends MultiverseCommand {
|
||||
.add(CommandValueFlag.enumBuilder("--world-type", WorldType.class)
|
||||
.addAlias("-t")
|
||||
.build())
|
||||
.add(CommandFlag.builder("--adjust-spawn")
|
||||
.add(CommandFlag.builder("--no-adjust-spawn")
|
||||
.addAlias("-n")
|
||||
.build())
|
||||
.add(CommandFlag.builder("--no-structures")
|
||||
@ -109,7 +109,7 @@ public class CreateCommand extends MultiverseCommand {
|
||||
issuer.sendInfo(MVCorei18n.CREATE_PROPERTIES_ENVIRONMENT, "{environment}", environment.name());
|
||||
issuer.sendInfo(MVCorei18n.CREATE_PROPERTIES_SEED, "{seed}", parsedFlags.flagValue("--seed", "RANDOM", String.class));
|
||||
issuer.sendInfo(MVCorei18n.CREATE_PROPERTIES_WORLDTYPE, "{worldType}", parsedFlags.flagValue("--world-type", WorldType.NORMAL, WorldType.class).name());
|
||||
issuer.sendInfo(MVCorei18n.CREATE_PROPERTIES_ADJUSTSPAWN, "{adjustSpawn}", String.valueOf(parsedFlags.hasFlag("--adjust-spawn")));
|
||||
issuer.sendInfo(MVCorei18n.CREATE_PROPERTIES_ADJUSTSPAWN, "{adjustSpawn}", String.valueOf(!parsedFlags.hasFlag("--no-adjust-spawn")));
|
||||
issuer.sendInfo(MVCorei18n.CREATE_PROPERTIES_GENERATOR, "{generator}", parsedFlags.flagValue("--generator", "", String.class));
|
||||
issuer.sendInfo(MVCorei18n.CREATE_PROPERTIES_STRUCTURES, "{structures}", String.valueOf(!parsedFlags.hasFlag("--no-structures")));
|
||||
|
||||
@ -119,7 +119,7 @@ public class CreateCommand extends MultiverseCommand {
|
||||
.environment(environment)
|
||||
.seed(parsedFlags.flagValue("--seed", String.class))
|
||||
.worldType(parsedFlags.flagValue("--world-type", WorldType.NORMAL, WorldType.class))
|
||||
.useSpawnAdjust(parsedFlags.hasFlag("--adjust-spawn"))
|
||||
.useSpawnAdjust(!parsedFlags.hasFlag("--no-adjust-spawn"))
|
||||
.generator(parsedFlags.flagValue("--generator", "", String.class))
|
||||
.generateStructures(!parsedFlags.hasFlag("--no-structures"))
|
||||
).onSuccess((success) -> {
|
||||
|
@ -24,7 +24,7 @@ import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
|
||||
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.AllowedPortalType;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.EnglishChatColor;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.SpawnLocation;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.SpawnLocation;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.SpawnSettings;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.WorldPropertyValidator;
|
||||
import me.main__.util.SerializationConfig.ChangeDeniedException;
|
||||
|
@ -9,7 +9,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.onarandombox.MultiverseCore.world.configuration.EntryFee;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.SpawnLocation;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.SpawnLocation;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.SpawnSettings;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.WorldPropertyValidator;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.AllowedPortalType;
|
||||
|
@ -1,25 +1,45 @@
|
||||
package com.onarandombox.MultiverseCore.worldnew;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.api.BlockSafety;
|
||||
import com.onarandombox.MultiverseCore.api.LocationManipulation;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.NullLocation;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.SpawnLocation;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.WorldConfig;
|
||||
import io.vavr.control.Option;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class MVWorld extends OfflineWorld {
|
||||
private static final int SPAWN_LOCATION_SEARCH_TOLERANCE = 16;
|
||||
private static final int SPAWN_LOCATION_SEARCH_RADIUS = 16;
|
||||
|
||||
private final UUID worldUid;
|
||||
|
||||
private final BlockSafety blockSafety;
|
||||
private final SafeTTeleporter safeTTeleporter;
|
||||
private final LocationManipulation locationManipulation;
|
||||
|
||||
MVWorld(
|
||||
@NotNull World world,
|
||||
@NotNull WorldConfig worldConfig
|
||||
@NotNull WorldConfig worldConfig,
|
||||
@NotNull BlockSafety blockSafety,
|
||||
@NotNull SafeTTeleporter safeTTeleporter,
|
||||
@NotNull LocationManipulation locationManipulation
|
||||
) {
|
||||
super(world.getName(), worldConfig);
|
||||
this.worldUid = world.getUID();
|
||||
this.blockSafety = blockSafety;
|
||||
this.safeTTeleporter = safeTTeleporter;
|
||||
this.locationManipulation = locationManipulation;
|
||||
|
||||
setupWorldConfig(world);
|
||||
setupSpawnLocation(world);
|
||||
}
|
||||
|
||||
private void setupWorldConfig(World world) {
|
||||
@ -29,6 +49,56 @@ public class MVWorld extends OfflineWorld {
|
||||
worldConfig.setSeed(world.getSeed());
|
||||
}
|
||||
|
||||
private void setupSpawnLocation(World world) {
|
||||
Location spawnLocation = worldConfig.getSpawnLocation();
|
||||
if (spawnLocation == null || spawnLocation instanceof NullLocation) {
|
||||
SpawnLocation newLocation = new SpawnLocation(readSpawnFromWorld(world));
|
||||
worldConfig.setSpawnLocation(newLocation);
|
||||
world.setSpawnLocation(newLocation.getBlockX(), newLocation.getBlockY(), newLocation.getBlockZ());
|
||||
}
|
||||
worldConfig.getSpawnLocation().setWorld(world);
|
||||
}
|
||||
|
||||
private Location readSpawnFromWorld(World world) { // TODO: Refactor... this is copy pasted and bad
|
||||
Location location = world.getSpawnLocation();
|
||||
// Set the worldspawn to our configspawn
|
||||
// Verify that location was safe
|
||||
if (!blockSafety.playerCanSpawnHereSafely(location)) {
|
||||
if (!this.getAdjustSpawn()) {
|
||||
Logging.fine("Spawn location from world.dat file was unsafe!!");
|
||||
Logging.fine("NOT adjusting spawn for '" + this.getAlias() + "' because you told me not to.");
|
||||
Logging.fine("To turn on spawn adjustment for this world simply type:");
|
||||
Logging.fine("/mvm set adjustspawn true " + this.getAlias());
|
||||
return location;
|
||||
}
|
||||
// If it's not, find a better one.
|
||||
Logging.warning("Spawn location from world.dat file was unsafe. Adjusting...");
|
||||
Logging.warning("Original Location: " + locationManipulation.strCoordsRaw(location));
|
||||
Location newSpawn = safeTTeleporter.getSafeLocation(location,
|
||||
SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
|
||||
// I think we could also do this, as I think this is what Notch does.
|
||||
// Not sure how it will work in the nether...
|
||||
//Location newSpawn = this.spawnLocation.getWorld().getHighestBlockAt(this.spawnLocation).getLocation();
|
||||
if (newSpawn != null) {
|
||||
Logging.info("New Spawn for '%s' is located at: %s",
|
||||
this.getName(), locationManipulation.locationToString(newSpawn));
|
||||
return newSpawn;
|
||||
} else {
|
||||
// If it's a standard end world, let's check in a better place:
|
||||
Location newerSpawn;
|
||||
newerSpawn = blockSafety.getTopBlock(new Location(world, 0, 0, 0));
|
||||
if (newerSpawn != null) {
|
||||
Logging.info("New Spawn for '%s' is located at: %s",
|
||||
this.getName(), locationManipulation.locationToString(newerSpawn));
|
||||
return newerSpawn;
|
||||
} else {
|
||||
Logging.severe("Safe spawn NOT found!!!");
|
||||
}
|
||||
}
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
public Option<World> getBukkitWorld() {
|
||||
return Option.of(Bukkit.getWorld(worldUid));
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package com.onarandombox.MultiverseCore.worldnew;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.google.common.base.Strings;
|
||||
import com.onarandombox.MultiverseCore.api.BlockSafety;
|
||||
import com.onarandombox.MultiverseCore.api.LocationManipulation;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.utils.file.FileUtils;
|
||||
import com.onarandombox.MultiverseCore.utils.result.Result;
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.WorldConfig;
|
||||
@ -34,13 +37,25 @@ public class WorldManager {
|
||||
private final Map<String, MVWorld> worldsMap;
|
||||
private final WorldsConfigManager worldsConfigManager;
|
||||
private final WorldNameChecker worldNameChecker;
|
||||
private final BlockSafety blockSafety;
|
||||
private final SafeTTeleporter safeTTeleporter;
|
||||
private final LocationManipulation locationManipulation;
|
||||
|
||||
@Inject
|
||||
WorldManager(@NotNull WorldsConfigManager worldsConfigManager, @NotNull WorldNameChecker worldNameChecker) {
|
||||
WorldManager(
|
||||
@NotNull WorldsConfigManager worldsConfigManager,
|
||||
@NotNull WorldNameChecker worldNameChecker,
|
||||
@NotNull BlockSafety blockSafety,
|
||||
@NotNull SafeTTeleporter safeTTeleporter,
|
||||
@NotNull LocationManipulation locationManipulation
|
||||
) {
|
||||
this.offlineWorldsMap = new HashMap<>();
|
||||
this.worldsMap = new HashMap<>();
|
||||
this.worldsConfigManager = worldsConfigManager;
|
||||
this.worldNameChecker = worldNameChecker;
|
||||
this.blockSafety = blockSafety;
|
||||
this.safeTTeleporter = safeTTeleporter;
|
||||
this.locationManipulation = locationManipulation;
|
||||
}
|
||||
|
||||
public void initAllWorlds() {
|
||||
@ -166,7 +181,7 @@ public class WorldManager {
|
||||
OfflineWorld offlineWorld = new OfflineWorld(world.getName(), worldConfig);
|
||||
offlineWorldsMap.put(offlineWorld.getName(), offlineWorld);
|
||||
|
||||
MVWorld mvWorld = new MVWorld(world, worldConfig);
|
||||
MVWorld mvWorld = new MVWorld(world, worldConfig, blockSafety, safeTTeleporter, locationManipulation);
|
||||
worldsMap.put(mvWorld.getName(), mvWorld);
|
||||
return mvWorld;
|
||||
}
|
||||
@ -197,7 +212,7 @@ public class WorldManager {
|
||||
|
||||
// Our multiverse world
|
||||
WorldConfig worldConfig = worldsConfigManager.getWorldConfig(offlineWorld.getName());
|
||||
MVWorld mvWorld = new MVWorld(world, worldConfig);
|
||||
MVWorld mvWorld = new MVWorld(world, worldConfig, blockSafety, safeTTeleporter, locationManipulation);
|
||||
worldsMap.put(mvWorld.getName(), mvWorld);
|
||||
|
||||
saveWorldsConfig();
|
||||
|
@ -0,0 +1,53 @@
|
||||
package com.onarandombox.MultiverseCore.worldnew.config;
|
||||
|
||||
import com.onarandombox.MultiverseCore.world.SimpleMVWorld;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.serialization.SerializableAs;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Null-location.
|
||||
*/
|
||||
@SerializableAs("MVNullLocation (It's a bug if you see this in your config file)")
|
||||
public final class NullLocation extends SpawnLocation {
|
||||
public NullLocation() {
|
||||
super(0, -1, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location clone() {
|
||||
throw new UnsupportedOperationException();
|
||||
};
|
||||
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Let Bukkit be able to deserialize this.
|
||||
* @param args The map.
|
||||
* @return The deserialized object.
|
||||
*/
|
||||
public static SimpleMVWorld.NullLocation deserialize(Map<String, Object> args) {
|
||||
return new SimpleMVWorld.NullLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector toVector() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return -1;
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Location{null}";
|
||||
};
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.onarandombox.MultiverseCore.world.configuration;
|
||||
package com.onarandombox.MultiverseCore.worldnew.config;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
@ -154,6 +154,7 @@ public class WorldConfigNodes {
|
||||
.build());
|
||||
|
||||
public final ConfigNode<Location> SPAWN_LOCATION = node(ConfigNode.builder("spawn-location", Location.class)
|
||||
.defaultValue(new NullLocation())
|
||||
.name("spawn-location")
|
||||
.build());
|
||||
|
||||
|
@ -7,25 +7,15 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.SpawnLocation;
|
||||
import com.onarandombox.MultiverseCore.utils.MockWorldFactory;
|
||||
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
|
||||
import com.onarandombox.MultiverseCore.world.WorldProperties;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Difficulty;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldType;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
@ -47,9 +37,7 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.mvplugins.multiverse.core.world
|
||||
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.SpawnLocation
|
||||
import com.onarandombox.MultiverseCore.worldnew.config.WorldsConfigManager
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
@ -47,6 +48,7 @@ class WorldConfigMangerTest : TestWithMockBukkit() {
|
||||
val worldConfig = worldConfigManager.getWorldConfig("world")
|
||||
worldConfig.setProperty("adjust-spawn", true)
|
||||
worldConfig.setProperty("alias", "newalias")
|
||||
worldConfig.setProperty("spawn-location", SpawnLocation(-64.0, 64.0, 48.0))
|
||||
worldConfigManager.save()
|
||||
compareConfigFile("worlds2.yml", "/properties_worlds.yml")
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ world:
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVNullLocation (It's a bug if you see this in your config file)
|
||||
spawning:
|
||||
animals:
|
||||
spawn: true
|
||||
@ -56,6 +58,8 @@ world_nether:
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVNullLocation (It's a bug if you see this in your config file)
|
||||
spawning:
|
||||
animals:
|
||||
spawn: true
|
||||
|
@ -22,6 +22,8 @@ world_nether:
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVNullLocation (It's a bug if you see this in your config file)
|
||||
spawning:
|
||||
animals:
|
||||
spawn: true
|
||||
|
@ -22,6 +22,8 @@ world:
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVNullLocation (It's a bug if you see this in your config file)
|
||||
spawning:
|
||||
animals:
|
||||
spawn: true
|
||||
@ -56,6 +58,8 @@ world_nether:
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVNullLocation (It's a bug if you see this in your config file)
|
||||
spawning:
|
||||
animals:
|
||||
spawn: true
|
||||
@ -90,6 +94,8 @@ newworld:
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVNullLocation (It's a bug if you see this in your config file)
|
||||
spawning:
|
||||
animals:
|
||||
spawn: true
|
||||
|
@ -22,6 +22,13 @@ world:
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
animals:
|
||||
spawn: true
|
||||
@ -56,6 +63,8 @@ world_nether:
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVNullLocation (It's a bug if you see this in your config file)
|
||||
spawning:
|
||||
animals:
|
||||
spawn: true
|
||||
|
Loading…
Reference in New Issue
Block a user