199 lines
5.4 KiB
Java
199 lines
5.4 KiB
Java
package tc.oc.pgm.portals;
|
|
|
|
import java.util.Optional;
|
|
import javax.annotation.Nullable;
|
|
|
|
import org.bukkit.EntityLocation;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.util.Vector;
|
|
import tc.oc.pgm.PGM;
|
|
import tc.oc.pgm.regions.Region;
|
|
|
|
import static com.google.common.base.Preconditions.checkNotNull;
|
|
|
|
public interface PortalTransform extends InvertibleOperator<PortalTransform> {
|
|
|
|
Vector apply(Vector v);
|
|
|
|
Location apply(Location v);
|
|
|
|
default EntityLocation apply(EntityLocation v) {
|
|
return (EntityLocation) apply((Location) v);
|
|
}
|
|
|
|
static PortalTransform piecewise(DoubleTransform x, DoubleTransform y, DoubleTransform z, DoubleTransform yaw, DoubleTransform pitch) {
|
|
if(x instanceof DoubleTransform.Identity &&
|
|
y instanceof DoubleTransform.Identity &&
|
|
z instanceof DoubleTransform.Identity &&
|
|
yaw instanceof DoubleTransform.Identity &&
|
|
pitch instanceof DoubleTransform.Identity) {
|
|
return IDENTITY;
|
|
} else {
|
|
return new Piecewise(x, y, z, yaw, pitch);
|
|
}
|
|
}
|
|
|
|
class Piecewise implements PortalTransform {
|
|
private final DoubleTransform x, y, z, yaw, pitch;
|
|
|
|
private Piecewise(DoubleTransform x, DoubleTransform y, DoubleTransform z, DoubleTransform yaw, DoubleTransform pitch) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
this.yaw = yaw;
|
|
this.pitch = pitch;
|
|
}
|
|
|
|
private Vector mutate(Vector v) {
|
|
v.setX(x.applyAsDouble(v.getX()));
|
|
v.setY(y.applyAsDouble(v.getY()));
|
|
v.setZ(z.applyAsDouble(v.getZ()));
|
|
return v;
|
|
}
|
|
|
|
private Location mutate(Location v) {
|
|
mutate(v.position());
|
|
v.setYaw((float) yaw.applyAsDouble(v.getYaw()));
|
|
v.setPitch((float) pitch.applyAsDouble(v.getPitch()));
|
|
return v;
|
|
}
|
|
|
|
@Override
|
|
public Vector apply(Vector v) {
|
|
return mutate(new Vector(v));
|
|
}
|
|
|
|
@Override
|
|
public Location apply(Location v) {
|
|
return mutate(v.clone());
|
|
}
|
|
|
|
@Override
|
|
public boolean invertible() {
|
|
return x.invertible() &&
|
|
y.invertible() &&
|
|
z.invertible() &&
|
|
yaw.invertible() &&
|
|
pitch.invertible();
|
|
}
|
|
|
|
@Override
|
|
public PortalTransform inverse() {
|
|
return new Piecewise(x.inverse(),
|
|
y.inverse(),
|
|
z.inverse(),
|
|
yaw.inverse(),
|
|
pitch.inverse());
|
|
}
|
|
}
|
|
|
|
Identity IDENTITY = new Identity();
|
|
class Identity implements PortalTransform {
|
|
private Identity() {}
|
|
|
|
@Override
|
|
public Location apply(Location v) {
|
|
return v;
|
|
}
|
|
|
|
@Override
|
|
public Vector apply(Vector v) {
|
|
return v;
|
|
}
|
|
|
|
@Override
|
|
public boolean invertible() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public PortalTransform inverse() {
|
|
return this;
|
|
}
|
|
}
|
|
|
|
static PortalTransform regional(Optional<Region> from, Region to) {
|
|
return new Regional(from, to);
|
|
}
|
|
|
|
class Regional implements PortalTransform {
|
|
private final Optional<Region> from;
|
|
private final Region to;
|
|
|
|
private Regional(Optional<Region> from, Region to) {
|
|
this.from = checkNotNull(from);
|
|
this.to = checkNotNull(to);
|
|
}
|
|
|
|
@Override
|
|
public Vector apply(Vector v) {
|
|
v = new Vector(v);
|
|
v.copy(to.getRandom(PGM.getMatchManager().needCurrentMatch().getRandom()));
|
|
return v;
|
|
}
|
|
|
|
@Override
|
|
public Location apply(Location v) {
|
|
v = v.clone();
|
|
v.setPosition(to.getRandom(PGM.getMatchManager().needMatch(v.getWorld()).getRandom()));
|
|
return v;
|
|
}
|
|
|
|
@Override
|
|
public boolean invertible() {
|
|
return from != null;
|
|
}
|
|
|
|
@Override
|
|
public PortalTransform inverse() {
|
|
from.orElseThrow(() -> new IllegalStateException("not invertible"));
|
|
return new Regional(Optional.of(to), from.get());
|
|
}
|
|
}
|
|
|
|
static PortalTransform concatenate(PortalTransform first, PortalTransform last) {
|
|
if(first instanceof Identity) {
|
|
return last;
|
|
} else if (last instanceof Identity) {
|
|
return first;
|
|
} else {
|
|
return new Concatenate(first, last);
|
|
}
|
|
}
|
|
|
|
class Concatenate implements PortalTransform {
|
|
private final PortalTransform first, last;
|
|
|
|
private Concatenate(PortalTransform first, PortalTransform last) {
|
|
this.first = checkNotNull(first);
|
|
this.last = checkNotNull(last);
|
|
}
|
|
|
|
@Override
|
|
public Vector apply(Vector v) {
|
|
return last.apply(first.apply(v));
|
|
}
|
|
|
|
@Override
|
|
public Location apply(Location v) {
|
|
return last.apply(first.apply(v));
|
|
}
|
|
|
|
@Override
|
|
public EntityLocation apply(EntityLocation v) {
|
|
return last.apply(first.apply(v));
|
|
}
|
|
|
|
@Override
|
|
public boolean invertible() {
|
|
return first.invertible() && last.invertible();
|
|
}
|
|
|
|
@Override
|
|
public PortalTransform inverse() {
|
|
return new Concatenate(last, first);
|
|
}
|
|
}
|
|
}
|
|
|