Skip to content

Commit

Permalink
fix(wool): use platform-specific ColorUtils for wool matching (#1364)
Browse files Browse the repository at this point in the history
Signed-off-by: TTtie <[email protected]>
  • Loading branch information
TTtie authored Jul 11, 2024
1 parent e374f3e commit 63e8ff9
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 44 deletions.
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

0 comments on commit 63e8ff9

Please sign in to comment.