Skip to content

Commit 433fa82

Browse files
mineLdivercalmilamsy
authored andcommitted
Mining levels graph
1 parent c36d9a4 commit 433fa82

10 files changed

Lines changed: 64 additions & 36 deletions

File tree

src/test/java/net/modificationstation/sltest/item/ItemListener.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import net.modificationstation.sltest.block.Blocks;
77
import net.modificationstation.sltest.block.VariationBlock;
88
import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent;
9+
import net.modificationstation.stationapi.api.item.tool.MiningLevelManager;
910
import net.modificationstation.stationapi.api.item.tool.ToolMaterialFactory;
1011
import net.modificationstation.stationapi.api.registry.BlockRegistry;
1112
import net.modificationstation.stationapi.api.registry.ItemRegistry;
@@ -19,8 +20,13 @@ public class ItemListener {
1920

2021
@EventListener
2122
public void registerItems(ItemRegistryEvent event) {
23+
MiningLevelManager.LevelNode moddedNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, NAMESPACE.id("needs_tool_level_modded")));
24+
MiningLevelManager.GRAPH.putEdge(ToolMaterial.STONE.getMiningLevelNode(), moddedNode);
25+
MiningLevelManager.GRAPH.putEdge(moddedNode, ToolMaterial.IRON.getMiningLevelNode());
26+
MiningLevelManager.invalidateCache();
27+
2228
testItem = new ModdedItem(NAMESPACE.id("test_item")).setTranslationKey(NAMESPACE, "testItem"); //8475
23-
testMaterial = ToolMaterialFactory.create("testMaterial", 3, Integer.MAX_VALUE, Float.MAX_VALUE, Integer.MAX_VALUE - 2).miningLevelTag(TagKey.of(BlockRegistry.KEY, NAMESPACE.id("needs_tool_level_modded")));
29+
testMaterial = ToolMaterialFactory.create("testMaterial", 3, Integer.MAX_VALUE, Float.MAX_VALUE, Integer.MAX_VALUE - 2).miningLevelNode(moddedNode);
2430
testPickaxe = new ModdedPickaxeItem(NAMESPACE.id("test_pickaxe"), testMaterial).setTranslationKey(NAMESPACE, "testPickaxe"); //8476
2531
testNBTItem = new NBTItem(NAMESPACE.id("nbt_item")).setTranslationKey(NAMESPACE, "nbt_item"); //8477
2632
testModelItem = new ModelItem(NAMESPACE.id("model_item")).setMaxCount(1).setTranslationKey(NAMESPACE, "idkSomething");
@@ -32,6 +38,8 @@ public void registerItems(ItemRegistryEvent event) {
3238
testShears = new TestShearsItem(NAMESPACE.id("test_shears")).setTranslationKey(NAMESPACE, "test_shears");
3339
pacifistSword = new PacifistSwordItem(NAMESPACE.id("pacifist_sword")).setTranslationKey(NAMESPACE, "pacifist_sword");
3440
dullPickaxe = new DullPickaxeItem(NAMESPACE.id("dull_pickaxe")).setTranslationKey(NAMESPACE, "dull_pickaxe");
41+
42+
3543
}
3644

3745
public static Item testItem;

