Iris/src/main/java/com/volmit/iris/object/IrisObjectRotation.java
Daniel Mills aa7a1ddd4e Bugfixes
2020-10-28 02:10:59 -04:00

325 lines
5.7 KiB
Java

package com.volmit.iris.object;
import java.util.List;
import com.volmit.iris.util.M;
import org.bukkit.Axis;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.*;
import org.bukkit.util.BlockVector;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.KList;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Configures rotation for iris")
@Data
public class IrisObjectRotation
{
@DontObfuscate
@Desc("If this rotator is enabled or not")
private boolean enabled = true;
@DontObfuscate
@Desc("The x axis rotation")
private IrisAxisRotationClamp xAxis = new IrisAxisRotationClamp();
@DontObfuscate
@Desc("The y axis rotation")
private IrisAxisRotationClamp yAxis = new IrisAxisRotationClamp(true, 0, 0, 90);
@DontObfuscate
@Desc("The z axis rotation")
private IrisAxisRotationClamp zAxis = new IrisAxisRotationClamp();
public double getYRotation(int spin)
{
return getRotation(spin, yAxis);
}
public double getXRotation(int spin)
{
return getRotation(spin, xAxis);
}
public double getZRotation(int spin)
{
return getRotation(spin, zAxis);
}
public double getRotation(int spin, IrisAxisRotationClamp clamp)
{
if(!enabled)
{
return 0;
}
if(!clamp.isEnabled())
{
return 0;
}
return clamp.getRadians(spin);
}
public BlockFace getFace(BlockVector v)
{
int x = (int) Math.round(v.getX());
int y = (int) Math.round(v.getY());
int z = (int) Math.round(v.getZ());
if(x == 0 && z == -1)
{
return BlockFace.NORTH;
}
if(x == 0 && z == 1)
{
return BlockFace.SOUTH;
}
if(x == 1 && z == 0)
{
return BlockFace.EAST;
}
if(x == -1 && z == 0)
{
return BlockFace.WEST;
}
if(y > 0)
{
return BlockFace.UP;
}
if(y < 0)
{
return BlockFace.DOWN;
}
return BlockFace.SOUTH;
}
public BlockFace faceForAxis(Axis axis)
{
switch(axis)
{
case X:
return BlockFace.EAST;
case Y:
return BlockFace.UP;
case Z:
return BlockFace.NORTH;
}
return BlockFace.NORTH;
}
public Axis axisFor(BlockFace f)
{
switch(f)
{
case NORTH:
case SOUTH:
return Axis.Z;
case EAST:
case WEST:
return Axis.X;
case UP:
case DOWN:
return Axis.Y;
}
return Axis.X;
}
public Axis axisFor2D(BlockFace f)
{
switch(f)
{
case NORTH:
case SOUTH:
return Axis.Z;
case EAST:
case WEST:
case UP:
case DOWN:
return Axis.X;
}
return Axis.X;
}
public BlockData rotate(BlockData dd, int spinxx, int spinyy, int spinzz)
{
BlockData d = dd;
int spinx = (int) (90D * (Math.ceil(Math.abs((spinxx % 360D) / 90D))));
int spiny = (int) (90D * (Math.ceil(Math.abs((spinyy % 360D) / 90D))));
int spinz = (int) (90D * (Math.ceil(Math.abs((spinzz % 360D) / 90D))));
if(!canRotate())
{
return d;
}
if(d instanceof Directional)
{
Directional g = ((Directional) d);
BlockFace f = g.getFacing();
BlockVector bv = new BlockVector(f.getModX(), f.getModY(), f.getModZ());
bv = rotate(bv.clone(), spinx, spiny, spinz);
BlockFace t = getFace(bv);
if(g.getFaces().contains(t))
{
g.setFacing(t);
}
else if(!g.getMaterial().isSolid())
{
d = null;
}
}
else if(d instanceof Orientable)
{
Orientable g = ((Orientable) d);
BlockFace f = faceForAxis(g.getAxis());
BlockVector bv = new BlockVector(f.getModX(), f.getModY(), f.getModZ());
bv = rotate(bv.clone(), spinx, spiny, spinz);
BlockFace t = getFace(bv);
Axis a = !((Orientable) d).getAxes().contains(Axis.Y) ? axisFor(t) : axisFor2D(t);
((Orientable) d).setAxis(a);
}
else if(d instanceof Rotatable)
{
Rotatable g = ((Rotatable) d);
BlockFace f = g.getRotation();
BlockVector bv = new BlockVector(f.getModX(), f.getModY(), f.getModZ());
bv = rotate(bv.clone(), spinx, spiny, spinz);
BlockFace t = getFace(bv);
g.setRotation(t);
}
else if(d instanceof MultipleFacing)
{
List<BlockFace> faces = new KList<>();
MultipleFacing g = (MultipleFacing) d;
for(BlockFace i : g.getFaces())
{
BlockVector bv = new BlockVector(i.getModX(), i.getModY(), i.getModZ());
bv = rotate(bv.clone(), spinx, spiny, spinz);
BlockFace r = getFace(bv);
if(g.getAllowedFaces().contains(r))
{
faces.add(r);
}
}
for(BlockFace i : g.getFaces())
{
g.setFace(i, false);
}
for(BlockFace i : faces)
{
g.setFace(i, true);
}
}
return d;
}
public BlockVector rotate(BlockVector b, int spinx, int spiny, int spinz)
{
if(!canRotate())
{
return b;
}
BlockVector v = b.clone();
if(canRotateX())
{
v.rotateAroundX(getXRotation(spinx));
}
if(canRotateZ())
{
v.rotateAroundZ(getZRotation(spinz));
}
if(canRotateY())
{
if(getYAxis().isLocked())
{
if(Math.abs(getYAxis().getMax()) == 180D)
{
v.setX(-v.getX());
v.setZ(-v.getZ());
}
else if(getYAxis().getMax() == 90D || getYAxis().getMax() == -270D)
{
double x = v.getX();
v.setX(v.getZ());
v.setZ(-x);
}
else if(getYAxis().getMax() == -90D || getYAxis().getMax() == 270D)
{
double x = v.getX();
v.setX(-v.getZ());
v.setZ(x);
}
else
{
v.rotateAroundY(getYRotation(spiny));
}
}
else
{
v.rotateAroundY(getYRotation(spiny));
}
}
return v;
}
public boolean canRotateX()
{
return enabled && xAxis.isEnabled();
}
public boolean canRotateY()
{
return enabled && yAxis.isEnabled();
}
public boolean canRotateZ()
{
return enabled && zAxis.isEnabled();
}
public boolean canRotate()
{
return canRotateX() || canRotateY() || canRotateZ();
}
}