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(wool): use platform-specific ColorUtils for wool matching #1364

Merged
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
9 changes: 6 additions & 3 deletions core/src/main/java/tc/oc/pgm/wool/MonumentWool.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import tc.oc.pgm.teams.Team;
import tc.oc.pgm.util.bukkit.BukkitUtils;
import tc.oc.pgm.util.event.PlayerItemTransferEvent;
import tc.oc.pgm.util.material.MaterialData;
import tc.oc.pgm.util.named.NameStyle;
import tc.oc.pgm.util.text.TextFormatter;

Expand Down Expand Up @@ -102,11 +103,12 @@ protected boolean canPlayerUpdateProximity(ParticipantState player) {
@Override
protected boolean canBlockUpdateProximity(BlockState oldState, BlockState newState) {
// If monument proximity metric is closest block, make it only the wool
return !hasTouched(getOwner()) || this.getDefinition().isObjectiveWool(newState.getData());
return !hasTouched(getOwner())
|| this.getDefinition().isObjectiveWool(MaterialData.block(newState));
}

public void handleWoolAcquisition(Player player, ItemStack item) {
if (!this.isPlaced() && this.getDefinition().isObjectiveWool(item)) {
if (!this.isPlaced() && this.getDefinition().isObjectiveWool(MaterialData.item(item))) {
ParticipantState participant = this.getMatch().getParticipantState(player);
if (participant != null && this.canComplete(participant.getParty())) {
touch(participant);
Expand All @@ -129,7 +131,8 @@ public void onItemKitApplication(ApplyItemKitEvent event) {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onArmorKitApplication(ApplyKitEvent event) {
if (event.getKit() instanceof ArmorKit) {
for (ArmorKit.ArmorItem armorPiece : ((ArmorKit) event.getKit()).getArmor().values()) {
for (ArmorKit.ArmorItem armorPiece :
((ArmorKit) event.getKit()).getArmor().values()) {
handleWoolAcquisition(event.getPlayer().getBukkit(), armorPiece.stack);
}
}
Expand Down
16 changes: 8 additions & 8 deletions core/src/main/java/tc/oc/pgm/wool/MonumentWoolFactory.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package tc.oc.pgm.wool;

import static net.kyori.adventure.text.Component.text;
import static tc.oc.pgm.wool.WoolModule.WOOL;

import net.kyori.adventure.text.Component;
import org.apache.commons.lang.StringUtils;
import org.bukkit.DyeColor;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Wool;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.Nullable;
import tc.oc.pgm.api.feature.FeatureInfo;
Expand All @@ -18,6 +18,8 @@
import tc.oc.pgm.goals.ShowOptions;
import tc.oc.pgm.teams.TeamFactory;
import tc.oc.pgm.util.bukkit.BukkitUtils;
import tc.oc.pgm.util.material.ColorUtils;
import tc.oc.pgm.util.material.MaterialData;
import tc.oc.pgm.util.text.TextFormatter;

@FeatureInfo(name = "wool")
Expand Down Expand Up @@ -118,12 +120,10 @@ public boolean isCraftable() {
return this.craftable;
}

public boolean isObjectiveWool(ItemStack stack) {
return stack != null && this.isObjectiveWool(stack.getData());
}

public boolean isObjectiveWool(org.bukkit.material.MaterialData material) {
return material instanceof Wool && ((Wool) material).getColor() == this.color;
public boolean isObjectiveWool(MaterialData materialData) {
return materialData != null
&& WOOL.matches(materialData)
&& ColorUtils.COLOR_UTILS.isColor(materialData, color);
}

public boolean isHolding(InventoryHolder holder) {
Expand All @@ -132,7 +132,7 @@ public boolean isHolding(InventoryHolder holder) {

public boolean isHolding(Inventory inv) {
for (ItemStack stack : inv.getContents()) {
if (this.isObjectiveWool(stack)) return true;
if (this.isObjectiveWool(MaterialData.item(stack))) return true;
}
return false;
}
Expand Down
12 changes: 6 additions & 6 deletions core/src/main/java/tc/oc/pgm/wool/WoolMatchModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static net.kyori.adventure.text.Component.translatable;
import static tc.oc.pgm.util.material.ColorUtils.COLOR_UTILS;
import static tc.oc.pgm.wool.WoolModule.WOOL;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
Expand Down Expand Up @@ -40,7 +41,7 @@
import tc.oc.pgm.goals.events.GoalStatusChangeEvent;
import tc.oc.pgm.teams.Team;
import tc.oc.pgm.util.block.BlockVectors;
import tc.oc.pgm.util.material.MaterialMatcher;
import tc.oc.pgm.util.material.MaterialData;

@ListenerScope(MatchScope.RUNNING)
public class WoolMatchModule implements MatchModule, Listener {
Expand All @@ -61,8 +62,6 @@ public class WoolMatchModule implements MatchModule, Listener {
// layout of the wools in the inventory. This is used to refill the container with wools.
private final Map<Inventory, Map<Integer, ItemStack>> woolChests = new HashMap<>();

private static final MaterialMatcher WOOL = MaterialMatcher.of(m -> m.name().endsWith("WOOL"));

private static final int REFILL_INTERVAL = 30; // seconds

public WoolMatchModule(Match match, Multimap<Team, MonumentWool> wools) {
Expand All @@ -85,7 +84,7 @@ public Multimap<Team, MonumentWool> getWools() {
private boolean isObjectiveWool(ItemStack stack) {
if (WOOL.matches(stack.getType())) {
for (MonumentWool wool : this.wools.values()) {
if (wool.getDefinition().isObjectiveWool(stack)) return true;
if (wool.getDefinition().isObjectiveWool(MaterialData.item(stack))) return true;
}
}
return false;
Expand Down Expand Up @@ -220,7 +219,7 @@ public void handleWoolCrafting(PrepareItemCraftEvent event) {

if (playerHolder != null && result != null && WOOL.matches(result.getType())) {
for (MonumentWool wool : this.wools.values()) {
if (wool.getDefinition().isObjectiveWool(result)) {
if (wool.getDefinition().isObjectiveWool(MaterialData.item(result))) {
if (!wool.getDefinition().isCraftable()) {
playerHolder.sendWarning(
translatable("wool.craftingDisabled", wool.getComponentName()));
Expand All @@ -242,6 +241,7 @@ private Entry<Team, MonumentWool> findMonumentWool(Vector point) {
}

private static boolean isValidWool(DyeColor expectedColor, BlockState state) {
return WOOL.matches(state.getType()) && COLOR_UTILS.isColor(state, expectedColor);
return WOOL.matches(state.getType())
&& COLOR_UTILS.isColor(MaterialData.block(state), expectedColor);
}
}
40 changes: 19 additions & 21 deletions core/src/main/java/tc/oc/pgm/wool/WoolModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@
import tc.oc.pgm.teams.TeamMatchModule;
import tc.oc.pgm.teams.TeamModule;
import tc.oc.pgm.teams.Teams;
import tc.oc.pgm.util.material.MaterialMatcher;
import tc.oc.pgm.util.xml.InvalidXMLException;
import tc.oc.pgm.util.xml.Node;
import tc.oc.pgm.util.xml.XMLUtils;

public class WoolModule implements MapModule<WoolMatchModule> {
protected static final MaterialMatcher WOOL = MaterialMatcher.of(m -> m.name().endsWith("WOOL"));
private static final Collection<MapTag> TAGS =
ImmutableList.of(new MapTag("wool", Gamemode.CAPTURE_THE_WOOL, false));

Expand Down Expand Up @@ -98,36 +100,32 @@ public WoolModule parse(MapFactory factory, Logger logger, Document doc)
ShowOptions options = ShowOptions.parse(factory.getFilters(), woolEl);
Boolean required = XMLUtils.parseBoolean(woolEl.getAttribute("required"), null);

ProximityMetric woolProximityMetric =
ProximityMetric.parse(
woolEl, "wool", new ProximityMetric(ProximityMetric.Type.CLOSEST_KILL, false));
ProximityMetric monumentProximityMetric =
ProximityMetric.parse(
woolEl, "monument", new ProximityMetric(ProximityMetric.Type.CLOSEST_BLOCK, false));
ProximityMetric woolProximityMetric = ProximityMetric.parse(
woolEl, "wool", new ProximityMetric(ProximityMetric.Type.CLOSEST_KILL, false));
ProximityMetric monumentProximityMetric = ProximityMetric.parse(
woolEl, "monument", new ProximityMetric(ProximityMetric.Type.CLOSEST_BLOCK, false));

Vector location;
if (factory.getProto().isOlderThan(MapProtos.WOOL_LOCATIONS)) {
// The default location is at infinity, so players/blocks are always an infinite distance
// from it
location =
new Vector(
Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
location = new Vector(
Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
} else {
location = XMLUtils.parseVector(XMLUtils.getRequiredAttribute(woolEl, "location"));
}

MonumentWoolFactory wool =
new MonumentWoolFactory(
id,
required,
options,
team,
woolProximityMetric,
monumentProximityMetric,
color,
location,
placement,
craftable);
MonumentWoolFactory wool = new MonumentWoolFactory(
id,
required,
options,
team,
woolProximityMetric,
monumentProximityMetric,
color,
location,
placement,
craftable);
factory.getFeatures().addFeature(woolEl, wool);
woolFactories.put(team, wool);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.bukkit.scoreboard.Team;
import tc.oc.pgm.util.block.BlockFaces;
import tc.oc.pgm.util.material.ColorUtils;
import tc.oc.pgm.util.material.MaterialData;
import tc.oc.pgm.util.platform.Supports;

@Supports(value = PAPER, minVersion = "1.20.6")
Expand Down Expand Up @@ -104,8 +105,8 @@ public void setColor(Block block, DyeColor color) {
}

@Override
public boolean isColor(BlockState block, DyeColor color) {
return setColor(block.getType(), color) == block.getType();
public boolean isColor(MaterialData data, DyeColor color) {
return setColor(data.getItemType(), color) == data.getItemType();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.bukkit.util.BlockVector;
import tc.oc.pgm.util.block.BlockFaces;
import tc.oc.pgm.util.material.ColorUtils;
import tc.oc.pgm.util.material.MaterialData;
import tc.oc.pgm.util.platform.Supports;
import tc.oc.pgm.util.text.TextTranslations;

Expand Down Expand Up @@ -67,8 +68,10 @@ public void setColor(Block block, DyeColor color) {
}

@Override
public boolean isColor(BlockState block, DyeColor color) {
return color.getWoolData() == block.getRawData();
public boolean isColor(MaterialData data, DyeColor color) {
return data instanceof LegacyMaterialData legacyData
&& isColorAffected(data.getItemType())
&& color.getWoolData() == legacyData.getData();
}

public void setColor(World world, Iterable<BlockVector> positions, DyeColor color) {
Expand Down
3 changes: 1 addition & 2 deletions util/src/main/java/tc/oc/pgm/util/material/ColorUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.bukkit.block.Banner;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BannerMeta;
import org.bukkit.scoreboard.Team;
Expand All @@ -27,7 +26,7 @@ public interface ColorUtils {

void setColor(Block block, DyeColor color);

boolean isColor(BlockState block, DyeColor color);
boolean isColor(MaterialData data, DyeColor color);

default void setColor(World world, Iterable<BlockVector> positions, DyeColor color) {
for (BlockVector pos : positions) {
Expand Down