Skip to content

Commit ed5a13b

Browse files
committed
Implement default-respawn-to-world-spawn config option and refactor respawn event
1 parent 971a159 commit ed5a13b

File tree

5 files changed

+69
-40
lines changed

5 files changed

+69
-40
lines changed

src/main/java/org/mvplugins/multiverse/core/api/MVConfig.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@ public interface MVConfig {
162162
*/
163163
String getJoinDestination();
164164

165+
/**
166+
* Sets defaultRespawnToWorldSpawn.
167+
* @param defaultRespawnToWorldSpawn The new value
168+
*/
169+
void setDefaultRespawnToWorldSpawn(boolean defaultRespawnToWorldSpawn);
170+
171+
/**
172+
* Gets defaultRespawnToWorldSpawn
173+
* @return defaultRespawnToWorldSpawn
174+
*/
175+
boolean getDefaultRespawnToWorldSpawn();
176+
165177
/**
166178
* Sets whether or not to let Bukkit determine portal search radius on its own or if Multiverse should give input.
167179
*

src/main/java/org/mvplugins/multiverse/core/config/MVCoreConfig.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,16 @@ public String getJoinDestination() {
244244
return configHandle.get(configNodes.JOIN_DESTINATION);
245245
}
246246

247+
@Override
248+
public void setDefaultRespawnToWorldSpawn(boolean defaultRespawnToWorldSpawn) {
249+
configHandle.set(configNodes.DEFAULT_RESPAWN_TO_WORLD_SPAWN, defaultRespawnToWorldSpawn);
250+
}
251+
252+
@Override
253+
public boolean getDefaultRespawnToWorldSpawn() {
254+
return configHandle.get(configNodes.DEFAULT_RESPAWN_TO_WORLD_SPAWN);
255+
}
256+
247257
@Override
248258
public void setUseCustomPortalSearch(boolean useDefaultPortalSearch) {
249259
configHandle.set(configNodes.USE_CUSTOM_PORTAL_SEARCH, useDefaultPortalSearch);

src/main/java/org/mvplugins/multiverse/core/config/MVCoreConfigNodes.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ private <N extends Node> N node(N node) {
184184
.name("join-destination")
185185
.build());
186186

187+
final ConfigNode<Boolean> DEFAULT_RESPAWN_TO_WORLD_SPAWN = node(ConfigNode.builder("spawn.default-respawn-to-world-spawn", Boolean.class)
188+
.comment("")
189+
.comment("By default when `respawn-world` is not set, players will respawn at the world's spawn location that they died in.")
190+
.comment("If you want another plugin to handle respawn, or use vanilla /spawnpoint, set this to false.")
191+
.comment("This only applies if the `respawn-world` property is not set for the world that the player died in.")
192+
.comment("You can set `respawn-world` property by running the command: `/mv modify <worldname> set respawn-world <worldname>`")
193+
.defaultValue(true)
194+
.name("default-respawn-to-world-spawn")
195+
.build());
196+
187197
private final ConfigHeaderNode PORTAL_HEADER = node(ConfigHeaderNode.builder("portal")
188198
.comment("")
189199
.comment("")

src/main/java/org/mvplugins/multiverse/core/listeners/MVPlayerListener.java

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.vavr.control.Option;
1515
import jakarta.inject.Inject;
1616
import jakarta.inject.Provider;
17+
import org.bukkit.Bukkit;
1718
import org.bukkit.Location;
1819
import org.bukkit.Material;
1920
import org.bukkit.Server;
@@ -119,48 +120,43 @@ public Map<String, String> getPlayerWorld() {
119120
*/
120121
@EventHandler(priority = EventPriority.LOW)
121122
public void playerRespawn(PlayerRespawnEvent event) {
122-
World world = event.getPlayer().getWorld();
123-
LoadedMultiverseWorld mvWorld = getWorldManager().getLoadedWorld(world.getName()).getOrNull();
124-
// If it's not a World MV manages we stop.
125-
if (mvWorld == null) {
126-
return;
127-
}
128-
129-
if (mvWorld.getBedRespawn() && event.isBedSpawn()) {
130-
Logging.fine("Spawning %s at their bed.", event.getPlayer().getName());
131-
return;
132-
}
133-
134-
if (mvWorld.getAnchorRespawn() && event.isAnchorSpawn()) {
135-
Logging.fine("Spawning %s at their anchor.", event.getPlayer().getName());
136-
return;
137-
}
138-
139-
// Get the instance of the World the player should respawn at.
140-
LoadedMultiverseWorld respawnWorld = null;
141-
if (getWorldManager().isLoadedWorld(mvWorld.getRespawnWorld())) {
142-
respawnWorld = getWorldManager().getLoadedWorld(mvWorld.getRespawnWorld()).getOrNull();
143-
}
144-
145-
// If it's null then it either means the World doesn't exist or the value is blank, so we don't handle it.
146-
// NOW: We'll always handle it to get more accurate spawns
147-
if (respawnWorld != null) {
148-
world = respawnWorld.getBukkitWorld().getOrNull();
149-
}
150-
// World has been set to the appropriate world
151-
Location respawnLocation = getMostAccurateRespawnLocation(world);
152-
153-
MVRespawnEvent respawnEvent = new MVRespawnEvent(respawnLocation, event.getPlayer(), "compatability");
154-
this.server.getPluginManager().callEvent(respawnEvent);
155-
event.setRespawnLocation(respawnEvent.getPlayersRespawnLocation());
123+
Player player = event.getPlayer();
124+
getWorldManager().getLoadedWorld(player.getWorld())
125+
.onEmpty(() -> Logging.fine("Player '%s' is in a world that is not managed by Multiverse.", player.getName()))
126+
.filter(mvWorld -> {
127+
if (mvWorld.getBedRespawn() && event.isBedSpawn()) {
128+
Logging.fine("Spawning %s at their bed.", player.getName());
129+
return false;
130+
}
131+
if (mvWorld.getAnchorRespawn() && event.isAnchorSpawn()) {
132+
Logging.fine("Spawning %s at their anchor.", player.getName());
133+
return false;
134+
}
135+
if (!config.getDefaultRespawnToWorldSpawn() && mvWorld.getRespawnWorldName().isBlank()) {
136+
Logging.fine("Not overriding respawn location for player '%s' as " +
137+
"default-respawn-to-world-spawn is disabled and no respawn-world is set.", player.getName());
138+
return false;
139+
}
140+
return true;
141+
})
142+
.flatMap(mvWorld -> getMostAccurateRespawnLocation (player, mvWorld))
143+
.peek(newRespawnLocation -> {
144+
MVRespawnEvent respawnEvent = new MVRespawnEvent(newRespawnLocation, event.getPlayer(), "compatability");
145+
this.server.getPluginManager().callEvent(respawnEvent);
146+
event.setRespawnLocation(respawnEvent.getPlayersRespawnLocation());
147+
});
156148
}
157149

158-
private Location getMostAccurateRespawnLocation(World w) {
159-
LoadedMultiverseWorld mvw = getWorldManager().getLoadedWorld(w.getName()).getOrNull();
160-
if (mvw != null) {
161-
return mvw.getSpawnLocation();
162-
}
163-
return w.getSpawnLocation();
150+
private Option<Location> getMostAccurateRespawnLocation(Player player, LoadedMultiverseWorld mvWorld) {
151+
return Option.of(mvWorld.getRespawnWorldName().isBlank()
152+
? player.getWorld()
153+
: server.getWorld(mvWorld.getRespawnWorldName()))
154+
.onEmpty(() -> Logging.warning("World '%s' has respawn-world property of '%s' that does not exist!",
155+
player.getWorld().getName(), mvWorld.getRespawnWorldName()))
156+
.map(newRespawnWorld -> getWorldManager()
157+
.getLoadedWorld(newRespawnWorld)
158+
.map(newMVRespawnWorld -> (Location) newMVRespawnWorld.getSpawnLocation())
159+
.getOrElse(newRespawnWorld::getSpawnLocation));
164160
}
165161

166162
@EventHandler

src/test/resources/fresh_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ spawn:
1515
first-spawn-location: ''
1616
enable-join-destination: false
1717
join-destination: ''
18+
default-respawn-to-world-spawn: true
1819

1920
portal:
2021
use-custom-portal-search: false

0 commit comments

Comments
 (0)