src/test/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"values": [
3-
"#needs_stone_tool",
43
"sltest:test_block"
54
]
65
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package net.modificationstation.stationapi.api.item.tool;
2+
3+
import com.google.common.graph.GraphBuilder;
4+
import com.google.common.graph.MutableGraph;
5+
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
6+
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
7+
import lombok.val;
8+
import net.minecraft.block.Block;
9+
import net.modificationstation.stationapi.api.block.BlockState;
10+
import net.modificationstation.stationapi.api.tag.TagKey;
11+
12+
import java.util.stream.Collectors;
13+
14+
public final class MiningLevelManager {
15+
public record LevelNode(TagKey<Block> blockTag) {}
16+
private record CacheKey(LevelNode levelNode, BlockState state) {}
17+
18+
public static final MutableGraph<LevelNode> GRAPH = GraphBuilder.directed().build();
19+
private static final Object2BooleanMap<CacheKey> CACHE = new Object2BooleanOpenHashMap<>();
20+
21+
public static boolean isSuitable(LevelNode levelNode, BlockState state) {
22+
return CACHE.computeIfAbsent(new CacheKey(levelNode, state), (CacheKey key) -> {
23+
val nodes = GRAPH.nodes().stream().filter(node -> key.state.isIn(node.blockTag)).collect(Collectors.toSet());
24+
if (nodes.isEmpty()) return true;
25+
val pred = GRAPH.predecessors(key.levelNode);
26+
return nodes.stream().anyMatch(node -> key.levelNode.equals(node) || pred.contains(node));
27+
});
28+
}
29+
30+
public static void invalidateCache() {
31+
CACHE.clear();
32+
}
33+
}
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
package net.modificationstation.stationapi.api.item.tool;
22

3-
import net.minecraft.block.Block;
43
import net.minecraft.item.ToolMaterial;
5-
import net.modificationstation.stationapi.api.tag.TagKey;
64
import net.modificationstation.stationapi.api.util.Util;
75

