Replace setPosition with trySetPosition (#1403)

Allows cancellation information to be fed back into the ascend/descend
algorithms.

(cherry picked from commit 71e104bcb187a5313e88dda5df79059c8ffbc1fe)
This commit is contained in:
Octavia Togami 2020-07-01 11:24:58 -04:00 committed by MattBDev
parent c82fec931a
commit 4c299bc0b8
8 changed files with 103 additions and 21 deletions

View File

@ -194,7 +194,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
}
@Override
public void setPosition(Vector3 pos, float pitch, float yaw) {
public void trySetPosition(Vector3 pos, float pitch, float yaw) {
org.bukkit.World world = player.getWorld();
if (pos instanceof com.sk89q.worldedit.util.Location) {
com.sk89q.worldedit.util.Location loc = (com.sk89q.worldedit.util.Location) pos;

View File

@ -36,6 +36,8 @@ import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.util.DeprecationUtil;
import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
@ -301,8 +303,40 @@ public interface Player extends Entity, Actor {
* @param pos where to move them
* @param pitch the pitch (up/down) of the player's view in degrees
* @param yaw the yaw (left/right) of the player's view in degrees
* @deprecated This method may fail without indication. Use
* {@link #trySetPosition(Vector3, float, float)} instead
*/
void setPosition(Vector3 pos, float pitch, float yaw);
@Deprecated
default void setPosition(Vector3 pos, float pitch, float yaw) {
trySetPosition(pos, pitch, yaw);
}
/**
* Attempt to move the player.
*
* <p>
* This action may fail, due to other mods cancelling the move.
* If so, this method will return {@code false}.
* </p>
*
* @param pos where to move them
* @param pitch the pitch (up/down) of the player's view in degrees
* @param yaw the yaw (left/right) of the player's view in degrees
* @return if the move was able to occur
* @apiNote This must be overridden by new subclasses. See {@link NonAbstractForCompatibility}
* for details
*/
@NonAbstractForCompatibility(
delegateName = "setPosition",
delegateParams = { Vector3.class, float.class, float.class }
)
default boolean trySetPosition(Vector3 pos, float pitch, float yaw) {
DeprecationUtil.checkDelegatingOverride(getClass());
setPosition(pos, pitch, yaw);
return true;
}
/**
* Sends a fake block to the client.

View File

@ -65,11 +65,14 @@ import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import java.io.File;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
/**
* An abstract implementation of both a {@link Actor} and a {@link Player}
* that is intended for implementations of WorldEdit to use to wrap
@ -179,8 +182,13 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
}
if (free == 2) {
boolean worked = true;
if (y - 1 != origY) {
setPosition(Vector3.at(x + 0.5, y - 2 + 1, z + 0.5));
worked = trySetPosition(Vector3.at(x + 0.5, y - 2 + 1, z + 0.5));
}
if (worked) {
return;
}
}
@ -199,8 +207,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
while (y >= 0) {
final BlockVector3 pos = BlockVector3.at(x, y, z);
final BlockState id = world.getBlock(pos);
if (id.getBlockType().getMaterial().isMovementBlocker()) {
setPosition(Vector3.at(x + 0.5, y + +BlockTypeUtil.centralTopLimit(id), z + 0.5));
if (id.getBlockType().getMaterial().isMovementBlocker()
&& trySetPosition(Vector3.at(x + 0.5, y + +BlockTypeUtil.centralTopLimit(id), z + 0.5))) {
return;
}
@ -213,6 +221,26 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
findFreePosition(getBlockLocation());
}
private boolean isBadSpaceForStanding(BlockVector3 location) {
BlockType type = getWorld().getBlock(location).getBlockType();
return type.getMaterial().isMovementBlocker() || type == BlockTypes.LAVA;
}
/**
* @param location where the player would be placed (not Y offset)
* @return if the player can stand at the location
*/
private boolean isLocationGoodForStanding(BlockVector3 location) {
if (isBadSpaceForStanding(location.add(0, 1, 0))) {
return false;
}
if (isBadSpaceForStanding(location)) {
return false;
}
return getWorld().getBlock(location.add(0, -1, 0)).getBlockType().getMaterial()
.isMovementBlocker();
}
@Override
public boolean ascendLevel() {
final Location pos = getBlockLocation();
@ -254,9 +282,9 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
double bottomLimit = BlockTypeUtil.centralBottomLimit(state);
double space = level + bottomLimit - freeStart;
if (space >= height) {
setPosition(Vector3.at(x + 0.5, freeStart, z + 0.5));
return true;
}
trySetPosition(Vector3.at(x + 0.5, freeStart, z + 0.5));
return true;
}
// Not enough room, reset the free position
if (bottomLimit != 1) {
freeStart = -1;
@ -312,9 +340,9 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
double freeStart = level + topLimit;
double space = freeEnd - freeStart;
if (space >= height) {
setPosition(Vector3.at(x + 0.5, freeStart, z + 0.5));
return true;
}
trySetPosition(Vector3.at(x + 0.5, freeStart, z + 0.5));
return true;
}
// Not enough room, reset the free position
if (topLimit != 0) {
freeEnd = -1;
@ -577,9 +605,9 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
}
@Override
public void setPosition(Vector3 pos) {
public boolean trySetPosition(Vector3 pos) {
final Location location = getLocation();
setPosition(pos, location.getPitch(), location.getYaw());
return trySetPosition(pos, location.getPitch(), location.getYaw());
}
@Override

View File

@ -54,9 +54,27 @@ public interface Locatable {
* Sets the position of this actor.
*
* @param pos where to move them
* @deprecated This method may fail without indication. Use {@link #trySetPosition(Vector3)}
* instead
*/
@Deprecated
default void setPosition(Vector3 pos) {
setLocation(new Location(getExtent(), pos));
trySetPosition(pos);
}
/**
* Attempts to set the position of this actor.
*
* <p>
* This action may fail, due to other mods cancelling the move.
* If so, this method will return {@code false}.
* </p>
*
* @param pos the position to set
* @return if the position was able to be set
*/
default boolean trySetPosition(Vector3 pos) {
return setLocation(new Location(getExtent(), pos));
}
/**

View File

@ -131,8 +131,8 @@ public class PlayerProxy extends AbstractPlayerActor {
}
@Override
public void setPosition(Vector3 pos, float pitch, float yaw) {
basePlayer.setPosition(pos, pitch, yaw);
public boolean trySetPosition(Vector3 pos, float pitch, float yaw) {
return basePlayer.trySetPosition(pos, pitch, yaw);
}
@Override

View File

@ -172,8 +172,9 @@ public class FabricPlayer extends AbstractPlayerActor {
}
@Override
public void setPosition(Vector3 pos, float pitch, float yaw) {
public boolean trySetPosition(Vector3 pos, float pitch, float yaw) {
this.player.networkHandler.requestTeleport(pos.getX(), pos.getY(), pos.getZ(), yaw, pitch);
return true;
}
@Override

View File

@ -168,8 +168,9 @@ public class ForgePlayer extends AbstractPlayerActor {
}
@Override
public void setPosition(Vector3 pos, float pitch, float yaw) {
public boolean trySetPosition(Vector3 pos, float pitch, float yaw) {
this.player.connection.setPlayerLocation(pos.getX(), pos.getY(), pos.getZ(), yaw, pitch);
return true;
}
@Override

View File

@ -165,12 +165,12 @@ public class SpongePlayer extends AbstractPlayerActor {
}
@Override
public void setPosition(Vector3 pos, float pitch, float yaw) {
public boolean trySetPosition(Vector3 pos, float pitch, float yaw) {
org.spongepowered.api.world.Location<World> loc = new org.spongepowered.api.world.Location<>(
this.player.getWorld(), pos.getX(), pos.getY(), pos.getZ()
this.player.getWorld(), pos.getX(), pos.getY(), pos.getZ()
);
this.player.setLocationAndRotation(loc, new Vector3d(pitch, yaw, 0));
return this.player.setLocationAndRotation(loc, new Vector3d(pitch, yaw, 0));
}
@Override