Skip to content

Commit

Permalink
Rewrite/rotation task (#683)
Browse files Browse the repository at this point in the history
* New methods in CruiseDirection

* Change RotationTask execute to use new methods

* Early return + rename variables

* Extract Rotate function

* Extract Rotate Human Entity

* checkChests refactor

* Extract rotation message

* Correction Entity List

* Fix rotateEntitiesOnCraft

* Merge clockwise and anticlockwise rotation

* Refactor `fromBlockFace` method
  • Loading branch information
Intybyte authored Aug 17, 2024
1 parent 953f7d0 commit dc05661
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 169 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,11 @@
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.InventoryView;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import static net.countercraft.movecraft.util.MathUtils.withinWorldBorder;
Expand Down Expand Up @@ -195,150 +194,142 @@ protected void execute() {
tOP.setX(tOP.getBlockX() + 0.5);
tOP.setZ(tOP.getBlockZ() + 0.5);

if (!(craft instanceof SinkingCraft && craft.getType().getBoolProperty(CraftType.ONLY_MOVE_PLAYERS))
&& craft.getType().getBoolProperty(CraftType.MOVE_ENTITIES)) {
Location midpoint = new Location(
craft.getWorld(),
(oldHitBox.getMaxX() + oldHitBox.getMinX())/2.0,
(oldHitBox.getMaxY() + oldHitBox.getMinY())/2.0,
(oldHitBox.getMaxZ() + oldHitBox.getMinZ())/2.0);
for(Entity entity : craft.getWorld().getNearbyEntities(midpoint,
oldHitBox.getXLength() / 2.0 + 1,
oldHitBox.getYLength() / 2.0 + 2,
oldHitBox.getZLength() / 2.0 + 1)) {

if (entity instanceof HumanEntity) {
InventoryView inventoryView = ((HumanEntity) entity).getOpenInventory();
if (inventoryView.getType() != InventoryType.CRAFTING) {
Location l = Movecraft.getInstance().getWorldHandler().getAccessLocation(inventoryView);
if (l != null) {
MovecraftLocation location = new MovecraftLocation(l.getBlockX(), l.getBlockY(), l.getBlockZ());
if (oldHitBox.contains(location)) {
location = MathUtils.rotateVec(rotation, location.subtract(originPoint)).add(originPoint);
updates.add(new AccessLocationUpdateCommand(inventoryView, location.toBukkit(w)));
}
}
}
}
rotateEntitiesOnCraft(tOP);

if (!craft.getType().getBoolProperty(CraftType.ONLY_MOVE_PLAYERS) || (
(entity.getType() == EntityType.PLAYER || entity.getType() == EntityType.PRIMED_TNT)
&& !(craft instanceof SinkingCraft)
)) {
// Player is onboard this craft

Location adjustedPLoc = entity.getLocation().subtract(tOP);

double[] rotatedCoords = MathUtils.rotateVecNoRound(rotation,
adjustedPLoc.getX(), adjustedPLoc.getZ());
float newYaw = rotation == MovecraftRotation.CLOCKWISE ? 90F : -90F;

CraftTeleportEntityEvent e = new CraftTeleportEntityEvent(craft, entity);
Bukkit.getServer().getPluginManager().callEvent(e);
if (e.isCancelled())
continue;

EntityUpdateCommand eUp = new EntityUpdateCommand(entity,
rotatedCoords[0] + tOP.getX() - entity.getLocation().getX(),
0,
rotatedCoords[1] + tOP.getZ() - entity.getLocation().getZ(),
newYaw,
0
);
updates.add(eUp);
}
}
Craft craft1 = getCraft();
if (craft1.getCruising()) {
CruiseDirection direction = craft1.getCruiseDirection();
craft1.setCruiseDirection(direction.getRotated(rotation));
}

if (getCraft().getCruising()) {
if (rotation == MovecraftRotation.ANTICLOCKWISE) {
// ship faces west
switch (getCraft().getCruiseDirection()) {
case WEST:
getCraft().setCruiseDirection(CruiseDirection.SOUTH);
break;
// ship faces east
case EAST:
getCraft().setCruiseDirection(CruiseDirection.NORTH);
break;
// ship faces north
case SOUTH:
getCraft().setCruiseDirection(CruiseDirection.EAST);
break;
// ship faces south
case NORTH:
getCraft().setCruiseDirection(CruiseDirection.WEST);
break;
}
} else if (rotation == MovecraftRotation.CLOCKWISE) {
// ship faces west
switch (getCraft().getCruiseDirection()) {
case WEST:
getCraft().setCruiseDirection(CruiseDirection.NORTH);
break;
// ship faces east
case EAST:
getCraft().setCruiseDirection(CruiseDirection.SOUTH);
break;
// ship faces north
case SOUTH:
getCraft().setCruiseDirection(CruiseDirection.WEST);
break;
// ship faces south
case NORTH:
getCraft().setCruiseDirection(CruiseDirection.EAST);
break;
}
}
// if you rotated a subcraft, update the parent with the new blocks
if (!this.isSubCraft) {
return;
}
// also find the furthest extent from center and notify the player of the new direction
int farthestX = 0;
int farthestZ = 0;
for (MovecraftLocation loc : newHitBox) {
if (Math.abs(loc.getX() - originPoint.getX()) > Math.abs(farthestX))
farthestX = loc.getX() - originPoint.getX();
if (Math.abs(loc.getZ() - originPoint.getZ()) > Math.abs(farthestZ))
farthestZ = loc.getZ() - originPoint.getZ();
}
Component faceMessage = I18nSupport.getInternationalisedComponent("Rotation - Farthest Extent Facing")
.append(Component.text(" "));

// if you rotated a subcraft, update the parent with the new blocks
if (this.isSubCraft) {
// also find the furthest extent from center and notify the player of the new direction
int farthestX = 0;
int farthestZ = 0;
for (MovecraftLocation loc : newHitBox) {
if (Math.abs(loc.getX() - originPoint.getX()) > Math.abs(farthestX))
farthestX = loc.getX() - originPoint.getX();
if (Math.abs(loc.getZ() - originPoint.getZ()) > Math.abs(farthestZ))
farthestZ = loc.getZ() - originPoint.getZ();
faceMessage = faceMessage.append(getRotationMessage(farthestX, farthestZ));
craft1.getAudience().sendMessage(faceMessage);

craftsInWorld = CraftManager.getInstance().getCraftsInWorld(craft1.getWorld());
for (Craft craft : craftsInWorld) {
if (newHitBox.intersection(craft.getHitBox()).isEmpty() || craft == craft1) {
continue;
}
Component faceMessage = I18nSupport.getInternationalisedComponent("Rotation - Farthest Extent Facing")
.append(Component.text(" "));
if (Math.abs(farthestX) > Math.abs(farthestZ)) {
if (farthestX > 0) {
faceMessage = faceMessage.append(I18nSupport.getInternationalisedComponent("Contact/Subcraft Rotate - East"));
} else {
faceMessage = faceMessage.append(I18nSupport.getInternationalisedComponent("Contact/Subcraft Rotate - West"));
}
//newHitBox.addAll(CollectionUtils.filter(craft.getHitBox(),newHitBox));
//craft.setHitBox(newHitBox);
if (Settings.Debug) {
Bukkit.broadcastMessage(String.format("Size of %s hitbox: %d, Size of %s hitbox: %d", this.craft.getType().getStringProperty(CraftType.NAME), newHitBox.size(), craft.getType().getStringProperty(CraftType.NAME), craft.getHitBox().size()));
}
craft.setHitBox(craft.getHitBox().difference(oldHitBox).union(newHitBox));
if (Settings.Debug){
Bukkit.broadcastMessage(String.format("Hitbox of craft %s intersects hitbox of craft %s", this.craft.getType().getStringProperty(CraftType.NAME), craft.getType().getStringProperty(CraftType.NAME)));
Bukkit.broadcastMessage(String.format("Size of %s hitbox: %d, Size of %s hitbox: %d", this.craft.getType().getStringProperty(CraftType.NAME), newHitBox.size(), craft.getType().getStringProperty(CraftType.NAME), craft.getHitBox().size()));
}
break;
}

}

private Component getRotationMessage(int farthestX, int farthestZ) {
if (Math.abs(farthestX) > Math.abs(farthestZ)) {
if (farthestX > 0) {
return I18nSupport.getInternationalisedComponent("Contact/Subcraft Rotate - East");
} else {
if (farthestZ > 0) {
faceMessage = faceMessage.append(I18nSupport.getInternationalisedComponent("Contact/Subcraft Rotate - South"));
} else {
faceMessage = faceMessage.append(I18nSupport.getInternationalisedComponent("Contact/Subcraft Rotate - North"));
}
return I18nSupport.getInternationalisedComponent("Contact/Subcraft Rotate - West");
}
getCraft().getAudience().sendMessage(faceMessage);

craftsInWorld = CraftManager.getInstance().getCraftsInWorld(getCraft().getWorld());
for (Craft craft : craftsInWorld) {
if (!newHitBox.intersection(craft.getHitBox()).isEmpty() && craft != getCraft()) {
//newHitBox.addAll(CollectionUtils.filter(craft.getHitBox(),newHitBox));
//craft.setHitBox(newHitBox);
if (Settings.Debug) {
Bukkit.broadcastMessage(String.format("Size of %s hitbox: %d, Size of %s hitbox: %d", this.craft.getType().getStringProperty(CraftType.NAME), newHitBox.size(), craft.getType().getStringProperty(CraftType.NAME), craft.getHitBox().size()));
}
craft.setHitBox(craft.getHitBox().difference(oldHitBox).union(newHitBox));
if (Settings.Debug){
Bukkit.broadcastMessage(String.format("Hitbox of craft %s intersects hitbox of craft %s", this.craft.getType().getStringProperty(CraftType.NAME), craft.getType().getStringProperty(CraftType.NAME)));
Bukkit.broadcastMessage(String.format("Size of %s hitbox: %d, Size of %s hitbox: %d", this.craft.getType().getStringProperty(CraftType.NAME), newHitBox.size(), craft.getType().getStringProperty(CraftType.NAME), craft.getHitBox().size()));
}
break;
}
} else {
if (farthestZ > 0) {
return I18nSupport.getInternationalisedComponent("Contact/Subcraft Rotate - South");
} else {
return I18nSupport.getInternationalisedComponent("Contact/Subcraft Rotate - North");
}
}
}

private void rotateEntitiesOnCraft(Location tOP) {
if (!craft.getType().getBoolProperty(CraftType.MOVE_ENTITIES)
|| (craft instanceof SinkingCraft
&& craft.getType().getBoolProperty(CraftType.ONLY_MOVE_PLAYERS))) {
return;
}

Location midpoint = new Location(
craft.getWorld(),
(oldHitBox.getMaxX() + oldHitBox.getMinX())/2.0,
(oldHitBox.getMaxY() + oldHitBox.getMinY())/2.0,
(oldHitBox.getMaxZ() + oldHitBox.getMinZ())/2.0);

List<EntityType> entityList = List.of(EntityType.PLAYER, EntityType.PRIMED_TNT);
for(Entity entity : craft.getWorld().getNearbyEntities(midpoint,
oldHitBox.getXLength() / 2.0 + 1,
oldHitBox.getYLength() / 2.0 + 2,
oldHitBox.getZLength() / 2.0 + 1)) {

rotateHumanEntity(entity);

if (craft.getType().getBoolProperty(CraftType.ONLY_MOVE_PLAYERS)
&& (!entityList.contains(entity.getType())
|| craft instanceof SinkingCraft)) {
continue;
}// Player is onboard this craft

Location adjustedPLoc = entity.getLocation().subtract(tOP);

double[] rotatedCoords = MathUtils.rotateVecNoRound(rotation,
adjustedPLoc.getX(), adjustedPLoc.getZ());
float newYaw = rotation == MovecraftRotation.CLOCKWISE ? 90F : -90F;

CraftTeleportEntityEvent e = new CraftTeleportEntityEvent(craft, entity);
Bukkit.getServer().getPluginManager().callEvent(e);
if (e.isCancelled())
continue;

EntityUpdateCommand eUp = new EntityUpdateCommand(entity,
rotatedCoords[0] + tOP.getX() - entity.getLocation().getX(),
0,
rotatedCoords[1] + tOP.getZ() - entity.getLocation().getZ(),
newYaw,
0
);
updates.add(eUp);


}
}

private void rotateHumanEntity(Entity entity) {
if (!(entity instanceof HumanEntity)) {
return;
}

InventoryView inventoryView = ((HumanEntity) entity).getOpenInventory();
if (inventoryView.getType() == InventoryType.CRAFTING) {
return;
}

Location l = Movecraft.getInstance().getWorldHandler().getAccessLocation(inventoryView);
if (l == null) {
return;
}

MovecraftLocation location = new MovecraftLocation(l.getBlockX(), l.getBlockY(), l.getBlockZ());
if (!oldHitBox.contains(location)) {
return;
}

location = MathUtils.rotateVec(rotation, location.subtract(originPoint)).add(originPoint);
updates.add(new AccessLocationUpdateCommand(inventoryView, location.toBukkit(w)));
}

public MovecraftLocation getOriginPoint() {
Expand Down Expand Up @@ -368,37 +359,32 @@ public boolean getIsSubCraft() {
private boolean checkChests(Material mBlock, MovecraftLocation newLoc) {
Material testMaterial;
MovecraftLocation aroundNewLoc;
final World world = craft.getWorld();

aroundNewLoc = newLoc.translate(1, 0, 0);
testMaterial = craft.getWorld().getBlockAt(aroundNewLoc.getX(), aroundNewLoc.getY(), aroundNewLoc.getZ()).getType();
if (testMaterial.equals(mBlock)) {
if (!oldHitBox.contains(aroundNewLoc)) {
return false;
}
}
testMaterial = world.getBlockAt(aroundNewLoc.getX(), aroundNewLoc.getY(), aroundNewLoc.getZ()).getType();
if (checkOldHitBox(testMaterial, mBlock, aroundNewLoc))
return false;

aroundNewLoc = newLoc.translate(-1, 0, 0);
testMaterial = craft.getWorld().getBlockAt(aroundNewLoc.getX(), aroundNewLoc.getY(), aroundNewLoc.getZ()).getType();
if (testMaterial.equals(mBlock)) {
if (!oldHitBox.contains(aroundNewLoc)) {
return false;
}
}
testMaterial = world.getBlockAt(aroundNewLoc.getX(), aroundNewLoc.getY(), aroundNewLoc.getZ()).getType();
if (checkOldHitBox(testMaterial, mBlock, aroundNewLoc))
return false;

aroundNewLoc = newLoc.translate(0, 0, 1);
testMaterial = craft.getWorld().getBlockAt(aroundNewLoc.getX(), aroundNewLoc.getY(), aroundNewLoc.getZ()).getType();
if (testMaterial.equals(mBlock)) {
if (!oldHitBox.contains(aroundNewLoc)) {
return false;
}
}
testMaterial = world.getBlockAt(aroundNewLoc.getX(), aroundNewLoc.getY(), aroundNewLoc.getZ()).getType();

if (checkOldHitBox(testMaterial, mBlock, aroundNewLoc))
return false;

aroundNewLoc = newLoc.translate(0, 0, -1);
testMaterial = craft.getWorld().getBlockAt(aroundNewLoc.getX(), aroundNewLoc.getY(), aroundNewLoc.getZ()).getType();
return !testMaterial.equals(mBlock) || oldHitBox.contains(aroundNewLoc);
testMaterial = world.getBlockAt(aroundNewLoc.getX(), aroundNewLoc.getY(), aroundNewLoc.getZ()).getType();
return !checkOldHitBox(testMaterial, mBlock, aroundNewLoc);
}


private boolean checkOldHitBox(Material testMaterial, Material mBlock, MovecraftLocation aroundNewLoc) {
return testMaterial.equals(mBlock) && !oldHitBox.contains(aroundNewLoc);
}

public MutableHitBox getNewHitBox() {
return newHitBox;
Expand Down
49 changes: 35 additions & 14 deletions api/src/main/java/net/countercraft/movecraft/CruiseDirection.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,41 @@ else if(rawDirection == (byte) 0x43)
}

public static CruiseDirection fromBlockFace(BlockFace direction) {
if(direction.getOppositeFace() == BlockFace.NORTH)
return NORTH;
else if(direction.getOppositeFace() == BlockFace.SOUTH)
return SOUTH;
else if(direction.getOppositeFace() == BlockFace.EAST)
return EAST;
else if(direction.getOppositeFace() == BlockFace.WEST)
return WEST;
else if(direction.getOppositeFace() == BlockFace.UP)
return UP;
else if(direction.getOppositeFace() == BlockFace.DOWN)
return DOWN;
else
return NONE;
return switch (direction.getOppositeFace()) {
case NORTH -> NORTH;
case SOUTH -> SOUTH;
case EAST -> EAST;
case WEST -> WEST;
case UP -> UP;
case DOWN -> DOWN;
default -> NONE;
};
}

public CruiseDirection getOpposite() {
return switch (this) {
case NORTH -> SOUTH;
case SOUTH -> NORTH;
case EAST -> WEST;
case WEST -> EAST;
case UP -> DOWN;
case DOWN -> UP;
case NONE -> NONE;
};
}

public CruiseDirection getRotated(MovecraftRotation rotation) {
return switch(rotation) {
case CLOCKWISE -> switch (this) {
case NORTH -> EAST;
case SOUTH -> WEST;
case EAST -> SOUTH;
case WEST -> NORTH;
default -> this;
};
case ANTICLOCKWISE -> getRotated(MovecraftRotation.CLOCKWISE).getOpposite();
case NONE -> this;
};
}
}

0 comments on commit dc05661

Please sign in to comment.