ModificationStation / StationAPI

A general use API for Fabric Loader mods on legacy Minecraft versions.
85 stars 19 forks source link

Tool items update #109

Open mineLdiver opened 6 months ago

mineLdiver commented 6 months ago

Current StationAPI tool items system is convoluted and broken.

There aren't solid plans on how to reimplement the system.

Discussion is welcome.

mineLdiver commented 5 months ago

My proposed layout: image

The idea is that each level node is only aware of its predecessors and can have multiple of them.

In code, if tool material only specifies a numeric mining level, it'll stick to the default branch (vanilla + extended). If a level node is specified, it overrides the numeric mining level, binding the tool material to the appropriate place in the graph.

Any level node can be modified at any time to get more predecessors, including vanilla nodes.

Feedback is greatly appreciated.

mineLdiver commented 5 months ago
Draft implementation without extended levels ```java import java.util.Arrays; import java.util.HashSet; import java.util.Optional; import java.util.Set; public class Main { static MiningNode[] VANILLA_NODES = new MiningNode[4]; static { var base = new MiningNode(Optional.empty(), Set.of()); var stone = new MiningNode(Optional.of(new BlockTag("needs_stone_tool")), set(base)); var iron = new MiningNode(Optional.of(new BlockTag("needs_iron_tool")), set(stone)); var diamond = new MiningNode(Optional.of(new BlockTag("needs_diamond_tool")), set(iron)); VANILLA_NODES[0] = base; VANILLA_NODES[1] = stone; VANILLA_NODES[2] = iron; VANILLA_NODES[3] = diamond; } @SafeVarargs static Set set(T... elements) { return new HashSet<>(Arrays.asList(elements)); } public static void main(String[] args) { var myLevel1 = new MiningNode(Optional.of(new BlockTag("needs_my_tool_level_1")), set(VANILLA_NODES[1])); var myLevel2 = new MiningNode(Optional.of(new BlockTag("needs_my_tool_level_2")), set(myLevel1)); var myLevel3 = new MiningNode(Optional.of(new BlockTag("needs_my_tool_level_3")), set(myLevel2)); VANILLA_NODES[2].predecessors().add(myLevel3); System.out.println(VANILLA_NODES[1].contains(new BlockTag("needs_my_tool_level_2"))); System.out.println(VANILLA_NODES[2].contains(new BlockTag("needs_my_tool_level_2"))); } record ToolMaterial( int miningLevel, int itemDurability, float miningSpeed, int attackDamage, Optional miningNode ) { MiningNode getNode() { return miningNode.orElseGet(() -> VANILLA_NODES[miningLevel]); } } record MiningNode( Optional tag, Set predecessors ) { boolean contains(BlockTag otherTag) { return (tag.isPresent() && tag.get().equals(otherTag)) || predecessors.stream().anyMatch(predecessor -> predecessor.contains(otherTag)); } } record BlockTag(String id) {} } ```
mineLdiver commented 5 months ago

Actual implementation turned out to be way easier thanks to tags that basically replace the MiningNode and all related logic.

Implementation is being worked on at https://github.com/ModificationStation/StationAPI/tree/2.0-alpha.3