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

Implement resize transformed region #1421

Merged
merged 2 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ public void trigger(MatchPlayer player) {
}
for (int i = 0; i < inv.getSize(); i++) {
ItemStack current = inv.getItem(i);
if (current != null && matcher.matches(current)) enchant(current, level);
if (current != null && matcher.matches(current)) {
enchant(current, level);
// Makes item sync with client instantly
inv.setItem(i, current);
}
}
}

Expand Down
5 changes: 0 additions & 5 deletions core/src/main/java/tc/oc/pgm/kits/KitParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -459,11 +459,6 @@ else if (stack.getAmount() != 1)
boolean ignoreEnchantments =
XMLUtils.parseBoolean(Node.fromAttr(parent, "ignore-enchantments"), ignoreMetadata);

if (ignoreMetadata && (!ignoreName || !ignoreEnchantments)) {
throw new InvalidXMLException(
"Cannot ignore metadata but respect name or enchantments", parent);
}

return new ItemMatcher(
stack, amount, ignoreDurability, ignoreMetadata, ignoreName, ignoreEnchantments);
}
Expand Down
13 changes: 13 additions & 0 deletions core/src/main/java/tc/oc/pgm/regions/RegionParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@
import tc.oc.pgm.util.XMLParser;
import tc.oc.pgm.util.xml.InvalidXMLException;
import tc.oc.pgm.util.xml.Node;
import tc.oc.pgm.util.xml.XMLFluentParser;
import tc.oc.pgm.util.xml.XMLUtils;

