Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/Add tracked locations rotating on subcrafts #728

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
43521e7
move trackedlocations to subcraft and back to the parent on release
DerToaster98 Jan 9, 2025
bea513c
Ugly hack to allow transfering it to a different craft
DerToaster98 Jan 9, 2025
6ee8f0c
Transfer the same *object*
DerToaster98 Jan 9, 2025
9b93697
update trackedlocation map to concurrent map
DerToaster98 Jan 12, 2025
1ed6851
for some odd reason, the pilot event for subcraft fires twice sometimes
DerToaster98 Jan 12, 2025
49a1bf4
use computeIfAbsent and HashSet in favor of Set.of()
DerToaster98 Jan 12, 2025
b4bcb84
reinforce transfer logic
DerToaster98 Jan 17, 2025
2492f1e
Fix trackedlocation rotation
DerToaster98 Jan 17, 2025
299c160
comment out code => this will rotate ALL aprent craft's trackedlocati…
DerToaster98 Jan 17, 2025
3c8d300
just to be safe and to keep it working with normal rotations
DerToaster98 Jan 17, 2025
873035c
transfer the object if possible to keep compatibility with moving sub…
DerToaster98 Jan 17, 2025
fd33db1
actually run the code
DerToaster98 Jan 17, 2025
7effbfb
temporary "debug" stuff
DerToaster98 Jan 17, 2025
b987822
no need to call reset()
DerToaster98 Jan 17, 2025
19ff28d
throw exception when the effective location changes while transferring
DerToaster98 Jan 17, 2025
e2f7a03
make trackedlocations a bit more stupid
DerToaster98 Jan 18, 2025
de7d7e8
move tracked locations
DerToaster98 Jan 18, 2025
8d312f1
clean up
DerToaster98 Jan 18, 2025
df0b690
remove debug println's
DerToaster98 Jan 18, 2025
ae18c94
Add craftOrigin helper object
DerToaster98 Jan 26, 2025
41c4ca3
update trackedLocation implementation to be based on the enw referenc…
DerToaster98 Jan 26, 2025
073059f
update implementation of translate and rotate for subcrafts
DerToaster98 Jan 26, 2025
f3af15c
forgot to rotate origin too
DerToaster98 Jan 26, 2025
5adcaeb
correct typo
DerToaster98 Jan 26, 2025
3f6425c
careful, the order here is very important => Origin needs to be rotat…
DerToaster98 Jan 26, 2025
8150cef
fix rotation on trackedlocations
DerToaster98 Jan 26, 2025
714316f
Use MovecraftLocation in TrackedLocation
DerToaster98 Jan 27, 2025
e0bfea0
Use MovecraftLocation in CraftOrigin
DerToaster98 Jan 27, 2025
4a018e5
Simplify lambda
DerToaster98 Jan 27, 2025
00a0f3f
Merge branch 'main' into tracked-location-subcraft-support
DerToaster98 Jan 27, 2025
97387ee
fixes and use movecraftlocation as origin now
DerToaster98 Jan 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,13 @@ protected void execute() {

// Rotates the craft's tracked locations, and all parent craft's.
Craft temp = craft;
do {
for (Set<TrackedLocation> locations : craft.getTrackedLocations().values()) {
//do {
for (Set<TrackedLocation> locations : temp.getTrackedLocations().values()) {
for (TrackedLocation location : locations) {
location.rotate(rotation, originPoint);
}
}
} while (temp instanceof SubCraft && (temp = ((SubCraft) temp).getParent()) != null);
//} while (temp instanceof SubCraft && (temp = ((SubCraft) temp).getParent()) != null);

updates.add(new CraftRotateCommand(getCraft(),originPoint, rotation));
//rotate entities in the craft
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import net.countercraft.movecraft.Movecraft;
import net.countercraft.movecraft.MovecraftChunk;
import net.countercraft.movecraft.MovecraftLocation;
import net.countercraft.movecraft.TrackedLocation;
import net.countercraft.movecraft.async.AsyncTask;
import net.countercraft.movecraft.config.Settings;
import net.countercraft.movecraft.craft.ChunkManager;
Expand Down Expand Up @@ -318,6 +319,8 @@ protected void execute() throws InterruptedException, ExecutionException {
}
}

updateTrackedLocations(craft, dx, dy, dz);

if (!collisionBox.isEmpty() && craft.getType().getBoolProperty(CraftType.CRUISE_ON_PILOT)) {
CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.EMPTY, false);
for (MovecraftLocation location : oldHitBox) {
Expand All @@ -339,6 +342,16 @@ protected void execute() throws InterruptedException, ExecutionException {
captureYield(harvestedBlocks);
}

protected void updateTrackedLocations(Craft craft, int dx, int dy, int dz) {
craft.getTrackedLocations().values().forEach(trackedLocations -> {
trackedLocations.forEach(
trackedLocation -> {
trackedLocation.translate(dx, dy, dz);
}
);
});
}

private void preventsTorpedoRocketsPilots() {
if (!craft.getType().getBoolProperty(CraftType.MOVE_ENTITIES) ||
(craft instanceof SinkingCraft
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;

Expand Down Expand Up @@ -79,7 +80,7 @@ public abstract class BaseCraft implements Craft {
private String name = "";
@NotNull
private MovecraftLocation lastTranslation = new MovecraftLocation(0, 0, 0);
private Map<NamespacedKey, Set<TrackedLocation>> trackedLocations = new HashMap<>();
private Map<NamespacedKey, Set<TrackedLocation>> trackedLocations = new ConcurrentHashMap<>();

@NotNull
private final CraftDataTagContainer dataTagContainer;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
package net.countercraft.movecraft.listener;

import com.google.common.base.Predicates;
import net.countercraft.movecraft.MovecraftLocation;
import net.countercraft.movecraft.TrackedLocation;
import net.countercraft.movecraft.craft.Craft;
import net.countercraft.movecraft.craft.SubCraft;
import net.countercraft.movecraft.events.CraftPilotEvent;
import net.countercraft.movecraft.events.CraftReleaseEvent;
import net.countercraft.movecraft.util.hitboxes.HitBox;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;

import java.util.*;
import java.util.function.Predicate;

public class CraftPilotListener implements Listener {

@EventHandler(ignoreCancelled = true)
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onCraftPilot(@NotNull CraftPilotEvent event) {
// Walk through all signs and set a UUID in there
final Craft craft = event.getCraft();
Expand All @@ -30,6 +40,91 @@ public void onCraftPilot(@NotNull CraftPilotEvent event) {
craft.markTileStateWithUUID(tile);
tile.update();
}

// Tracked locations => Modify correctly with subcrafts
if (craft instanceof SubCraft subCraft && subCraft.getParent() != null) {
final Craft parent = subCraft.getParent();
if (parent.getWorld() != subCraft.getWorld()) {
return;
}
transferTrackedLocations(parent, subCraft, (trackedLocation) -> {
MovecraftLocation absolute = trackedLocation.getAbsoluteLocation();
if (subCraft.getHitBox().inBounds(absolute)) {
if (subCraft.getHitBox().contains(absolute)) {
return true;
}
}
return false;
}, true);
}
}

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onCraftRelease(@NotNull CraftReleaseEvent event) {
if (event.getReason() != CraftReleaseEvent.Reason.SUB_CRAFT) {
return;
}
Craft released = event.getCraft();
if (!(released instanceof SubCraft)) {
return;
}
SubCraft subCraft = (SubCraft) released;
if (subCraft.getParent() == null) {
return;
}

// Attention: SquadronCrafts are also subcrafts! We need to make sure that they are at least intersecting the parent when we add back the tracked locations
final HitBox parentHitBox = subCraft.getParent().getHitBox();
final HitBox subCraftHitBox = subCraft.getHitBox();

if (!parentHitBox.inBounds(subCraftHitBox.getMinX(), subCraftHitBox.getMinY(), subCraftHitBox.getMinZ())) {
if (!parentHitBox.inBounds(subCraftHitBox.getMaxX(), subCraftHitBox.getMaxY(), subCraftHitBox.getMaxZ())) {
// Subcraft cant possible be within its parent anymore
return;
}
}

transferTrackedLocations(subCraft, subCraft.getParent(), Predicates.alwaysTrue(), true);
}

/*
* Transfers TrackedLocations from a craft A to a craft B with a optional filter.
* This MOVES the tracked locations, so keep that in mind
*/
private static void transferTrackedLocations(final Craft a, final Craft b, Predicate<TrackedLocation> filterArgument, boolean move) {
final MovecraftLocation bMidPoint = b.getHitBox().getMidPoint();

for (Map.Entry<NamespacedKey, Set<TrackedLocation>> entry : a.getTrackedLocations().entrySet()) {
final Set<TrackedLocation> bTrackedLocations = b.getTrackedLocations().computeIfAbsent(entry.getKey(), k -> new HashSet<>());
final Set<TrackedLocation> aTrackedLocations = entry.getValue();

if (aTrackedLocations.isEmpty()) {
continue;
}

// Commented out code: previous attempt to actually transfer the tracked locations, which technically is unnecessary unless for subcrafts like squadrons that actually move!
List<TrackedLocation> transferred = new ArrayList<>();
aTrackedLocations.forEach(trackedLocation -> {
if (filterArgument.test(trackedLocation)) {
if (move) {
// Technically this (the reset call) is not necessary, but we will keep it here for potential extensions by third party addons
final MovecraftLocation absoluteLocation = trackedLocation.getAbsoluteLocation();
trackedLocation.reset(absoluteLocation);
if (!(bTrackedLocations.add(trackedLocation))) {
trackedLocation.reset(absoluteLocation);
} else {
transferred.add(trackedLocation);
}
if (!absoluteLocation.equals(trackedLocation.getAbsoluteLocation())) {
throw new IllegalStateException("Somehow the previous and transferred absolute locations are NOT the same! This should NEVER happen!");
}
} else {
bTrackedLocations.add(trackedLocation);
}
}
});
aTrackedLocations.removeAll(transferred);
}
}

}
56 changes: 43 additions & 13 deletions api/src/main/java/net/countercraft/movecraft/TrackedLocation.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,73 @@
import org.jetbrains.annotations.NotNull;

public class TrackedLocation {
private MovecraftLocation offSet;
private final Craft craft;

private int x;
private int y;
private int z;

/**
* Creates a new TrackedLocation instance which tracks a location about a craft's midpoint.
* @param craft The craft that's that tied to the location.
* @param location The absolute position to track. This location will be stored as a relative
* location to the craft's central hitbox.
*/
public TrackedLocation(@NotNull MovecraftLocation location) {
reinit(location);
}

@Deprecated(forRemoval = true)
public TrackedLocation(@NotNull Craft craft, @NotNull MovecraftLocation location) {
this.craft = craft;
MovecraftLocation midPoint = craft.getHitBox().getMidPoint();
offSet = location.subtract(midPoint);
this(location);
}

protected void reinit(@NotNull MovecraftLocation location) {
reinit(location.getX(), location.getY(), location.getZ());
}

protected void reinit(final int x, final int y, final int z) {
this.x = x;
this.y = y;
this.z = z;
}

/**
* Rotates the stored location.
* @param rotation A clockwise or counter-clockwise direction to rotate.
*/
public void rotate(MovecraftRotation rotation, MovecraftLocation origin) {
offSet = MathUtils.rotateVec(rotation, getAbsoluteLocation().subtract(origin));
MovecraftLocation absolute = this.getAbsoluteLocation();
MovecraftLocation vector = MathUtils.rotateVec(rotation, absolute.subtract(origin));

MovecraftLocation newAbsolute = origin.add(vector);
reinit(newAbsolute);
}

public void translate(final int dx, final int dy, final int dz) {
this.x += dx;
this.y += dy;
this.z += dz;
}

/**
* Gets the stored absolute location.
* @return Returns the absolute location instead of a vector.
*/
public MovecraftLocation getAbsoluteLocation() {
MovecraftLocation midPoint = craft.getHitBox().getMidPoint();
return offSet.add(midPoint);
return new MovecraftLocation(this.x, this. y, this.z);
}

/**
* Gets the stored location as a position vector relative to the midpoint.
* @return Returns the absolute location instead of a vector.
* NEVER USE THIS UNLESS ABSOLUTELY NECESSARY
* @param craft
* @param location
*/
public MovecraftLocation getOffSet() {
return offSet;
@Deprecated(forRemoval = true)
public void reset(@NotNull Craft craft, @NotNull MovecraftLocation location) {
reset(location);
}

public void reset(@NotNull MovecraftLocation location) {
reinit(location);
}

}
Loading