86
public interface StationToolMaterial {
9-
default ToolMaterial miningLevelTag(TagKey<Block> tag) {
7+
default ToolMaterial miningLevelNode(MiningLevelManager.LevelNode levelNode) {
108
return Util.assertImpl();
119
}
1210

13-
default TagKey<Block> getMiningLevelTag() {
11+
default MiningLevelManager.LevelNode getMiningLevelNode() {
1412
return Util.assertImpl();
1513
}
1614
}

station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package net.modificationstation.stationapi.impl.item;
22

3+
import com.google.common.graph.GraphBuilder;
34
import net.mine_diver.unsafeevents.listener.EventListener;
45
import net.minecraft.item.Item;
56
import net.minecraft.item.ItemStack;
6-
import net.minecraft.item.ToolMaterial;
77
import net.modificationstation.stationapi.api.StationAPI;
88
import net.modificationstation.stationapi.api.block.BlockState;
99
import net.modificationstation.stationapi.api.event.item.IsItemSuitableForStateEvent;
1010
import net.modificationstation.stationapi.api.event.item.ItemMiningSpeedMultiplierOnStateEvent;
1111
import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent;
12+
import net.modificationstation.stationapi.api.item.tool.MiningLevelManager;
1213
import net.modificationstation.stationapi.api.item.tool.ToolLevel;
1314
import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint;
1415
import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy;
@@ -18,7 +19,6 @@
1819
import net.modificationstation.stationapi.api.util.Namespace;
1920

2021
import java.util.ArrayList;
21-
import java.util.Arrays;
2222
import java.util.List;
2323
import java.util.Objects;
2424

@@ -73,19 +73,13 @@ private static void getStrength(ItemMiningSpeedMultiplierOnStateEvent event) {
7373

7474
if (!isSuitable(event.itemStack, event.state)) return;
7575

76+
GraphBuilder.directed().allowsSelfLoops(true).build();
7677
event.miningSpeedMultiplier = ((ToolLevel) event.itemStack.getItem()).getMaterial(event.itemStack).getMiningSpeedMultiplier();
7778
}
7879

7980
private static boolean isSuitable(ItemStack item, BlockState state) {
8081
return item.getItem() instanceof ToolLevel toolLevel
8182
&& state.isIn(toolLevel.getEffectiveBlocks(item))
82-
&&
83-
(
84-
state.isIn(toolLevel.getMaterial(item).getMiningLevelTag())
85-
|| Arrays
86-
.stream(ToolMaterial.values())
87-
.filter(toolMaterial -> toolMaterial.getMiningLevelTag() != null)
88-
.noneMatch(toolMaterial -> state.isIn(toolMaterial.getMiningLevelTag()))
89-
);
83+
&& MiningLevelManager.isSuitable(toolLevel.getMaterial(item).getMiningLevelNode(), state);
9084
}
9185
}
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
package net.modificationstation.stationapi.mixin.tools;
22

3-
import net.minecraft.block.Block;
43
import net.minecraft.item.ToolMaterial;
4+
import net.modificationstation.stationapi.api.item.tool.MiningLevelManager;
55
import net.modificationstation.stationapi.api.item.tool.StationToolMaterial;
6-
import net.modificationstation.stationapi.api.tag.TagKey;
76
import org.spongepowered.asm.mixin.Mixin;
87
import org.spongepowered.asm.mixin.Unique;
98

109
@Mixin(ToolMaterial.class)
1110
class ToolMaterialMixin implements StationToolMaterial {
1211
@Unique
13-
private TagKey<Block> stationapi_miningLevelTag;
12+
private MiningLevelManager.LevelNode stationapi_levelNode;
1413

1514
@Override
1615
@Unique
17-
public ToolMaterial miningLevelTag(TagKey<Block> tag) {
18-
stationapi_miningLevelTag = tag;
16+
public ToolMaterial miningLevelNode(MiningLevelManager.LevelNode levelNode) {
17+
stationapi_levelNode = levelNode;
1918
return ToolMaterial.class.cast(this);
2019
}
2120

2221
@Override
2322
@Unique
24-
public TagKey<Block> getMiningLevelTag() {
25-
return stationapi_miningLevelTag;
23+
public MiningLevelManager.LevelNode getMiningLevelNode() {
24+
return stationapi_levelNode;
2625
}
2726
}

station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import net.minecraft.item.ToolMaterial;
55
import net.modificationstation.stationapi.api.StationAPI;
66
import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent;
7+
import net.modificationstation.stationapi.api.item.tool.MiningLevelManager;
78
import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint;
89
import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy;
910
import net.modificationstation.stationapi.api.registry.BlockRegistry;
@@ -16,11 +17,14 @@
1617
public final class VanillaToolFixImpl {
1718
@EventListener
1819
private static void fixToolMaterials(ItemRegistryEvent event) {
19-
ToolMaterial stone = ToolMaterial.STONE;
20-
ToolMaterial iron = ToolMaterial.IRON;
21-
ToolMaterial diamond = ToolMaterial.DIAMOND;
22-
stone.miningLevelTag(TagKey.of(BlockRegistry.KEY, of("needs_stone_tool")));
23-
iron.miningLevelTag(TagKey.of(BlockRegistry.KEY, of("needs_iron_tool")));
24-
diamond.miningLevelTag(TagKey.of(BlockRegistry.KEY, of("needs_diamond_tool")));
20+
MiningLevelManager.LevelNode stoneNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, of("needs_stone_tool")));
21+
MiningLevelManager.LevelNode ironNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, of("needs_iron_tool")));
22+
MiningLevelManager.LevelNode diamondNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, of("needs_diamond_tool")));
23+
MiningLevelManager.GRAPH.putEdge(stoneNode, ironNode);
24+
MiningLevelManager.GRAPH.putEdge(ironNode, diamondNode);
25+
MiningLevelManager.invalidateCache();
26+
ToolMaterial.STONE.miningLevelNode(stoneNode);
27+
ToolMaterial.IRON.miningLevelNode(ironNode);
28+
ToolMaterial.DIAMOND.miningLevelNode(diamondNode);
2529
}
2630
}
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"values": [
3-
"#needs_iron_tool",
43
"obsidian"
54
]
65
}

station-vanilla-fix-v0/src/main/resources/data/minecraft/stationapi/tags/blocks/needs_iron_tool.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"values": [
3-
"#needs_stone_tool",
43
"diamond_block",
54
"diamond_ore",
65
"gold_block",

0 commit comments

Comments
 (0)