Skip to content

Commit

Permalink
Attempt to estimate world in teleport when it's not specified. (#6611)
Browse files Browse the repository at this point in the history
  • Loading branch information
Moderocky authored Jul 1, 2024
1 parent 585e8d1 commit 2f629f1
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions src/main/java/ch/njol/skript/effects/EffTeleport.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package ch.njol.skript.effects;

import ch.njol.skript.Skript;
import ch.njol.skript.sections.EffSecSpawn;
import ch.njol.skript.sections.EffSecSpawn.SpawnEvent;
import ch.njol.skript.bukkitutil.EntityUtils;
import ch.njol.skript.doc.Description;
Expand All @@ -31,7 +30,6 @@
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.Trigger;
import ch.njol.skript.lang.TriggerItem;
import ch.njol.skript.lang.TriggerSection;
import ch.njol.skript.timings.SkriptTimings;
import ch.njol.skript.util.Direction;
import ch.njol.skript.variables.Variables;
Expand All @@ -53,7 +51,7 @@
"which may cause lag spikes or server crashes when using this effect to teleport entities to unloaded chunks."
})
@Examples({
"teleport the player to {homes.%player%}",
"teleport the player to {homes::%player%}",
"teleport the attacker to the victim"
})
@Since("1.0")
Expand Down Expand Up @@ -101,18 +99,25 @@ protected TriggerItem walk(Event e) {
Location loc = location.getSingle(e);
if (loc == null)
return next;
boolean unknownWorld = !loc.isWorldLoaded();

Entity[] entityArray = entities.getArray(e); // We have to fetch this before possible async execution to avoid async local variable access.
if (entityArray.length == 0)
return next;

if (!delayed) {
if (e instanceof PlayerRespawnEvent && entityArray.length == 1 && entityArray[0].equals(((PlayerRespawnEvent) e).getPlayer())) {
if (unknownWorld)
return next;
((PlayerRespawnEvent) e).setRespawnLocation(loc);
return next;
}

if (e instanceof PlayerMoveEvent && entityArray.length == 1 && entityArray[0].equals(((PlayerMoveEvent) e).getPlayer())) {
if (unknownWorld) { // we can approximate the world
loc = loc.clone();
loc.setWorld(((PlayerMoveEvent) e).getFrom().getWorld());
}
((PlayerMoveEvent) e).setTo(loc);
return next;
}
Expand All @@ -125,14 +130,27 @@ protected TriggerItem walk(Event e) {
return next;
}

if (unknownWorld) { // we can't fetch the chunk without a world
if (entityArray.length == 1) { // if there's 1 thing we can borrow its world
Entity entity = entityArray[0];
if (entity == null)
return next;
// assume it's a local teleport, use the first entity we find as a reference
loc = loc.clone();
loc.setWorld(entity.getWorld());
} else {
return next; // no entities = no chunk = nobody teleporting
}
}
final Location fixed = loc;
Delay.addDelayedEvent(e);
Object localVars = Variables.removeLocals(e);

// This will either fetch the chunk instantly if on Spigot or already loaded or fetch it async if on Paper.
PaperLib.getChunkAtAsync(loc).thenAccept(chunk -> {
// The following is now on the main thread
for (Entity entity : entityArray) {
EntityUtils.teleport(entity, loc);
EntityUtils.teleport(entity, fixed);
}

// Re-set local variables
Expand Down

0 comments on commit 2f629f1

Please sign in to comment.