4545import org .mvplugins .multiverse .core .world .WorldManager ;
4646import org .mvplugins .multiverse .core .world .entrycheck .EntryFeeResult ;
4747import org .mvplugins .multiverse .core .world .entrycheck .WorldEntryCheckerProvider ;
48+ import org .mvplugins .multiverse .core .world .helpers .DimensionFinder ;
4849import org .mvplugins .multiverse .core .world .helpers .EnforcementHandler ;
4950import org .spigotmc .event .player .PlayerSpawnLocationEvent ;
5051
@@ -64,6 +65,7 @@ final class MVPlayerListener implements CoreListener {
6465 private final Provider <MVCommandManager > commandManagerProvider ;
6566 private final DestinationsProvider destinationsProvider ;
6667 private final EnforcementHandler enforcementHandler ;
68+ private final DimensionFinder dimensionFinder ;
6769
6870 private final Map <String , String > playerWorld = new ConcurrentHashMap <>();
6971
@@ -79,7 +81,8 @@ final class MVPlayerListener implements CoreListener {
7981 WorldEntryCheckerProvider worldEntryCheckerProvider ,
8082 Provider <MVCommandManager > commandManagerProvider ,
8183 DestinationsProvider destinationsProvider ,
82- EnforcementHandler enforcementHandler ) {
84+ EnforcementHandler enforcementHandler ,
85+ DimensionFinder dimensionFinder ) {
8386 this .plugin = plugin ;
8487 this .config = config ;
8588 this .worldManagerProvider = worldManagerProvider ;
@@ -91,6 +94,7 @@ final class MVPlayerListener implements CoreListener {
9194 this .commandManagerProvider = commandManagerProvider ;
9295 this .destinationsProvider = destinationsProvider ;
9396 this .enforcementHandler = enforcementHandler ;
97+ this .dimensionFinder = dimensionFinder ;
9498 }
9599
96100 private WorldManager getWorldManager () {
@@ -122,25 +126,29 @@ public Map<String, String> getPlayerWorld() {
122126 @ EventHandler (priority = EventPriority .LOW )
123127 public void playerRespawn (PlayerRespawnEvent event ) {
124128 Player player = event .getPlayer ();
125- getWorldManager ().getLoadedWorld (player .getWorld ())
126- .onEmpty (() -> Logging .fine ("Player '%s' is in a world that is not managed by Multiverse." , player .getName ()))
127- .filter (mvWorld -> {
128- if (mvWorld .getBedRespawn () && event .isBedSpawn ()) {
129- Logging .fine ("Spawning %s at their bed." , player .getName ());
130- return false ;
131- }
132- if (mvWorld .getAnchorRespawn () && event .isAnchorSpawn ()) {
133- Logging .fine ("Spawning %s at their anchor." , player .getName ());
134- return false ;
135- }
136- if (!config .getDefaultRespawnWithinSameWorld () && mvWorld .getRespawnWorldName ().isEmpty ()) {
137- Logging .fine ("Not overriding respawn location for player '%s' as " +
138- "default-respawn-within-same-world is disabled and no respawn-world is set." , player .getName ());
139- return false ;
140- }
141- return true ;
129+ LoadedMultiverseWorld mvWorld = getWorldManager ().getLoadedWorld (player .getWorld ()).getOrNull ();
130+ if (mvWorld == null ) {
131+ Logging .finer ("Player '%s' died in a world that is not managed by Multiverse." , player .getName ());
132+ return ;
133+ }
134+
135+ if (mvWorld .getBedRespawn () && event .isBedSpawn ()) {
136+ Logging .fine ("Spawning %s at their bed." , player .getName ());
137+ return ;
138+ }
139+ if (mvWorld .getAnchorRespawn () && event .isAnchorSpawn ()) {
140+ Logging .fine ("Spawning %s at their anchor." , player .getName ());
141+ return ;
142+ }
143+
144+ getRespawnWorld (mvWorld )
145+ .onEmpty (() -> Logging .fine ("No respawn-world determined for world '%s'." , mvWorld .getName ()))
146+ .flatMap (respawnWorld -> {
147+ Logging .finer ("Using respawn-world '%s' for world '%s'." , respawnWorld .getName (), mvWorld .getName ());
148+ return getMostAccurateRespawnLocation (respawnWorld , event .getRespawnLocation ())
149+ .onEmpty (() -> Logging .finer ("No accurate respawn-location determined for world '%s'." ,
150+ mvWorld .getName ()));
142151 })
143- .flatMap (mvWorld -> getMostAccurateRespawnLocation (player , mvWorld , event .getRespawnLocation ()))
144152 .peek (newRespawnLocation -> {
145153 MVRespawnEvent respawnEvent = new MVRespawnEvent (newRespawnLocation , event .getPlayer ());
146154 this .server .getPluginManager ().callEvent (respawnEvent );
@@ -153,22 +161,34 @@ public void playerRespawn(PlayerRespawnEvent event) {
153161 });
154162 }
155163
156- private Option <Location > getMostAccurateRespawnLocation (Player player , MultiverseWorld mvWorld , Location defaultRespawnLocation ) {
157- return Option .of (mvWorld .getRespawnWorldName ().isEmpty ()
158- ? player .getWorld ()
159- : server .getWorld (mvWorld .getRespawnWorldName ()))
160- .onEmpty (() -> Logging .warning ("World '%s' has respawn-world property of '%s' that does not exist!" ,
161- player .getWorld ().getName (), mvWorld .getRespawnWorldName ()))
162- .flatMap (newRespawnWorld -> {
163- if (!config .getEnforceRespawnAtWorldSpawn () && newRespawnWorld .equals (defaultRespawnLocation .getWorld ())) {
164- Logging .fine ("Respawn location is within same world as respawn-world, not overriding." );
165- return Option .none ();
166- }
167- return getWorldManager ()
168- .getLoadedWorld (newRespawnWorld )
169- .map (newMVRespawnWorld -> (Location ) newMVRespawnWorld .getSpawnLocation ())
170- .orElse (() -> Option .of (newRespawnWorld .getSpawnLocation ()));
171- });
164+ private Option <LoadedMultiverseWorld > getRespawnWorld (LoadedMultiverseWorld mvWorld ) {
165+ if (!mvWorld .getRespawnWorldName ().isEmpty ()) {
166+ Logging .finer ("Using configured respawn-world for world '%s'." , mvWorld .getName ());
167+ return getWorldManager ().getLoadedWorld (mvWorld .getRespawnWorldName ())
168+ .onEmpty (() -> {
169+ Logging .warning ("World '%s' has respawn-world property of '%s' that does not exist!" ,
170+ mvWorld .getName (), mvWorld .getRespawnWorldName ());
171+ });
172+ } else if (!dimensionFinder .isOverworld (mvWorld ) && config .getDefaultRespawnInOverworld ()) {
173+ Logging .finer ("Defaulting to overworld for world '%s'." , mvWorld .getName ());
174+ return dimensionFinder .getOverworldWorld (mvWorld ).flatMap (getWorldManager ()::getLoadedWorld )
175+ .onEmpty (() -> {
176+ Logging .warning ("World '%s' has no overworld to teleport to!" ,
177+ mvWorld .getName ());
178+ });
179+ } else if (config .getDefaultRespawnWithinSameWorld ()) {
180+ Logging .finer ("Defaulting to same world for world '%s'." , mvWorld .getName ());
181+ return Option .of (mvWorld );
182+ }
183+ return Option .none ();
184+ }
185+
186+ private Option <Location > getMostAccurateRespawnLocation (LoadedMultiverseWorld mvWorld , Location defaultRespawnLocation ) {
187+ if (!config .getEnforceRespawnAtWorldSpawn () && Objects .equals (defaultRespawnLocation .getWorld (), mvWorld .getBukkitWorld ().getOrNull ())) {
188+ Logging .fine ("Respawn location is within same world as respawn-world, not overriding." );
189+ return Option .none ();
190+ }
191+ return Option .of (mvWorld .getSpawnLocation ());
172192 }
173193
174194 @ EventHandler
0 commit comments