Skip to content

Commit

Permalink
fix(FastLeafDecay): account for datapacks changing the leaves block tag
Browse files Browse the repository at this point in the history
  • Loading branch information
Machine-Maker committed Jan 22, 2022
1 parent 42e33ec commit f22777a
Show file tree
Hide file tree
Showing 9 changed files with 322 additions and 264 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
import com.google.inject.Inject;
import me.machinemaker.vanillatweaks.integrations.Interactions;
import me.machinemaker.vanillatweaks.modules.ModuleListener;
import me.machinemaker.vanillatweaks.tags.MaterialTag;
import me.machinemaker.vanillatweaks.tags.Tags;
import me.machinemaker.vanillatweaks.tags.types.MaterialTag;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

class LeafListener implements ModuleListener {

private static final List<BlockFace> FACES = Lists.newArrayList(Arrays.stream(BlockFace.values()).filter(BlockFace::isCartesian).toList());
private static final List<BlockFace> FACES = Lists.newArrayList(Arrays.stream(BlockFace.values()).filter(BlockFace::isCartesian).toList()); // mutable list due to Collections#shuffle
private static final Set<Block> SCHEDULED = Sets.newHashSet();
private final JavaPlugin plugin;

Expand Down Expand Up @@ -71,9 +71,7 @@ private void doDecay(Block block) {
for (BlockFace face : FACES) {
Block b = block.getRelative(face);
if (SCHEDULED.contains(b)) continue;
if (!Tag.LEAVES.isTagged(b.getType())) continue;
Leaves leaves = (Leaves) b.getBlockData();
if (leaves.isPersistent() || leaves.getDistance() < 7) continue;
if (!(b.getBlockData() instanceof Leaves leaves) || leaves.isPersistent() || leaves.getDistance() < 7) continue; // https://github.com/MC-Machinations/VanillaTweaks/issues/54, datapacks modify the #minecraft:leaves block tag
SCHEDULED.add(b);
Bukkit.getScheduler().runTaskLater(this.plugin, () -> {
LeavesDecayEvent decayEvent = new LeavesDecayEvent(b);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* GNU General Public License v3
*
* VanillaTweaks, a performant replacement for the VanillaTweaks datapacks.
*
* Copyright (C) 2021 Machine_Maker
*
* This program 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, version 3.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
package me.machinemaker.vanillatweaks.tags;

import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

abstract class AbstractTag<T extends Keyed> implements Tag<T> {

private final NamespacedKey key;
protected final Set<T> tagged;

protected AbstractTag(NamespacedKey key, @NotNull Collection<T> values) {
this.key = key;
this.tagged = Set.copyOf(values);
}

@Override
public NamespacedKey getKey() {
return this.key;
}

@Override
public boolean isTagged(T value) {
return this.tagged.contains(value);
}

@Override
public boolean test(T value) {
return this.isTagged(value);
}

@NotNull
@Override
public Set<T> getValues() {
return this.tagged;
}

static abstract class Builder<T extends Keyed, A extends AbstractTag<T>, C extends Builder<T, A, C>> {

protected final NamespacedKey key;
protected final Set<T> tagged;

protected Builder(NamespacedKey key) {
this(key, Collections.emptySet());
}

protected Builder(NamespacedKey key, Set<T> tagged) {
this.key = key;
this.tagged = new HashSet<>(tagged);
}

@SuppressWarnings("unchecked")
private C self() {
return (C) this;
}

public final C endsWith(String suffix) {
return this.add(v -> this.nameOf(v).endsWith(suffix));
}

public final C startsWith(String prefix) {
return this.add(v -> this.nameOf(v).startsWith(prefix));
}

public final C contains(String contains) {
return this.add(v -> this.nameOf(v).contains(contains));
}

public final C add(Predicate<T> predicate) {
return this.add(this.allValues().stream().filter(predicate).toList());
}

public final C add(org.bukkit.Tag<T> tag) {
return this.add(tag.getValues());
}

public final C add(Tag<T> tag) {
return this.add(tag.getValues());
}

public final C add(Collection<T> values) {
this.tagged.addAll(values);
return this.self();
}

@SafeVarargs
public final C add(T... values) {
//noinspection ManualArrayToCollectionCopy
for (T value : values) {
//noinspection UseBulkOperation
this.tagged.add(value);
}
return this.self();
}

public final C remove(Predicate<T> predicate) {
this.tagged.removeIf(predicate);
return this.self();
}

public final C remove(org.bukkit.Tag<T> tag) {
return this.remove(tag.getValues());
}

public final C remove(Tag<T> tag) {
return this.remove(tag.getValues());
}

public final C remove(Collection<T> values) {
this.tagged.removeAll(values);
return this.self();
}

@SafeVarargs
public final C remove(T... values) {
for (T value : values) {
this.tagged.remove(value);
}
return this.self();
}

public final C verify(int size) {
if (this.tagged.size() != size) {
throw new IllegalStateException(String.format("%s does not have the expected size. expected: %d, actual: %d", this.key, size, this.tagged.size()));
}
return this.self();
}

public abstract String nameOf(T value);

public abstract Collection<T> allValues();

public abstract A build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* GNU General Public License v3
*
* VanillaTweaks, a performant replacement for the VanillaTweaks datapacks.
*
* Copyright (C) 2021 Machine_Maker
*
* This program 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, version 3.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
package me.machinemaker.vanillatweaks.tags;

import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.Collection;
import java.util.Set;

public final class MaterialTag extends AbstractTag<Material> {

public MaterialTag(NamespacedKey key, @NotNull Collection<Material> values) {
super(key, values);
}

public static Builder builder(NamespacedKey key) {
return new Builder(key);
}

public boolean isTagged(Item item) {
return this.isTagged(item.getItemStack());
}

public boolean isTagged(ItemStack stack) {
return this.isTagged(stack.getType());
}

public boolean isTagged(Block block) {
return this.isTagged(block.getType());
}

public static final class Builder extends AbstractTag.Builder<Material, MaterialTag, Builder> {

Builder(NamespacedKey key) {
super(key);
}

@Override
public String nameOf(Material value) {
return value.name();
}

@Override
public Collection<Material> allValues() {
//noinspection deprecation // for tests
return Set.copyOf(Arrays.stream(Material.values()).filter(m -> !m.isLegacy()).toList());
}

@Override
public MaterialTag build() {
return new MaterialTag(this.key, this.tagged);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* GNU General Public License v3
*
* VanillaTweaks, a performant replacement for the VanillaTweaks datapacks.
*
* Copyright (C) 2021 Machine_Maker
*
* This program 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, version 3.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
package me.machinemaker.vanillatweaks.tags;

import org.bukkit.Keyed;

import java.util.function.Predicate;

public interface Tag<T extends Keyed> extends org.bukkit.Tag<T>, Predicate<T> {

/**
* Checks if the value is a member of this tag
*
* @param value the value to check
* @return true if value is a member of this tag
*/
@Override
boolean test(T value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,46 +20,49 @@
package me.machinemaker.vanillatweaks.tags;

import me.machinemaker.vanillatweaks.utils.Keys;
import me.machinemaker.vanillatweaks.tags.types.MaterialTag;
import org.bukkit.Material;

public final class Tags {

private Tags() {
}

public static final MaterialTag DURABILITY = new MaterialTag(Keys.key("durability_items"))
.add(material -> material.getMaxDurability() > 0);
public static final MaterialTag DURABILITY = material("durability_items").add(m -> m.getMaxDurability() > 0).build();

public static final MaterialTag DAMAGEABLE_TOOLS = new MaterialTag(Keys.key("damageable_tools"))
public static final MaterialTag DAMAGEABLE_TOOLS = material("damageable_tools")
.endsWith("_SWORD")
.endsWith("_SHOVEL")
.endsWith("_PICKAXE")
.endsWith("_AXE")
.endsWith("_HOE")
.endsWith("_ON_A_STICK")
.add(Material.FLINT_AND_STEEL)
.endsWith("BOW")
.add(Material.SHEARS)
.add(Material.FISHING_ROD)
.add(Material.TRIDENT);
.add(Material.FLINT_AND_STEEL, Material.SHEARS, Material.FISHING_ROD, Material.TRIDENT)
.build();

public static final MaterialTag DAMAGEABLE_ARMOR = new MaterialTag(Keys.key("damageable_armor"))
public static final MaterialTag DAMAGEABLE_ARMOR = material("damageable_armor")
.add(DURABILITY)
.not(DAMAGEABLE_TOOLS);
.remove(DAMAGEABLE_TOOLS)
.build();

public static final MaterialTag REDSTONE_COMPONENTS = new MaterialTag(Keys.key("redstone_components"))
public static final MaterialTag REDSTONE_COMPONENTS = material("redstone_components")
.add(Material.REPEATER)
.add(Material.COMPARATOR)
.add(Material.OBSERVER)
.add(Material.DISPENSER)
.add(Material.DROPPER)
.add(Material.HOPPER)
.add(Material.STICKY_PISTON)
.add(Material.PISTON);
public static final MaterialTag GLAZED_TERRACOTTA = new MaterialTag(Keys.key("glazed_terracotta"))
.endsWith("_GLAZED_TERRACOTTA").ensureSize("glazed terracotta", 16);
.add(Material.PISTON)
.build();

public static final MaterialTag CHESTPLATES = new MaterialTag(Keys.key("chestplates"))
.endsWith("_CHESTPLATE").ensureSize("chestplates", 6);
public static final MaterialTag GLAZED_TERRACOTTA = material("glazed_terracotta")
.endsWith("_GLAZED_TERRACOTTA").verify(16).build();

public static final MaterialTag CHESTPLATES = material("chestplates")
.endsWith("_CHESTPLATE").verify(6).build();

private static MaterialTag.Builder material(String name) {
return MaterialTag.builder(Keys.key(name));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* GNU General Public License v3
*
* VanillaTweaks, a performant replacement for the VanillaTweaks datapacks.
*
* Copyright (C) 2021 Machine_Maker
*
* This program 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, version 3.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Package for managing/creating value tags
*/
@DefaultQualifier(NonNull.class)
package me.machinemaker.vanillatweaks.tags;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;
Loading

0 comments on commit f22777a

Please sign in to comment.