public abstract class RegionParser implements XMLParser<Region, RegionDefinition> {

protected final Map<String, Method> methodParsers;
protected final MapFactory factory;
protected final XMLFluentParser parser;

public RegionParser(MapFactory factory) {
this.factory = factory;
this.methodParsers = MethodParsers.getMethodParsersForClass(getClass());
this.parser = factory.getParser();
}

@Override
Expand Down Expand Up @@ -291,6 +294,16 @@ public MirroredRegion parseMirror(Element el) throws InvalidXMLException {
return new MirroredRegion(this.parseChildren(el), origin, normal);
}

@MethodParser("resize")
public ResizedRegion parseResize(Element el) throws InvalidXMLException {
Region child = this.parseChildren(el);
Vector min = parser.vector(el, "min").attr().required();
Vector max = parser.vector(el, "max").attr().required();
boolean relative = parser.parseBool(el, "relative").attr().orFalse();
validate(child, BlockBoundedValidation.INSTANCE, new Node(el));
return new ResizedRegion(child, min, max, relative);
}

@MethodParser("everywhere")
public EverywhereRegion parseEverywhere(Element el) throws InvalidXMLException {
return EverywhereRegion.INSTANCE;
Expand Down
69 changes: 69 additions & 0 deletions core/src/main/java/tc/oc/pgm/regions/ResizedRegion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package tc.oc.pgm.regions;

import org.bukkit.util.Vector;
import tc.oc.pgm.api.region.Region;
import tc.oc.pgm.util.math.TransformMatrix;

public class ResizedRegion extends TransformedRegion {
private final Vector min, max;
private final boolean relative;
private TransformMatrix matrix;
private TransformMatrix inverse;

public ResizedRegion(Region region, Vector min, Vector max, boolean relative) {
super(region);
this.min = min;
this.max = max;
this.relative = relative;
}

@Override
protected Vector transform(Vector point) {
if (matrix == null) ensureInitialized();
return matrix.transform(point);
}

@Override
protected Vector untransform(Vector point) {
if (inverse == null) ensureInitialized();
return inverse.transform(point);
}

@Override
public Bounds getBounds() {
ensureInitialized();
return super.getBounds();
}

private void ensureInitialized() {
if (matrix != null) return;

var oldBounds = region.getBounds();
if (oldBounds.isEmpty() || !oldBounds.isBlockFinite()) {
this.bounds = oldBounds;
this.matrix = this.inverse = TransformMatrix.identity();
return;
}

var oldSize = oldBounds.getSize();

if (relative) {
min.multiply(oldSize);
max.multiply(oldSize);
}

this.bounds =
new Bounds(oldBounds.getMin().subtract(min), oldBounds.getMax().add(max));
var newSize = bounds.getSize();

this.matrix = TransformMatrix.concat(
TransformMatrix.untranslate(oldBounds.getMin()),
TransformMatrix.scale(newSize.clone().divide(oldSize)),
Pablete1234 marked this conversation as resolved.
Show resolved Hide resolved
TransformMatrix.translate(bounds.getMin()));

this.inverse = TransformMatrix.concat(
TransformMatrix.untranslate(bounds.getMin()),
TransformMatrix.scale(oldSize.clone().divide(newSize)),
TransformMatrix.translate(oldBounds.getMin()));
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/tc/oc/pgm/shops/menu/Payment.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public boolean hasPayment(PlayerInventory inventory) {

public boolean matches(ItemStack item) {
return this.item != null
? Materials.itemsSimilar(item, this.item, true, false)
? Materials.itemsSimilar(item, this.item, true)
: item.getType() == currency;
}
}
13 changes: 13 additions & 0 deletions core/src/main/java/tc/oc/pgm/util/xml/XMLFluentParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import tc.oc.pgm.util.xml.parsers.Builder;
import tc.oc.pgm.util.xml.parsers.FilterBuilder;
import tc.oc.pgm.util.xml.parsers.ItemBuilder;
import tc.oc.pgm.util.xml.parsers.NumberBuilder;
import tc.oc.pgm.util.xml.parsers.PrimitiveBuilder;
import tc.oc.pgm.util.xml.parsers.ReferenceBuilder;
import tc.oc.pgm.util.xml.parsers.RegionBuilder;
Expand Down Expand Up @@ -74,6 +75,18 @@ protected String parse(String text) throws TextException {
};
}

public NumberBuilder<Integer> parseInt(Element el, String... prop) {
return number(Integer.class, el, prop);
}

public NumberBuilder<Double> parseDouble(Element el, String... prop) {
return number(Double.class, el, prop);
}

public <T extends Number> NumberBuilder<T> number(Class<T> cls, Element el, String... prop) {
return new NumberBuilder<>(cls, el, prop);
}

public Builder.Generic<Vector> vector(Element el, String... prop) {
return new Builder.Generic<>(el, prop) {
@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package tc.oc.pgm.util.xml.parsers;

import org.jdom2.Element;
import org.jetbrains.annotations.Nullable;
import tc.oc.pgm.util.xml.InvalidXMLException;
import tc.oc.pgm.util.xml.Node;
import tc.oc.pgm.util.xml.XMLUtils;

public class NumberBuilder<T extends Number> extends Builder<T, NumberBuilder<T>> {

private final Class<T> type;
private boolean infinity;

public NumberBuilder(Class<T> type, @Nullable Element el, String... prop) {
super(el, prop);
this.type = type;
}

/** Allow infinity like oo or -oo */
public NumberBuilder<T> inf() {
this.infinity = true;
return this;
}

@Override
protected T parse(Node node) throws InvalidXMLException {
return XMLUtils.parseNumber(node, type, infinity);
}

@Override
protected NumberBuilder<T> getThis() {
return this;
}
}
32 changes: 20 additions & 12 deletions util/src/main/java/tc/oc/pgm/util/inventory/ItemMatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ public ItemMatcher(
boolean ignoreMetadata,
boolean ignoreName,
boolean ignoreEnchantments) {
if (ignoreMetadata && (!ignoreName || !ignoreEnchantments))
throw new UnsupportedOperationException(
"Cannot ignore metadata but respect name or enchantments");

this.ignoreDurability = ignoreDurability;

Expand All @@ -36,20 +33,31 @@ public ItemMatcher(
this.base = stripMeta(base);
}

private ItemStack stripMeta(ItemStack item) {
ItemMeta meta = item.getItemMeta();
if (meta == null || (!ignoreMetadata && !(ignoreEnchantments && meta.hasEnchants())))
return item;
private ItemStack stripMeta(final ItemStack item) {
// No modification needed
if (!item.hasItemMeta() || (!ignoreMetadata && !ignoreName && !ignoreEnchantments)) return item;

item = item.clone();
if (ignoreMetadata) item.setItemMeta(null);
else item.getEnchantments().keySet().forEach(item::removeEnchantment);
var newItem = item.clone();
if (ignoreMetadata) {
// Strip all meta, then re-add if needed
newItem.setItemMeta(null);

return item;
// Restore name or enchants
if (!ignoreName) newItem.getItemMeta().setDisplayName(item.getItemMeta().getDisplayName());
if (!ignoreEnchantments) newItem.addUnsafeEnchantments(item.getEnchantments());
} else {
// Strip only specific parts
ItemMeta meta = item.getItemMeta();

if (ignoreName) meta.setDisplayName(null);
if (ignoreEnchantments) item.getEnchantments().keySet().forEach(item::removeEnchantment);
}

return newItem;
}

public boolean matches(ItemStack query) {
return Materials.itemsSimilar(base, stripMeta(query), ignoreDurability, ignoreName)
return Materials.itemsSimilar(base, stripMeta(query), ignoreDurability)
&& amount.contains(query.getAmount());
}
}
31 changes: 3 additions & 28 deletions util/src/main/java/tc/oc/pgm/util/material/Materials.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ static boolean isSolid(Material material) {
return material != null && material.isSolid() && !SOLID_EXCLUSIONS.matches(material);
}

static boolean itemsSimilar(
ItemStack first, ItemStack second, boolean skipDur, boolean skipCheckingName) {
static boolean itemsSimilar(ItemStack first, ItemStack second, boolean skipDur) {
if (first == second) {
return true;
}
Expand All @@ -107,36 +106,12 @@ static boolean itemsSimilar(
}
final boolean hasMeta1 = first.hasItemMeta();
final boolean hasMeta2 = second.hasItemMeta();
if (!hasMeta1 && !hasMeta2) {
return true;
}
if (!hasMeta1 && !hasMeta2) return true;

final ItemMeta meta1 = hasMeta1 ? first.getItemMeta() : null;
final ItemMeta meta2 = hasMeta2 ? second.getItemMeta() : null;

final String prevName1 = meta1 != null ? meta1.getDisplayName() : null;
final String prevName2 = meta2 != null ? meta2.getDisplayName() : null;
if (skipCheckingName) {
if (meta1 != null) {
meta1.setDisplayName(null);
}
if (meta2 != null) {
meta2.setDisplayName(null);
}
}

try {
return Bukkit.getItemFactory().equals(meta1, meta2);
} finally {
if (skipCheckingName) {
if (meta1 != null) {
meta1.setDisplayName(prevName1);
}
if (meta2 != null) {
meta2.setDisplayName(prevName2);
}
}
}
return Bukkit.getItemFactory().equals(meta1, meta2);
}

static boolean isSolid(MaterialData material) {
Expand Down
Loading