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

Improve Location Comparison #6205

Merged
merged 5 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
27 changes: 24 additions & 3 deletions src/main/java/ch/njol/skript/classes/data/DefaultComparators.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,27 @@
import ch.njol.skript.aliases.ItemData;
import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.classes.ClassInfo;
import org.skriptlang.skript.lang.comparator.Comparator;
import ch.njol.skript.entity.BoatChestData;
import ch.njol.skript.entity.BoatData;
import ch.njol.skript.entity.EntityData;
import ch.njol.skript.entity.RabbitData;
import org.skriptlang.skript.lang.comparator.Comparators;
import ch.njol.skript.util.BlockUtils;
import ch.njol.skript.util.Date;
import ch.njol.skript.util.EnchantmentType;
import ch.njol.skript.util.Experience;
import ch.njol.skript.util.WeatherType;
import ch.njol.skript.util.GameruleValue;
import ch.njol.skript.util.LocationUtils;
import ch.njol.skript.util.StructureType;
import ch.njol.skript.util.Time;
import ch.njol.skript.util.Timeperiod;
import ch.njol.skript.util.Timespan;
import ch.njol.skript.util.WeatherType;
import ch.njol.skript.util.slot.EquipmentSlot;
import ch.njol.skript.util.slot.Slot;
import ch.njol.skript.util.slot.SlotWithIndex;
import ch.njol.util.StringUtils;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
Expand All @@ -61,6 +61,8 @@
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.skriptlang.skript.lang.comparator.Comparator;
import org.skriptlang.skript.lang.comparator.Comparators;
import org.skriptlang.skript.lang.comparator.Relation;

import java.util.Objects;
Expand Down Expand Up @@ -630,6 +632,25 @@ public boolean supportsOrdering() {
return false;
}
});

// Location - Location
Comparators.registerComparator(Location.class, Location.class, new Comparator<Location, Location>() {
@Override
public Relation compare(Location location1, Location location2) {
// check normal equality first
if (location1.equals(location2)) return Relation.EQUAL;
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
// if not, standardize values
Location normalizedLocation1 = LocationUtils.normalize(location1.clone());
Location normalizedLocation2 = LocationUtils.normalize(location2.clone());
// check if they are equal now
return Relation.get(normalizedLocation1.equals(normalizedLocation2));
}

@Override
public boolean supportsOrdering() {
return false;
}
});
}

}
80 changes: 80 additions & 0 deletions src/main/java/ch/njol/skript/util/LocationUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.util;

import org.bukkit.Location;

/**
* A class that contains methods based around
* making it easier to deal with {@link Location}
* objects.
*/
public class LocationUtils {

/**
* Normalizes the location by ensuring that the pitch is between -90 and 90, the yaw is between -180 and 180,
* and all -0.0 values are converted to 0.0.
*
* @param location The location to normalize
* @return The same location with normalized values.
*/
public static Location normalize(Location location) {
location.setPitch(Location.normalizePitch(location.getPitch()));
location.setYaw(Location.normalizeYaw(location.getYaw()));

if (location.getYaw() == -0.0) location.setYaw(0);
if (location.getPitch() == -0.0) location.setPitch(0);
if (location.getX() == -0.0) location.setX(0);
if (location.getY() == -0.0) location.setY(0);
if (location.getZ() == -0.0) location.setZ(0);
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved

return location;
}

/**
* Compares two locations without taking into account their yaw or pitch.
*
* @param loc1 The first location
* @param loc2 The second location
* @return Whether the x, y, z, and world of the two locations are the same.
*/
public static boolean compareWithoutDirection(Location loc1, Location loc2) {
return compareWithoutDirection(loc1, loc2, 0.0);
}

/**
* Compares two locations without taking into account their yaw or pitch, with a tolerance for the difference
* between the x, y, and z values. This essentially checks if loc2 is within a cube of side length 2*epsilon centered
* around loc1.
* <p>
* Intended for rough comparisons of locations in the future.
*
* @param loc1 The first location
* @param loc2 The second location
* @param epsilon The maximum difference between each of the x, y, and z values of the two locations.
* @return Whether the x, y, z, and world of the two locations are the same.
*/
public static boolean compareWithoutDirection(Location loc1, Location loc2, double epsilon) {
return loc1.getWorld().equals(loc2.getWorld()) &&
Math.abs(loc1.getX() - loc2.getX()) <= epsilon &&
Math.abs(loc1.getY() - loc2.getY()) <= epsilon &&
Math.abs(loc1.getZ() - loc2.getZ()) <= epsilon;
}

}