diff --git a/build.gradle.kts b/build.gradle.kts index ed375204e..904bf6d94 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -91,7 +91,7 @@ allprojects { // adds some useful annotations for miscellaneous uses. does not add any dependencies, though people without the lib will be missing some useful context hints. "implementationOnly"("org.jetbrains:annotations:23.0.0") - modLocalRuntime("com.github.calmilamsy:ModMenu:${project.properties["modmenu_version"]}") { + modLocalRuntime("net.glasslauncher.mods:ModMenu:${project.properties["modmenu_version"]}") { isTransitive = false } diff --git a/gradle.properties b/gradle.properties index ae77df92b..4ba705338 100644 --- a/gradle.properties +++ b/gradle.properties @@ -35,5 +35,5 @@ fabric.loom.multiProjectOptimisation=true # Test properties gcapi_version = 1.3.1 hmi_version = 5.1.1 - modmenu_version = v1.8.5-beta.3 + modmenu_version = 1.8.5-beta.9 mojangfix_version = 0.5.2 \ No newline at end of file diff --git a/src/test/java/net/modificationstation/sltest/block/Blocks.java b/src/test/java/net/modificationstation/sltest/block/Blocks.java index a378b1806..5385bf4f2 100644 --- a/src/test/java/net/modificationstation/sltest/block/Blocks.java +++ b/src/test/java/net/modificationstation/sltest/block/Blocks.java @@ -16,7 +16,7 @@ public enum Blocks { - TEST_BLOCK("test_block", "testBlock", id -> new TemplateBlock(id, Material.CLAY).setHardness(1)), + TEST_BLOCK("test_block", "testBlock", id -> new TemplateBlock(id, Material.STONE).setHardness(1)), TEST_ANIMATED_BLOCK("test_animated_block", "testAnimatedBlock", id -> new ModdedMetaBlock(id, Material.NETHER_PORTAL)), CUSTOM_MODEL_BLOCK("farlands_block", "farlands_block", id -> new ModdedModelBlock(id, Material.SOIL).setHardness(1)), FREEZER("freezer", "freezer", id -> new BlockFreezer(id).setHardness(2.5F).setSoundGroup(TemplateBlock.DEFAULT_SOUND_GROUP)), diff --git a/src/test/java/net/modificationstation/sltest/gui/hud/TestHudText.java b/src/test/java/net/modificationstation/sltest/gui/hud/TestHudText.java new file mode 100644 index 000000000..7d56c2f77 --- /dev/null +++ b/src/test/java/net/modificationstation/sltest/gui/hud/TestHudText.java @@ -0,0 +1,33 @@ +package net.modificationstation.sltest.gui.hud; + +import net.mine_diver.unsafeevents.listener.EventListener; +import net.modificationstation.stationapi.api.client.event.gui.hud.HudTextLine; +import net.modificationstation.stationapi.api.client.event.gui.hud.HudTextRenderEvent; + +import java.util.Random; + +public class TestHudText { + private static final int[] COLORS = {0x5BCEFA, 0xF5A9B8, 0xFFFFFF, 0xF5A9B8}; + private final Random random = new Random(); + private int frames; + private int color; + private int verColor; + + @EventListener + public void renderHudText(HudTextRenderEvent event) { + if (frames % 7 == 0) verColor = random.nextInt(0xFFFFFF + 1); + event.setVersion(new HudTextLine( + "Statint api 2rd ediction ;)" + (event.debug ? "(" + event.minecraft.debugText + ")" : ""), + verColor) + ); + if (frames > 0 && frames % 15 == 0) { + color = color + 1 < COLORS.length? color + 1 : 0; + } + event.right.add(new HudTextLine("gaming", COLORS[color])); + if (event.debug) { + event.left.add(new HudTextLine("This Texts only Shows In de Bugge ?!??! :0")); + event.right.add(new HudTextLine("this text has a rly big offsets", 0xFF0000, 40)); + } + frames++; + } +} diff --git a/src/test/java/net/modificationstation/sltest/item/ItemListener.java b/src/test/java/net/modificationstation/sltest/item/ItemListener.java index ee725ed40..89a2a712d 100644 --- a/src/test/java/net/modificationstation/sltest/item/ItemListener.java +++ b/src/test/java/net/modificationstation/sltest/item/ItemListener.java @@ -6,9 +6,12 @@ import net.modificationstation.sltest.block.Blocks; import net.modificationstation.sltest.block.VariationBlock; import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent; +import net.modificationstation.stationapi.api.item.tool.MiningLevelManager; import net.modificationstation.stationapi.api.item.tool.ToolMaterialFactory; +import net.modificationstation.stationapi.api.registry.BlockRegistry; import net.modificationstation.stationapi.api.registry.ItemRegistry; import net.modificationstation.stationapi.api.registry.Registry; +import net.modificationstation.stationapi.api.tag.TagKey; import net.modificationstation.stationapi.api.template.item.BlockStateItem; import static net.modificationstation.sltest.SLTest.NAMESPACE; @@ -17,8 +20,13 @@ public class ItemListener { @EventListener public void registerItems(ItemRegistryEvent event) { + MiningLevelManager.LevelNode moddedNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, NAMESPACE.id("needs_tool_level_modded"))); + MiningLevelManager.GRAPH.putEdge(ToolMaterial.STONE.getMiningLevelNode(), moddedNode); + MiningLevelManager.GRAPH.putEdge(moddedNode, ToolMaterial.IRON.getMiningLevelNode()); + MiningLevelManager.invalidateCache(); + testItem = new ModdedItem(NAMESPACE.id("test_item")).setTranslationKey(NAMESPACE, "testItem"); //8475 - testMaterial = ToolMaterialFactory.create("testMaterial", 3, Integer.MAX_VALUE, Float.MAX_VALUE, Integer.MAX_VALUE - 2); + testMaterial = ToolMaterialFactory.create("testMaterial", 3, Integer.MAX_VALUE, Float.MAX_VALUE, Integer.MAX_VALUE - 2).miningLevelNode(moddedNode); testPickaxe = new ModdedPickaxeItem(NAMESPACE.id("test_pickaxe"), testMaterial).setTranslationKey(NAMESPACE, "testPickaxe"); //8476 testNBTItem = new NBTItem(NAMESPACE.id("nbt_item")).setTranslationKey(NAMESPACE, "nbt_item"); //8477 testModelItem = new ModelItem(NAMESPACE.id("model_item")).setMaxCount(1).setTranslationKey(NAMESPACE, "idkSomething"); @@ -30,6 +38,8 @@ public void registerItems(ItemRegistryEvent event) { testShears = new TestShearsItem(NAMESPACE.id("test_shears")).setTranslationKey(NAMESPACE, "test_shears"); pacifistSword = new PacifistSwordItem(NAMESPACE.id("pacifist_sword")).setTranslationKey(NAMESPACE, "pacifist_sword"); dullPickaxe = new DullPickaxeItem(NAMESPACE.id("dull_pickaxe")).setTranslationKey(NAMESPACE, "dull_pickaxe"); + + } public static Item testItem; diff --git a/src/test/resources/data/minecraft/stationapi/tags/blocks/mineable/pickaxe.json b/src/test/resources/data/minecraft/stationapi/tags/blocks/mineable/pickaxe.json new file mode 100644 index 000000000..04f9bde83 --- /dev/null +++ b/src/test/resources/data/minecraft/stationapi/tags/blocks/mineable/pickaxe.json @@ -0,0 +1,5 @@ +{ + "values": [ + "sltest:test_block" + ] +} \ No newline at end of file diff --git a/src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json b/src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json new file mode 100644 index 000000000..04f9bde83 --- /dev/null +++ b/src/test/resources/data/sltest/stationapi/tags/blocks/needs_tool_level_modded.json @@ -0,0 +1,5 @@ +{ + "values": [ + "sltest:test_block" + ] +} \ No newline at end of file diff --git a/src/test/resources/fabric.mod.json b/src/test/resources/fabric.mod.json index 3ef1d5b6f..ffedfc5a7 100644 --- a/src/test/resources/fabric.mod.json +++ b/src/test/resources/fabric.mod.json @@ -33,7 +33,8 @@ "net.modificationstation.sltest.datafixer.DataFixerListener", "net.modificationstation.sltest.worldgen.TestWorldgenListener", "net.modificationstation.sltest.bonemeal.BonemealListener", - "net.modificationstation.sltest.dispenser.DispenserListener" + "net.modificationstation.sltest.dispenser.DispenserListener", + "net.modificationstation.sltest.gui.hud.TestHudText" ], "stationapi:event_bus_client": [ "net.modificationstation.sltest.gui.GuiListener", diff --git a/station-flattening-v0/build.gradle.kts b/station-flattening-v0/build.gradle.kts index 07cbbd120..17257068b 100644 --- a/station-flattening-v0/build.gradle.kts +++ b/station-flattening-v0/build.gradle.kts @@ -5,6 +5,7 @@ version = getSubprojectVersion(project, "1.0.0") addModuleDependencies(project, "station-api-base", + "station-gui-api-v0", "station-maths-v0", "station-registry-api-v0", "station-networking-v0", diff --git a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/hud/StationFlatteningHudText.java b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/hud/StationFlatteningHudText.java new file mode 100644 index 000000000..039459485 --- /dev/null +++ b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/hud/StationFlatteningHudText.java @@ -0,0 +1,59 @@ +package net.modificationstation.stationapi.impl.client.gui.hud; + +import net.fabricmc.loader.api.FabricLoader; +import net.mine_diver.unsafeevents.listener.EventListener; +import net.minecraft.block.Block; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.hit.HitResultType; +import net.modificationstation.stationapi.api.StationAPI; +import net.modificationstation.stationapi.api.block.BlockState; +import net.modificationstation.stationapi.api.client.event.gui.hud.HudTextRenderEvent; +import net.modificationstation.stationapi.api.client.event.gui.hud.HudTextLine; +import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint; +import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy; +import net.modificationstation.stationapi.api.state.property.Property; +import net.modificationstation.stationapi.api.tag.TagKey; + +import java.util.Collection; +import java.util.Collections; + +import static net.modificationstation.stationapi.api.client.event.gui.hud.HudTextLine.GRAY; +import static net.modificationstation.stationapi.api.client.event.gui.hud.HudTextLine.WHITE; + +@Entrypoint(eventBus = @EventBusPolicy(registerInstance = false)) +public class StationFlatteningHudText { + @EventListener(phase = StationAPI.INTERNAL_PHASE) + private static void renderHudText(HudTextRenderEvent event) { + if (!event.debug) return; + HitResult hit = event.minecraft.field_2823; + if (hit == null || hit.type != HitResultType.BLOCK) return; + BlockState state = event.minecraft.world.getBlockState(hit.blockX, hit.blockY, hit.blockZ); + Collections.addAll(event.right, + new HudTextLine("Block: " + state.getBlock().getTranslatedName(), WHITE, 20), + new HudTextLine("Meta: " + event.minecraft.world.getBlockMeta(hit.blockX, hit.blockY, hit.blockZ)) + ); + Collection> properties = state.getProperties(); + if (!properties.isEmpty()) { + event.right.add(new HudTextLine("Properties:")); + event.right.addAll(properties.stream().map(prop -> + new HudTextLine(prop.getName() + ": " + state.get(prop), GRAY) + ).toList()); + } + + Collection> tags = state.streamTags().toList(); + if (!tags.isEmpty()) { + event.right.add(new HudTextLine("Tags:")); + event.right.addAll(tags.stream().map(tag -> new HudTextLine("#" + tag.id(), GRAY)).toList()); + } + + if (FabricLoader.getInstance().isDevelopmentEnvironment()) { + BlockEntity entity = event.minecraft.world.method_1777(hit.blockX, hit.blockY, hit.blockZ); + if (entity != null) { + String className = entity.getClass().getName(); + String text = "Tile Entity: " + className.substring(className.lastIndexOf('.') + 1); + event.right.add(new HudTextLine(text, WHITE, 20)); + } + } + } +} diff --git a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/client/InGameHudMixin.java b/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/client/InGameHudMixin.java deleted file mode 100644 index f4153e33f..000000000 --- a/station-flattening-v0/src/main/java/net/modificationstation/stationapi/mixin/flattening/client/InGameHudMixin.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.modificationstation.stationapi.mixin.flattening.client; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.block.Block; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.class_564; -import net.minecraft.client.Minecraft; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.util.hit.HitResult; -import net.minecraft.util.hit.HitResultType; -import net.modificationstation.stationapi.api.block.BlockState; -import net.modificationstation.stationapi.api.state.property.Property; -import net.modificationstation.stationapi.api.tag.TagKey; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.At.Shift; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.Collection; - -@Mixin(InGameHud.class) -abstract class InGameHudMixin extends DrawContext { - @Shadow private Minecraft minecraft; - - @Inject( - method = "render", - at = @At( - value = "INVOKE", - target = "Ljava/lang/Runtime;maxMemory()J", - shift = Shift.BEFORE - ), - locals = LocalCapture.CAPTURE_FAILSOFT - ) - private void stationapi_renderHud(float bl, boolean i, int j, int par4, CallbackInfo ci, class_564 scaler, int var6, int var7, TextRenderer var8) { - HitResult hit = minecraft.field_2823; - int offset = 22; - if (hit != null && hit.type == HitResultType.BLOCK) { - BlockState state = minecraft.world.getBlockState(hit.blockX, hit.blockY, hit.blockZ); - - String text = "Block: " + state.getBlock().getTranslatedName(); - drawTextWithShadow(var8, text, var6 - var8.getWidth(text) - 2, offset += 10, 16777215); - - text = "Meta: " + minecraft.world.getBlockMeta(hit.blockX, hit.blockY, hit.blockZ); - drawTextWithShadow(var8, text, var6 - var8.getWidth(text) - 2, offset += 10, 16777215); - - Collection> properties = state.getProperties(); - if (!properties.isEmpty()) { - text = "Properties:"; - drawTextWithShadow(var8, text, var6 - var8.getWidth(text) - 2, offset += 10, 16777215); - - for (Property property : properties) { - text = property.getName() + ": " + state.get(property); - drawTextWithShadow(var8, text, var6 - var8.getWidth(text) - 2, offset += 10, 14737632); - } - } - - Collection> tags = state.streamTags().toList(); - if (!tags.isEmpty()) { - text = "Tags:"; - drawTextWithShadow(var8, text, var6 - var8.getWidth(text) - 2, offset += 10, 16777215); - - for (TagKey property : tags) { - text = "#" + property.id(); - drawTextWithShadow(var8, text, var6 - var8.getWidth(text) - 2, offset += 10, 14737632); - } - } - - if (FabricLoader.getInstance().isDevelopmentEnvironment()) { - BlockEntity entity = minecraft.world.method_1777(hit.blockX, hit.blockY, hit.blockZ); - if (entity != null) { - String className = entity.getClass().getName(); - text = "Tile Entity: " + className.substring(className.lastIndexOf('.') + 1); - drawTextWithShadow(var8, text, var6 - var8.getWidth(text) - 2, offset + 20, 16777215); - } - } - } - } -} diff --git a/station-flattening-v0/src/main/resources/fabric.mod.json b/station-flattening-v0/src/main/resources/fabric.mod.json index 73e6844e1..429265ecd 100644 --- a/station-flattening-v0/src/main/resources/fabric.mod.json +++ b/station-flattening-v0/src/main/resources/fabric.mod.json @@ -23,7 +23,8 @@ "net.modificationstation.stationapi.api.block.States", "net.modificationstation.stationapi.impl.block.PlacementStateImpl", "net.modificationstation.stationapi.impl.world.WorldDataVersionImpl", - "net.modificationstation.stationapi.impl.block.BlockInteractionImpl" + "net.modificationstation.stationapi.impl.block.BlockInteractionImpl", + "net.modificationstation.stationapi.impl.client.gui.hud.StationFlatteningHudText" ], "main": [ "net.modificationstation.stationapi.impl.packet.StationFlatteningNetworkingImpl" diff --git a/station-flattening-v0/src/main/resources/station-flattening-v0.mixins.json b/station-flattening-v0/src/main/resources/station-flattening-v0.mixins.json index 591676dde..588b73385 100644 --- a/station-flattening-v0/src/main/resources/station-flattening-v0.mixins.json +++ b/station-flattening-v0/src/main/resources/station-flattening-v0.mixins.json @@ -36,7 +36,6 @@ "client": [ "client.BlockRenderManagerMixin", "client.ClientWorldMixin", - "client.InGameHudMixin", "client.InteractionManagerMixin", "client.MinecraftMixin", "client.MultiplayerChunkCacheMixin", diff --git a/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/api/client/event/gui/hud/HudTextLine.java b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/api/client/event/gui/hud/HudTextLine.java new file mode 100644 index 000000000..93dc5236d --- /dev/null +++ b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/api/client/event/gui/hud/HudTextLine.java @@ -0,0 +1,29 @@ +package net.modificationstation.stationapi.api.client.event.gui.hud; + +import lombok.AllArgsConstructor; + +/** + * Text and info for rendering custom HUD text lines. + */ +@AllArgsConstructor +public final class HudTextLine { + public static final int WHITE = 0xFFFFFF; + public static final int GRAY = 0xE0E0E0; + + public String text; + /** + * @see net.glasslauncher.mods.api.gcapi.api.CharacterUtils#getIntFromColour(Color) + */ + public int color; + /** + * Y offset from the last rendered line. + */ + public int yOffset; + + public HudTextLine(String text) { + this(text, WHITE); + } + public HudTextLine(String text, int color) { + this(text, color, 10); + } +} diff --git a/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/api/client/event/gui/hud/HudTextRenderEvent.java b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/api/client/event/gui/hud/HudTextRenderEvent.java new file mode 100644 index 000000000..ad4eb5967 --- /dev/null +++ b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/api/client/event/gui/hud/HudTextRenderEvent.java @@ -0,0 +1,34 @@ +package net.modificationstation.stationapi.api.client.event.gui.hud; + +import lombok.Getter; +import lombok.experimental.SuperBuilder; +import net.mine_diver.unsafeevents.Event; +import net.mine_diver.unsafeevents.event.EventPhases; +import net.minecraft.client.Minecraft; +import net.modificationstation.stationapi.api.StationAPI; + +import java.util.ArrayList; +import java.util.List; + +/** + * Fires while rendering in-game (debug) HUD text. + */ +@SuperBuilder +@EventPhases({StationAPI.INTERNAL_PHASE, EventPhases.DEFAULT_PHASE}) +public class HudTextRenderEvent extends Event { + /** + * Whether the F3 debug HUD is enabled. + * @see net.minecraft.client.option.GameOptions#debugHud + */ + public final boolean debug; + public final Minecraft minecraft; + public final List left = new ArrayList<>(), right = new ArrayList<>(); + @Getter private HudTextLine version; + + /** + * Set by highest priority listener. + */ + public void setVersion(HudTextLine line) { + if (version == null) version = line; + } +} diff --git a/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/hud/StationVanillaHudText.java b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/hud/StationVanillaHudText.java new file mode 100644 index 000000000..7937d556b --- /dev/null +++ b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/hud/StationVanillaHudText.java @@ -0,0 +1,55 @@ +package net.modificationstation.stationapi.impl.client.gui.hud; + +import net.mine_diver.unsafeevents.listener.EventListener; +import net.mine_diver.unsafeevents.listener.ListenerPriority; +import net.minecraft.util.math.MathHelper; +import net.modificationstation.stationapi.api.StationAPI; +import net.modificationstation.stationapi.api.client.event.gui.hud.HudTextRenderEvent; +import net.modificationstation.stationapi.api.client.event.gui.hud.HudTextLine; +import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint; +import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy; + +import static net.modificationstation.stationapi.api.client.event.gui.hud.HudTextLine.GRAY; + +import java.util.Collections; + +@Entrypoint(eventBus = @EventBusPolicy(registerInstance = false)) +public class StationVanillaHudText { + @EventListener(phase = StationAPI.INTERNAL_PHASE, priority = ListenerPriority.HIGHEST) + private static void renderVanillaDebugText(HudTextRenderEvent event) { + if (!event.debug) return; + Collections.addAll(event.left, + new HudTextLine(event.minecraft.method_2141()), + new HudTextLine(event.minecraft.method_2142()), + new HudTextLine(event.minecraft.method_2144()), + new HudTextLine(event.minecraft.method_2143()), + new HudTextLine("x: " + event.minecraft.player.x, GRAY, 22), + new HudTextLine("y: " + event.minecraft.player.y, GRAY, 8), + new HudTextLine("z: " + event.minecraft.player.y, GRAY, 8), + new HudTextLine( + "f: " + (MathHelper.floor((double)(event.minecraft.player.yaw * 4.0F / 360.0F) + 0.5) & 3), + GRAY, 8 + ) + ); + long max = Runtime.getRuntime().maxMemory(); + long total = Runtime.getRuntime().totalMemory(); + long free = Runtime.getRuntime().freeMemory(); + long used = total - free; + Collections.addAll(event.right, + new HudTextLine( + "Used memory: " + used * 100L / max + "% (" + used / 1024L / 1024L + "MB) of " + + max / 1024L / 1024L + "MB", GRAY + ), + new HudTextLine( + "Allocated memory: " + total * 100L / max + "% (" + total / 1024L / 1024L + "MB)", GRAY + ) + ); + } + + // lowest default priority so other mods can overwrite it + @EventListener(priority = ListenerPriority.LOWEST) + private static void renderVanillaVersionText(HudTextRenderEvent event) { + if (!event.debug) return; + event.setVersion(new HudTextLine("Minecraft Beta 1.7.3 (" + event.minecraft.debugText + ")")); + } +} diff --git a/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/EditWorldScreenImpl.java b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/EditWorldScreenImpl.java index 4840b3561..01aa445cf 100644 --- a/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/EditWorldScreenImpl.java +++ b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/screen/EditWorldScreenImpl.java @@ -9,7 +9,7 @@ import net.modificationstation.stationapi.api.client.gui.widget.ButtonWidgetDetachedContext; import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint; import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy; -import net.modificationstation.stationapi.mixin.gui.client.ScreenAccessor; +import net.modificationstation.stationapi.mixin.client.gui.ScreenAccessor; @Entrypoint(eventBus = @EventBusPolicy(registerInstance = false)) @EventListener(phase = StationAPI.INTERNAL_PHASE) diff --git a/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/gui/client/ScreenAccessor.java b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/client/gui/ScreenAccessor.java similarity index 82% rename from station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/gui/client/ScreenAccessor.java rename to station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/client/gui/ScreenAccessor.java index b225fb211..0dc050149 100644 --- a/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/gui/client/ScreenAccessor.java +++ b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/client/gui/ScreenAccessor.java @@ -1,4 +1,4 @@ -package net.modificationstation.stationapi.mixin.gui.client; +package net.modificationstation.stationapi.mixin.client.gui; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screen.Screen; diff --git a/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/gui/client/SelectWorldScreenMixin.java b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/client/gui/SelectWorldScreenMixin.java similarity index 96% rename from station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/gui/client/SelectWorldScreenMixin.java rename to station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/client/gui/SelectWorldScreenMixin.java index d065dace7..686b0ab3e 100644 --- a/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/gui/client/SelectWorldScreenMixin.java +++ b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/client/gui/SelectWorldScreenMixin.java @@ -1,4 +1,4 @@ -package net.modificationstation.stationapi.mixin.gui.client; +package net.modificationstation.stationapi.mixin.client.gui; import net.minecraft.class_591; import net.minecraft.client.gui.screen.Screen; diff --git a/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/client/gui/hud/InGameHudMixin.java b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/client/gui/hud/InGameHudMixin.java new file mode 100644 index 000000000..66f34681f --- /dev/null +++ b/station-gui-api-v0/src/main/java/net/modificationstation/stationapi/mixin/client/gui/hud/InGameHudMixin.java @@ -0,0 +1,55 @@ +package net.modificationstation.stationapi.mixin.client.gui.hud; + +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.class_564; +import net.minecraft.client.Minecraft; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.option.GameOptions; +import net.modificationstation.stationapi.api.client.event.gui.hud.*; +import org.lwjgl.opengl.GL11; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import static net.modificationstation.stationapi.api.StationAPI.EVENT_BUS; + + +@Mixin(InGameHud.class) +abstract class InGameHudMixin extends DrawContext { + @Shadow private Minecraft minecraft; + + @Redirect( + method = "render", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/client/option/GameOptions;debugHud:Z", + ordinal = 0, + opcode = Opcodes.GETFIELD + ) + ) + private boolean stationapi_renderText(GameOptions options, @Local TextRenderer tr, @Local class_564 scaler) { + GL11.glPushMatrix(); + if (Minecraft.failedSessionCheckTime > 0L) { + GL11.glTranslatef(0.0F, 32.0F, 0.0F); + } + var event = EVENT_BUS.post(HudTextRenderEvent.builder().debug(options.debugHud).minecraft(minecraft).build()); + var version = event.getVersion(); + if (version != null) tr.drawWithShadow(version.text, 2, 2, version.color); + for (int i = 0, y = 2; i < event.left.size(); i++) { + var line = event.left.get(i); + if (i > 0 || version != null) y += line.yOffset; + tr.drawWithShadow(line.text, 2, y, line.color); + } + for (int i = 0, y = 2; i < event.right.size(); i++) { + var line = event.right.get(i); + if (i > 0) y += line.yOffset; + tr.drawWithShadow(line.text, scaler.method_1857() - tr.getWidth(line.text) - 2, y, line.color); + } + GL11.glPopMatrix(); + return false; + } +} diff --git a/station-gui-api-v0/src/main/resources/fabric.mod.json b/station-gui-api-v0/src/main/resources/fabric.mod.json index 6ae043ae3..ba16d255f 100644 --- a/station-gui-api-v0/src/main/resources/fabric.mod.json +++ b/station-gui-api-v0/src/main/resources/fabric.mod.json @@ -20,7 +20,8 @@ "environment": "client", "entrypoints": { "stationapi:event_bus_client": [ - "net.modificationstation.stationapi.impl.client.gui.screen.EditWorldScreenImpl" + "net.modificationstation.stationapi.impl.client.gui.screen.EditWorldScreenImpl", + "net.modificationstation.stationapi.impl.client.gui.hud.StationVanillaHudText" ] }, "mixins": [ diff --git a/station-gui-api-v0/src/main/resources/station-gui-api-v0.mixins.json b/station-gui-api-v0/src/main/resources/station-gui-api-v0.mixins.json index 10e7e8bcf..83312842f 100644 --- a/station-gui-api-v0/src/main/resources/station-gui-api-v0.mixins.json +++ b/station-gui-api-v0/src/main/resources/station-gui-api-v0.mixins.json @@ -1,13 +1,14 @@ { "required": true, "minVersion": "0.8", - "package": "net.modificationstation.stationapi.mixin.gui", + "package": "net.modificationstation.stationapi.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ ], "client": [ - "client.ScreenAccessor", - "client.SelectWorldScreenMixin" + "client.gui.ScreenAccessor", + "client.gui.SelectWorldScreenMixin", + "client.gui.hud.InGameHudMixin" ], "injectors": { "defaultRequire": 1 diff --git a/station-lifecycle-events-v0/src/main/resources/station-lifecycle-events-v0.mixins.json b/station-lifecycle-events-v0/src/main/resources/station-lifecycle-events-v0.mixins.json index bdfda5905..93d37150f 100644 --- a/station-lifecycle-events-v0/src/main/resources/station-lifecycle-events-v0.mixins.json +++ b/station-lifecycle-events-v0/src/main/resources/station-lifecycle-events-v0.mixins.json @@ -3,12 +3,10 @@ "minVersion": "0.8", "package": "net.modificationstation.stationapi.mixin.lifecycle", "compatibilityLevel": "JAVA_17", - "mixins": [ - "server.ServerPlayNetworkHandlerMixin" - ], "server": [ "server.MinecraftServerMixin", - "server.ServerLoginNetworkHandlerMixin" + "server.ServerLoginNetworkHandlerMixin", + "server.ServerPlayNetworkHandlerMixin" ], "client": [ "client.ClientNetworkHandlerMixin", diff --git a/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/event/registry/RegistriesFrozenEvent.java b/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/event/registry/RegistriesFrozenEvent.java new file mode 100644 index 000000000..d9a13dcd5 --- /dev/null +++ b/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/event/registry/RegistriesFrozenEvent.java @@ -0,0 +1,16 @@ +package net.modificationstation.stationapi.api.event.registry; + +import net.mine_diver.unsafeevents.Event; +import net.mine_diver.unsafeevents.event.EventPhases; +import net.modificationstation.stationapi.api.StationAPI; + +/** + * This is the last init event called by StAPI. + * Called after registries are frozen. + * {@link net.modificationstation.stationapi.mixin.registry.client.MinecraftMixin} + */ +@SuppressWarnings("JavadocReference") // Shut, I know. +@EventPhases(StationAPI.INTERNAL_PHASE) +public class RegistriesFrozenEvent extends Event { + +} diff --git a/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/mixin/registry/client/MinecraftMixin.java b/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/mixin/registry/client/MinecraftMixin.java index e31a1526f..4bb983462 100644 --- a/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/mixin/registry/client/MinecraftMixin.java +++ b/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/mixin/registry/client/MinecraftMixin.java @@ -1,6 +1,8 @@ package net.modificationstation.stationapi.mixin.registry.client; import net.minecraft.client.Minecraft; +import net.modificationstation.stationapi.api.StationAPI; +import net.modificationstation.stationapi.api.event.registry.RegistriesFrozenEvent; import net.modificationstation.stationapi.api.registry.Registries; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -16,5 +18,6 @@ class MinecraftMixin { ) private void stationapi_freeze(CallbackInfo ci) { Registries.bootstrap(); + StationAPI.EVENT_BUS.post(new RegistriesFrozenEvent()); } } diff --git a/station-renderer-api-v0/build.gradle.kts b/station-renderer-api-v0/build.gradle.kts index 632b75bd9..0148ddbba 100644 --- a/station-renderer-api-v0/build.gradle.kts +++ b/station-renderer-api-v0/build.gradle.kts @@ -8,6 +8,7 @@ addModuleDependencies(project, "station-maths-v0", "station-blocks-v0", "station-items-v0", + "station-gui-api-v0", "station-registry-api-v0", "station-lifecycle-events-v0", "station-flattening-v0", diff --git a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/hud/StationRendererHudText.java b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/hud/StationRendererHudText.java new file mode 100644 index 000000000..b88732f54 --- /dev/null +++ b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/gui/hud/StationRendererHudText.java @@ -0,0 +1,21 @@ +package net.modificationstation.stationapi.impl.client.gui.hud; + +import net.mine_diver.unsafeevents.listener.EventListener; +import net.modificationstation.stationapi.api.StationAPI; +import net.modificationstation.stationapi.api.client.event.gui.hud.HudTextRenderEvent; +import net.modificationstation.stationapi.api.client.event.gui.hud.HudTextLine; +import net.modificationstation.stationapi.api.client.render.RendererAccess; +import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint; +import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy; + +import java.util.Objects; + +@Entrypoint(eventBus = @EventBusPolicy(registerInstance = false)) +public class StationRendererHudText { + @EventListener(phase = StationAPI.INTERNAL_PHASE) + private static void renderHudText(HudTextRenderEvent event) { + if (!event.debug) return; + event.left.add(new HudTextLine("Active renderer: " + (RendererAccess.INSTANCE.hasRenderer() ? + Objects.requireNonNull(RendererAccess.INSTANCE.getRenderer()).getClass().getSimpleName() : "none (vanilla)"))); + } +} diff --git a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/mixin/render/client/InGameHudMixin.java b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/mixin/render/client/InGameHudMixin.java deleted file mode 100644 index 89d07cb74..000000000 --- a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/mixin/render/client/InGameHudMixin.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.modificationstation.stationapi.mixin.render.client; - -import net.minecraft.class_564; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.modificationstation.stationapi.api.client.render.RendererAccess; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.Objects; - -import static net.modificationstation.stationapi.api.StationAPI.NAMESPACE; - -@Mixin(InGameHud.class) -class InGameHudMixin extends DrawContext { - @Inject( - method = "render", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/font/TextRenderer;drawWithShadow(Ljava/lang/String;III)V", - ordinal = 5, - shift = At.Shift.AFTER - ), - locals = LocalCapture.CAPTURE_FAILHARD - ) - private void stationapi_showCurrentRenderer(float flag, boolean i, int j, int par4, CallbackInfo ci, class_564 var5, int var6, int var7, TextRenderer textRenderer) { - drawTextWithShadow(textRenderer, "[" + NAMESPACE.getName() + "] Active renderer: " + (RendererAccess.INSTANCE.hasRenderer() ? Objects.requireNonNull(RendererAccess.INSTANCE.getRenderer()).getClass().getSimpleName() : "none (vanilla)"), 2, 98, 14737632); - } -} diff --git a/station-renderer-api-v0/src/main/resources/fabric.mod.json b/station-renderer-api-v0/src/main/resources/fabric.mod.json index 0da340298..8c5a87b27 100644 --- a/station-renderer-api-v0/src/main/resources/fabric.mod.json +++ b/station-renderer-api-v0/src/main/resources/fabric.mod.json @@ -20,7 +20,8 @@ "environment": "client", "entrypoints": { "stationapi:event_bus_client": [ - "net.modificationstation.stationapi.impl.client.texture.StationRenderImpl" + "net.modificationstation.stationapi.impl.client.texture.StationRenderImpl", + "net.modificationstation.stationapi.impl.client.gui.hud.StationRendererHudText" ] }, "mixins": [ diff --git a/station-renderer-api-v0/src/main/resources/station-renderer-api-v0.mixins.json b/station-renderer-api-v0/src/main/resources/station-renderer-api-v0.mixins.json index fc01473dc..0c29027e8 100644 --- a/station-renderer-api-v0/src/main/resources/station-renderer-api-v0.mixins.json +++ b/station-renderer-api-v0/src/main/resources/station-renderer-api-v0.mixins.json @@ -11,7 +11,6 @@ "client": [ "client.BlockRenderManagerAccessor", "client.BlockRenderManagerMixin", - "client.InGameHudMixin", "client.TessellatorAccessor", "client.TessellatorMixin", "client.TextureManagerAccessor", diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/MiningLevelManager.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/MiningLevelManager.java new file mode 100644 index 000000000..205f3b7db --- /dev/null +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/MiningLevelManager.java @@ -0,0 +1,33 @@ +package net.modificationstation.stationapi.api.item.tool; + +import com.google.common.graph.GraphBuilder; +import com.google.common.graph.MutableGraph; +import it.unimi.dsi.fastutil.objects.Object2BooleanMap; +import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; +import lombok.val; +import net.minecraft.block.Block; +import net.modificationstation.stationapi.api.block.BlockState; +import net.modificationstation.stationapi.api.tag.TagKey; + +import java.util.stream.Collectors; + +public final class MiningLevelManager { + public record LevelNode(TagKey blockTag) {} + private record CacheKey(LevelNode levelNode, BlockState state) {} + + public static final MutableGraph GRAPH = GraphBuilder.directed().build(); + private static final Object2BooleanMap CACHE = new Object2BooleanOpenHashMap<>(); + + public static boolean isSuitable(LevelNode levelNode, BlockState state) { + return CACHE.computeIfAbsent(new CacheKey(levelNode, state), (CacheKey key) -> { + val nodes = GRAPH.nodes().stream().filter(node -> key.state.isIn(node.blockTag)).collect(Collectors.toSet()); + if (nodes.isEmpty()) return true; + val pred = GRAPH.predecessors(key.levelNode); + return nodes.stream().anyMatch(node -> key.levelNode.equals(node) || pred.contains(node)); + }); + } + + public static void invalidateCache() { + CACHE.clear(); + } +} diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationHoeItem.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationHoeItem.java index 5f6ca48dc..9115fe99e 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationHoeItem.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationHoeItem.java @@ -7,7 +7,6 @@ import net.modificationstation.stationapi.api.util.Util; public interface StationHoeItem extends ToolLevel { - @Override default void setEffectiveBlocks(TagKey effectiveBlocks) { Util.assertImpl(); diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationShearsItem.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationShearsItem.java index f0d24982d..b6904d204 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationShearsItem.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationShearsItem.java @@ -7,7 +7,6 @@ import net.modificationstation.stationapi.api.util.Util; public interface StationShearsItem extends ToolLevel { - @Override default void setEffectiveBlocks(TagKey effectiveBlocks) { Util.assertImpl(); diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationSwordItem.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationSwordItem.java index 2cac4fec5..0f648e8d9 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationSwordItem.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationSwordItem.java @@ -7,7 +7,6 @@ import net.modificationstation.stationapi.api.util.Util; public interface StationSwordItem extends ToolLevel { - @Override default void setEffectiveBlocks(TagKey effectiveBlocks) { Util.assertImpl(); diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolItem.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolItem.java index 57998fd5a..f23cdbc75 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolItem.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolItem.java @@ -7,7 +7,6 @@ import net.modificationstation.stationapi.api.util.Util; public interface StationToolItem extends ToolLevel { - @Override default void setEffectiveBlocks(TagKey effectiveBlocks) { Util.assertImpl(); diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java index b9676af8a..a8aa7d932 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationToolMaterial.java @@ -1,48 +1,14 @@ package net.modificationstation.stationapi.api.item.tool; -import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -import it.unimi.dsi.fastutil.objects.ReferenceSet; -import net.minecraft.block.Block; import net.minecraft.item.ToolMaterial; -import net.modificationstation.stationapi.api.block.BlockState; -import net.modificationstation.stationapi.api.util.Identifier; -import net.modificationstation.stationapi.api.tag.TagKey; import net.modificationstation.stationapi.api.util.Util; -import java.util.function.BiPredicate; -import java.util.function.Predicate; - public interface StationToolMaterial { - - ReferenceSet> ALL_TOOL_MATERIAL_TAGS = new ReferenceOpenHashSet<>(); - - default ToolMaterial inheritsFrom(ToolMaterial... toolMaterials) { + default ToolMaterial miningLevelNode(MiningLevelManager.LevelNode levelNode) { return Util.assertImpl(); } - default ToolMaterial requiredBlockTag(Identifier tag) { + default MiningLevelManager.LevelNode getMiningLevelNode() { return Util.assertImpl(); } - - default ReferenceSet getParentMaterials() { - return Util.assertImpl(); - } - - default TagKey getRequiredBlockTag() { - return Util.assertImpl(); - } - - default boolean matches(BlockState state) { - return ALL_TOOL_MATERIAL_TAGS.stream().noneMatch(state::isIn) || matches0(state); - } - - private boolean matches0(BlockState state) { - TagKey tag = getRequiredBlockTag(); - if (tag != null) { - if (state.isIn(tag)) return true; - BiPredicate matches0 = StationToolMaterial::matches0; - Predicate matchesThis = t -> matches0.test(t, state); - return getParentMaterials().stream().anyMatch(matchesThis); - } else return false; - } } diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolLevel.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolLevel.java index 84bb3fb87..d12cf4528 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolLevel.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolLevel.java @@ -6,7 +6,6 @@ import net.modificationstation.stationapi.api.tag.TagKey; public interface ToolLevel { - void setEffectiveBlocks(TagKey effectiveBlocks); TagKey getEffectiveBlocks(ItemStack stack); diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolMaterialFactory.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolMaterialFactory.java index e0b52131a..8ecfecadd 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolMaterialFactory.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/ToolMaterialFactory.java @@ -4,7 +4,6 @@ import net.modificationstation.stationapi.api.factory.EnumFactory; public class ToolMaterialFactory { - public static ToolMaterial create(String materialName, int miningLevel, int durability, float miningSpeed, int attackDamage) { return EnumFactory.addEnum( ToolMaterial.class, materialName, diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/HijackShearsImplV1.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/HijackShearsImplV1.java index ef0f81f1a..873ee30c3 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/HijackShearsImplV1.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/HijackShearsImplV1.java @@ -7,7 +7,6 @@ @EventListener(phase = StationAPI.INTERNAL_PHASE) public class HijackShearsImplV1 { - //TODO: Make this match anything that has shear tool properties. Not sure how to go around this at the moment. @EventListener private static void hijackShearsEvent(ShearsOverrideEvent event) { diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java index 258205d1d..9f4d161d6 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java @@ -1,5 +1,6 @@ package net.modificationstation.stationapi.impl.item; +import com.google.common.graph.GraphBuilder; import net.mine_diver.unsafeevents.listener.EventListener; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -8,6 +9,7 @@ import net.modificationstation.stationapi.api.event.item.IsItemSuitableForStateEvent; import net.modificationstation.stationapi.api.event.item.ItemMiningSpeedMultiplierOnStateEvent; import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent; +import net.modificationstation.stationapi.api.item.tool.MiningLevelManager; import net.modificationstation.stationapi.api.item.tool.ToolLevel; import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint; import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy; @@ -25,7 +27,6 @@ @Entrypoint(eventBus = @EventBusPolicy(registerInstance = false)) @EventListener(phase = StationAPI.INTERNAL_PHASE) public class ToolEffectivenessImplV1 { - public static final List VANILLA_TOOLS = new ArrayList<>(); @EventListener(priority = LOW) @@ -55,15 +56,30 @@ private static void getItems(ItemRegistryEvent event) { @EventListener private static void isEffective(IsItemSuitableForStateEvent event) { - event.suitable = event.suitable || isSuitable(event.itemStack, event.state); + // Disable custom tool logic if both the block and the tool are vanilla + // This is done to preserve the vanilla mining speeds + if (VANILLA_TOOLS.contains(ItemRegistry.INSTANCE.getId(event.itemStack.getItem())) + && Objects.requireNonNull(BlockRegistry.INSTANCE.getId(event.state.getBlock())).namespace == Namespace.MINECRAFT) return; + + event.suitable = isSuitable(event.itemStack, event.state); } @EventListener private static void getStrength(ItemMiningSpeedMultiplierOnStateEvent event) { - if (!(VANILLA_TOOLS.contains(ItemRegistry.INSTANCE.getId(event.itemStack.getItem())) && Objects.requireNonNull(BlockRegistry.INSTANCE.getId(event.state.getBlock())).namespace == Namespace.MINECRAFT) && isSuitable(event.itemStack, event.state)) event.miningSpeedMultiplier = ((ToolLevel) event.itemStack.getItem()).getMaterial(event.itemStack).getMiningSpeedMultiplier(); + // Disable custom tool logic if both the block and the tool are vanilla + // This is done to preserve the vanilla mining speeds + if (VANILLA_TOOLS.contains(ItemRegistry.INSTANCE.getId(event.itemStack.getItem())) + && Objects.requireNonNull(BlockRegistry.INSTANCE.getId(event.state.getBlock())).namespace == Namespace.MINECRAFT) return; + + if (!isSuitable(event.itemStack, event.state)) return; + + GraphBuilder.directed().allowsSelfLoops(true).build(); + event.miningSpeedMultiplier = ((ToolLevel) event.itemStack.getItem()).getMaterial(event.itemStack).getMiningSpeedMultiplier(); } private static boolean isSuitable(ItemStack item, BlockState state) { - return item.getItem() instanceof ToolLevel toolLevel && state.isIn(toolLevel.getEffectiveBlocks(item)) && toolLevel.getMaterial(item).matches(state); + return item.getItem() instanceof ToolLevel toolLevel + && state.isIn(toolLevel.getEffectiveBlocks(item)) + && MiningLevelManager.isSuitable(toolLevel.getMaterial(item).getMiningLevelNode(), state); } } diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java index 3429c86b5..aa4265349 100644 --- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java +++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolMaterialMixin.java @@ -1,64 +1,26 @@ package net.modificationstation.stationapi.mixin.tools; -import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -import it.unimi.dsi.fastutil.objects.ReferenceSet; -import it.unimi.dsi.fastutil.objects.ReferenceSets; -import net.minecraft.block.Block; import net.minecraft.item.ToolMaterial; +import net.modificationstation.stationapi.api.item.tool.MiningLevelManager; import net.modificationstation.stationapi.api.item.tool.StationToolMaterial; -import net.modificationstation.stationapi.api.registry.BlockRegistry; -import net.modificationstation.stationapi.api.tag.TagKey; -import net.modificationstation.stationapi.api.util.Identifier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.Collections; @Mixin(ToolMaterial.class) class ToolMaterialMixin implements StationToolMaterial { @Unique - private TagKey stationapi_requiredBlockTag; - @Unique - private ReferenceSet stationapi_parentMaterials; - @Unique - private ReferenceSet stationapi_parentMaterialsView; - - @Inject( - method = "(Ljava/lang/String;IIIFI)V", - at = @At("RETURN") - ) - private void stationapi_init(String i, int j, int k, int f, float l, int par6, CallbackInfo ci) { - stationapi_parentMaterials = new ReferenceOpenHashSet<>(); - stationapi_parentMaterialsView = ReferenceSets.unmodifiable(stationapi_parentMaterials); - } - - @Override - @Unique - public ToolMaterial inheritsFrom(ToolMaterial... toolMaterials) { - Collections.addAll(stationapi_parentMaterials, toolMaterials); - return ToolMaterial.class.cast(this); - } + private MiningLevelManager.LevelNode stationapi_levelNode; @Override @Unique - public ToolMaterial requiredBlockTag(Identifier tag) { - ALL_TOOL_MATERIAL_TAGS.remove(stationapi_requiredBlockTag); - ALL_TOOL_MATERIAL_TAGS.add(stationapi_requiredBlockTag = TagKey.of(BlockRegistry.INSTANCE.getKey(), tag)); + public ToolMaterial miningLevelNode(MiningLevelManager.LevelNode levelNode) { + stationapi_levelNode = levelNode; return ToolMaterial.class.cast(this); } @Override @Unique - public ReferenceSet getParentMaterials() { - return stationapi_parentMaterialsView; - } - - @Override - @Unique - public TagKey getRequiredBlockTag() { - return stationapi_requiredBlockTag; + public MiningLevelManager.LevelNode getMiningLevelNode() { + return stationapi_levelNode; } } diff --git a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java index c9cffd6bc..f51cceb4c 100644 --- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java +++ b/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java @@ -4,8 +4,11 @@ import net.minecraft.item.ToolMaterial; import net.modificationstation.stationapi.api.StationAPI; import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent; +import net.modificationstation.stationapi.api.item.tool.MiningLevelManager; import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint; import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy; +import net.modificationstation.stationapi.api.registry.BlockRegistry; +import net.modificationstation.stationapi.api.tag.TagKey; import static net.modificationstation.stationapi.api.util.Identifier.of; @@ -14,14 +17,14 @@ public final class VanillaToolFixImpl { @EventListener private static void fixToolMaterials(ItemRegistryEvent event) { - ToolMaterial stone = ToolMaterial.STONE; - ToolMaterial iron = ToolMaterial.IRON; - ToolMaterial diamond = ToolMaterial.DIAMOND; - stone.inheritsFrom(ToolMaterial.WOOD, ToolMaterial.GOLD); - stone.requiredBlockTag(of("needs_stone_tool")); - iron.inheritsFrom(ToolMaterial.STONE); - iron.requiredBlockTag(of("needs_iron_tool")); - diamond.inheritsFrom(ToolMaterial.IRON); - diamond.requiredBlockTag(of("needs_diamond_tool")); + MiningLevelManager.LevelNode stoneNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, of("needs_stone_tool"))); + MiningLevelManager.LevelNode ironNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, of("needs_iron_tool"))); + MiningLevelManager.LevelNode diamondNode = new MiningLevelManager.LevelNode(TagKey.of(BlockRegistry.KEY, of("needs_diamond_tool"))); + MiningLevelManager.GRAPH.putEdge(stoneNode, ironNode); + MiningLevelManager.GRAPH.putEdge(ironNode, diamondNode); + MiningLevelManager.invalidateCache(); + ToolMaterial.STONE.miningLevelNode(stoneNode); + ToolMaterial.IRON.miningLevelNode(ironNode); + ToolMaterial.DIAMOND.miningLevelNode(diamondNode); } }