getType() {
+ return TYPE;
}
public Object[] deserializeObjects() {
diff --git a/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/network/packet/PacketHelper.java b/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/network/packet/PacketHelper.java
index 7cfc4bf9f..d449bf949 100644
--- a/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/network/packet/PacketHelper.java
+++ b/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/network/packet/PacketHelper.java
@@ -47,7 +47,7 @@ public static void sendTo(PlayerEntity player, Packet packet) {
* Registers the given packet.
*
* For registering packets that use {@link Identifier} instead of a byte ID,
- * refer to {@link IdentifiablePacket#register(Identifier, boolean, boolean, IdentifiablePacket.Factory)}
+ * refer to {@link ManagedPacket#register(Identifier, boolean, boolean, ManagedPacket.Factory)}
*
* @param rawId the packet ID that you want to use for the packet.
* The ID is written as a byte, meaning it can be any number in the 0-255 (inclusive) range,
diff --git a/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/network/packet/PacketType.java b/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/network/packet/PacketType.java
new file mode 100644
index 000000000..5e63e5404
--- /dev/null
+++ b/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/network/packet/PacketType.java
@@ -0,0 +1,75 @@
+package net.modificationstation.stationapi.api.network.packet;
+
+import lombok.Setter;
+import net.minecraft.network.NetworkHandler;
+import net.minecraft.network.packet.Packet;
+import net.modificationstation.stationapi.api.registry.PacketTypeRegistry;
+import net.modificationstation.stationapi.api.registry.RegistryEntry;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+import java.util.Optional;
+
+public final class PacketType> {
+ public final RegistryEntry.Reference> registryEntry;
+ public final boolean clientBound;
+ public final boolean serverBound;
+ public final ManagedPacket.@NotNull Factory factory;
+ @Setter
+ private @Nullable NetworkHandler handler;
+ public final boolean blocking;
+
+ private PacketType(Builder builder) {
+ //noinspection unchecked
+ registryEntry = (RegistryEntry.Reference>) (RegistryEntry.Reference>) PacketTypeRegistry.INSTANCE.createReservedEntry(builder.rawId, this);
+ clientBound = builder.clientBound;
+ serverBound = builder.serverBound;
+ factory = builder.factory;
+ blocking = builder.blocking;
+ }
+
+ public Optional getHandler() {
+ return Optional.ofNullable(handler);
+ }
+
+ public static > Builder builder(
+ boolean clientBound, boolean serverBound,
+ @NotNull ManagedPacket.Factory factory
+ ) {
+ return new Builder<>(clientBound, serverBound, factory);
+ }
+
+ public static final class Builder> {
+ private int rawId = PacketTypeRegistry.AUTO_ID;
+ private final boolean clientBound;
+ private final boolean serverBound;
+ private final ManagedPacket.Factory factory;
+ private boolean blocking;
+
+ private Builder(
+ boolean clientBound, boolean serverBound,
+ @NotNull ManagedPacket.Factory factory
+ ) {
+ this.clientBound = clientBound;
+ this.serverBound = serverBound;
+ this.factory = Objects.requireNonNull(factory, "Attempted to build a PacketType with null packet factory!");
+ }
+
+ @ApiStatus.Internal
+ public Builder rawId(int rawId) {
+ this.rawId = rawId;
+ return this;
+ }
+
+ public Builder blocking() {
+ this.blocking = true;
+ return this;
+ }
+
+ public PacketType build() {
+ return new PacketType<>(this);
+ }
+ }
+}
diff --git a/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/registry/IdentifiablePacketRegistry.java b/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/registry/IdentifiablePacketRegistry.java
deleted file mode 100644
index 0f9a3bf51..000000000
--- a/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/registry/IdentifiablePacketRegistry.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package net.modificationstation.stationapi.api.registry;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import net.modificationstation.stationapi.api.network.packet.IdentifiablePacket;
-
-import static net.modificationstation.stationapi.api.StationAPI.NAMESPACE;
-
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class IdentifiablePacketRegistry {
- private static final IdentifiablePacket.Factory EMPTY = () -> null;
- public static final RegistryKey> KEY = RegistryKey.ofRegistry(NAMESPACE.id("packets"));
- public static final Registry INSTANCE = Registries.create(KEY, registry -> EMPTY);
-}
diff --git a/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/registry/PacketTypeRegistry.java b/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/registry/PacketTypeRegistry.java
new file mode 100644
index 000000000..181f0c2d3
--- /dev/null
+++ b/station-networking-v0/src/main/java/net/modificationstation/stationapi/api/registry/PacketTypeRegistry.java
@@ -0,0 +1,18 @@
+package net.modificationstation.stationapi.api.registry;
+
+import com.mojang.serialization.Lifecycle;
+import net.modificationstation.stationapi.api.event.registry.RegistryAttribute;
+import net.modificationstation.stationapi.api.event.registry.RegistryAttributeHolder;
+import net.modificationstation.stationapi.api.network.packet.PacketType;
+
+import static net.modificationstation.stationapi.api.StationAPI.NAMESPACE;
+
+public final class PacketTypeRegistry extends SimpleRegistry> {
+ public static final RegistryKey>> KEY = RegistryKey.ofRegistry(NAMESPACE.id("packet_types"));
+ public static final Registry> INSTANCE = Registries.create(KEY, new PacketTypeRegistry(), registry -> registry.get(NAMESPACE.id("registry/remap_client")), Lifecycle.experimental());
+
+ private PacketTypeRegistry() {
+ super(KEY, Lifecycle.experimental(), true);
+ RegistryAttributeHolder.get(this).addAttribute(RegistryAttribute.SYNCED);
+ }
+}
diff --git a/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/client/network/packet/PacketHelperClientImpl.java b/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/client/network/packet/PacketHelperClientImpl.java
index 3a1cd12e0..789050b06 100644
--- a/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/client/network/packet/PacketHelperClientImpl.java
+++ b/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/client/network/packet/PacketHelperClientImpl.java
@@ -4,8 +4,7 @@
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.packet.Packet;
-import net.modificationstation.stationapi.api.network.packet.IdentifiablePacket;
-import net.modificationstation.stationapi.impl.network.packet.IdentifiablePacketImpl;
+import net.modificationstation.stationapi.api.network.packet.ManagedPacket;
import net.modificationstation.stationapi.impl.network.packet.PacketHelperImpl;
public class PacketHelperClientImpl extends PacketHelperImpl {
@@ -15,12 +14,12 @@ public void send(Packet packet) {
Minecraft minecraft = (Minecraft) FabricLoader.getInstance().getGameInstance();
if (minecraft.world.isRemote)
minecraft.getNetworkHandler().sendPacket(packet);
- else packet.apply(packet instanceof IdentifiablePacket identifiablePacket ? IdentifiablePacketImpl.HANDLERS.get(identifiablePacket.getId()) : null);
+ else packet.apply(packet instanceof ManagedPacket> managedPacket ? managedPacket.getType().getHandler().orElse(null) : null);
}
@Override
public void sendTo(PlayerEntity player, Packet packet) {
if (!player.world.isRemote)
- packet.apply(packet instanceof IdentifiablePacket identifiablePacket ? IdentifiablePacketImpl.HANDLERS.get(identifiablePacket.getId()) : null);
+ packet.apply(packet instanceof ManagedPacket> managedPacket ? managedPacket.getType().getHandler().orElse(null) : null);
}
}
diff --git a/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/IdentifiablePacketImpl.java b/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/IdentifiablePacketImpl.java
deleted file mode 100644
index 3a748dd58..000000000
--- a/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/IdentifiablePacketImpl.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package net.modificationstation.stationapi.impl.network.packet;
-
-import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
-import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
-import net.minecraft.network.NetworkHandler;
-import net.modificationstation.stationapi.api.util.Identifier;
-
-import java.util.Map;
-import java.util.Set;
-
-public class IdentifiablePacketImpl {
- public static final Set
- CLIENT_BOUND_PACKETS = new ReferenceOpenHashSet<>(),
- SERVER_BOUND_PACKETS = new ReferenceOpenHashSet<>();
-
- public static final Map HANDLERS = new Reference2ReferenceOpenHashMap<>();
-}
diff --git a/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/StationNetworkingImpl.java b/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/StationNetworkingImpl.java
index b641befd2..f1e087cda 100644
--- a/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/StationNetworkingImpl.java
+++ b/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/StationNetworkingImpl.java
@@ -1,17 +1,21 @@
package net.modificationstation.stationapi.impl.network.packet;
import net.fabricmc.api.ModInitializer;
-import net.modificationstation.stationapi.api.network.packet.IdentifiablePacket;
+import net.modificationstation.stationapi.api.network.packet.ManagedPacket;
import net.modificationstation.stationapi.api.network.packet.MessagePacket;
+import net.modificationstation.stationapi.api.registry.PacketTypeRegistry;
+import net.modificationstation.stationapi.api.registry.Registry;
import net.modificationstation.stationapi.mixin.network.AbstractPacketAccessor;
+import static net.modificationstation.stationapi.api.StationAPI.NAMESPACE;
+
public class StationNetworkingImpl implements ModInitializer {
@Override
public void onInitialize() {
// Avoid side checks for IdentifiablePacket by numerical ID
- AbstractPacketAccessor.getClientBoundPackets().add(IdentifiablePacket.PACKET_ID);
- AbstractPacketAccessor.getServerBoundPackets().add(IdentifiablePacket.PACKET_ID);
-
- IdentifiablePacket.register(MessagePacket.PACKET_ID, true, true, MessagePacket::new);
+ AbstractPacketAccessor.getClientBoundPackets().add(ManagedPacket.PACKET_ID);
+ AbstractPacketAccessor.getServerBoundPackets().add(ManagedPacket.PACKET_ID);
+
+ Registry.register(PacketTypeRegistry.INSTANCE, NAMESPACE.id("message"), MessagePacket.TYPE);
}
}
diff --git a/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/server/network/packet/PacketHelperServerImpl.java b/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/server/network/packet/PacketHelperServerImpl.java
index 1f1511be7..a43b00bd9 100644
--- a/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/server/network/packet/PacketHelperServerImpl.java
+++ b/station-networking-v0/src/main/java/net/modificationstation/stationapi/impl/server/network/packet/PacketHelperServerImpl.java
@@ -3,14 +3,13 @@
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.network.packet.Packet;
-import net.modificationstation.stationapi.api.network.packet.IdentifiablePacket;
-import net.modificationstation.stationapi.impl.network.packet.IdentifiablePacketImpl;
+import net.modificationstation.stationapi.api.network.packet.ManagedPacket;
import net.modificationstation.stationapi.impl.network.packet.PacketHelperImpl;
public class PacketHelperServerImpl extends PacketHelperImpl {
@Override
public void send(Packet packet) {
- packet.apply(packet instanceof IdentifiablePacket identifiablePacket ? IdentifiablePacketImpl.HANDLERS.get(identifiablePacket.getId()) : null);
+ packet.apply(packet instanceof ManagedPacket> managedPacket ? managedPacket.getType().getHandler().orElse(null) : null);
}
@Override
diff --git a/station-networking-v0/src/main/java/net/modificationstation/stationapi/mixin/network/ConnectionMixin.java b/station-networking-v0/src/main/java/net/modificationstation/stationapi/mixin/network/ConnectionMixin.java
index ae753d3a1..81dd7aab1 100644
--- a/station-networking-v0/src/main/java/net/modificationstation/stationapi/mixin/network/ConnectionMixin.java
+++ b/station-networking-v0/src/main/java/net/modificationstation/stationapi/mixin/network/ConnectionMixin.java
@@ -2,17 +2,27 @@
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.network.Connection;
import net.minecraft.network.NetworkHandler;
import net.minecraft.network.packet.Packet;
-import net.modificationstation.stationapi.api.network.packet.IdentifiablePacket;
-import net.modificationstation.stationapi.impl.network.packet.IdentifiablePacketImpl;
+import net.modificationstation.stationapi.api.network.packet.ManagedPacket;
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.Redirect;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+import java.util.concurrent.atomic.AtomicBoolean;
@Mixin(Connection.class)
class ConnectionMixin {
+ @Unique
+ private static final Object STATIONAPI$PACKET_READ_LOCK = new Object();
+ @Unique
+ private static final AtomicBoolean STATIONAPI$BLOCKNG_PACKET = new AtomicBoolean();
+
@WrapOperation(
method = "method_1129",
at = @At(
@@ -20,11 +30,36 @@ class ConnectionMixin {
target = "Lnet/minecraft/network/packet/Packet;apply(Lnet/minecraft/network/NetworkHandler;)V"
)
)
- private void stationapi_ifIdentifiable(Packet instance, NetworkHandler packetHandler, Operation original) {
- instance.apply(
- instance instanceof IdentifiablePacket identifiablePacket ?
- IdentifiablePacketImpl.HANDLERS.getOrDefault(identifiablePacket.getId(), packetHandler) :
- packetHandler
- );
+ private void stationapi_ifIdentifiable(Packet instance, NetworkHandler networkHandler, Operation original) {
+ if (instance instanceof ManagedPacket> managedPacket) {
+ instance.apply(managedPacket.getType().getHandler().orElse(networkHandler));
+ if (managedPacket.getType().blocking) {
+ synchronized (STATIONAPI$PACKET_READ_LOCK) {
+ STATIONAPI$BLOCKNG_PACKET.set(false);
+ STATIONAPI$PACKET_READ_LOCK.notifyAll();
+ }
+ }
+ } else original.call(instance, networkHandler);
+ }
+
+ @Inject(
+ method = "method_1139",
+ at = @At(
+ value = "INVOKE",
+ target = "Ljava/util/List;add(Ljava/lang/Object;)Z",
+ shift = At.Shift.AFTER
+ )
+ )
+ private void stationapi_waitOnBlockingPacket(
+ CallbackInfoReturnable cir,
+ @Local(index = 2) Packet packet
+ ) {
+ if (!(packet instanceof ManagedPacket> managedPacket) || !managedPacket.getType().blocking) return;
+ synchronized (STATIONAPI$PACKET_READ_LOCK) {
+ STATIONAPI$BLOCKNG_PACKET.set(true);
+ while (STATIONAPI$BLOCKNG_PACKET.get()) try {
+ STATIONAPI$PACKET_READ_LOCK.wait();
+ } catch (InterruptedException ignored) {}
+ }
}
}
diff --git a/station-networking-v0/src/main/java/net/modificationstation/stationapi/mixin/network/PacketMixin.java b/station-networking-v0/src/main/java/net/modificationstation/stationapi/mixin/network/PacketMixin.java
index ef9774ac8..bd9840c1a 100644
--- a/station-networking-v0/src/main/java/net/modificationstation/stationapi/mixin/network/PacketMixin.java
+++ b/station-networking-v0/src/main/java/net/modificationstation/stationapi/mixin/network/PacketMixin.java
@@ -2,14 +2,12 @@
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.network.packet.Packet;
import net.modificationstation.stationapi.api.StationAPI;
import net.modificationstation.stationapi.api.event.network.packet.PacketRegisterEvent;
-import net.modificationstation.stationapi.api.network.packet.IdentifiablePacket;
-import net.modificationstation.stationapi.api.util.Identifier;
+import net.modificationstation.stationapi.api.network.packet.ManagedPacket;
+import net.modificationstation.stationapi.api.registry.PacketTypeRegistry;
import net.modificationstation.stationapi.api.util.Null;
-import net.modificationstation.stationapi.impl.network.packet.IdentifiablePacketImpl;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@@ -21,25 +19,13 @@
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.util.Objects;
@Mixin(Packet.class)
abstract class PacketMixin {
@Shadow
static void register(int rawId, boolean clientBound, boolean serverBound, Class extends Packet> type) {}
- @Shadow
- public static void writeString(String string, DataOutputStream dataOutputStream) {}
-
- @Shadow
- public static String readString(DataInputStream dataInputStream, int i) {
- return Null.get();
- }
-
- @Shadow
- public static Packet create(int i) {
- return Null.get();
- }
-
@Inject(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/Packet;register(IZZLjava/lang/Class;)V", ordinal = 56, shift = At.Shift.AFTER))
private static void stationapi_afterVanillaPackets(CallbackInfo ci) {
StationAPI.EVENT_BUS.post(PacketRegisterEvent.builder().register(PacketMixin::register).build());
@@ -51,8 +37,8 @@ private static void stationapi_afterVanillaPackets(CallbackInfo ci) {
cancellable = true
)
private void stationapi_ifIdentifiable(CallbackInfoReturnable cir) {
- if (this instanceof IdentifiablePacket)
- cir.setReturnValue(IdentifiablePacket.PACKET_ID);
+ if (this instanceof ManagedPacket)
+ cir.setReturnValue(ManagedPacket.PACKET_ID);
}
@Inject(
@@ -62,9 +48,9 @@ private void stationapi_ifIdentifiable(CallbackInfoReturnable cir) {
target = "Lnet/minecraft/network/packet/Packet;write(Ljava/io/DataOutputStream;)V"
)
)
- private static void stationapi_ifIdentifiable(Packet packet, DataOutputStream out, CallbackInfo ci) {
- if (packet instanceof IdentifiablePacket idPacket)
- writeString(idPacket.getId().toString(), out);
+ private static void stationapi_ifIdentifiable(Packet packet, DataOutputStream out, CallbackInfo ci) throws IOException {
+ if (packet instanceof ManagedPacket> managedPacket)
+ out.writeInt(PacketTypeRegistry.INSTANCE.getRawId(managedPacket.getType()));
}
@WrapOperation(
@@ -74,15 +60,15 @@ private static void stationapi_ifIdentifiable(Packet packet, DataOutputStream ou
target = "Lnet/minecraft/network/packet/Packet;create(I)Lnet/minecraft/network/packet/Packet;"
)
)
- private static Packet stationapi_ifIdentifiable(int id, Operation original, @Local(argsOnly = true) DataInputStream in, @Local(argsOnly = true) boolean server) throws IOException {
- if (id == IdentifiablePacket.PACKET_ID) {
- Identifier identifier = Identifier.of(readString(in, Short.MAX_VALUE));
+ private static Packet stationapi_ifIdentifiable(int rawId, Operation original, DataInputStream stream, boolean bl) throws IOException {
+ if (rawId == ManagedPacket.PACKET_ID) {
+ var packetType = Objects.requireNonNull(PacketTypeRegistry.INSTANCE.get(stream.readInt()), "Received nonexistent managed packet!");
if (
- server && !IdentifiablePacketImpl.SERVER_BOUND_PACKETS.contains(identifier) ||
- !server && !IdentifiablePacketImpl.CLIENT_BOUND_PACKETS.contains(identifier)
- ) throw new IOException("Bad packet id " + identifier);
- return IdentifiablePacket.create(identifier);
+ bl && !packetType.serverBound ||
+ !bl && !packetType.clientBound
+ ) throw new IOException("Bad packet id " + packetType.registryEntry.registryKey().getValue());
+ return packetType.factory.create();
}
- return original.call(id);
+ return original.call(rawId);
}
}
diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/api/recipe/StationRecipe.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/api/recipe/StationRecipe.java
deleted file mode 100644
index 047a084fb..000000000
--- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/api/recipe/StationRecipe.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package net.modificationstation.stationapi.api.recipe;
-
-import net.minecraft.item.ItemStack;
-
-/**
- * This entire interface is slated for removal in alpha 3.
- * Stop using it, it's shit and was made specifically for HMI, for all the wrong reasons.
- * - calm
- */
-@Deprecated(forRemoval = true)
-public interface StationRecipe {
-
- @Deprecated(forRemoval = true)
- ItemStack[] getIngredients();
-
- @Deprecated(forRemoval = true)
- ItemStack[] getOutputs();
-}
diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapedRecipe.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapedRecipe.java
index bd90c04fd..d57e08eac 100644
--- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapedRecipe.java
+++ b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapedRecipe.java
@@ -5,17 +5,11 @@
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.CraftingRecipe;
-import net.modificationstation.stationapi.api.recipe.StationRecipe;
-import net.modificationstation.stationapi.api.registry.ItemRegistry;
import net.modificationstation.stationapi.api.tag.TagKey;
import java.util.*;
-import java.util.function.Function;
-
-public class StationShapedRecipe implements CraftingRecipe, StationRecipe {
-
- private static final Random RANDOM = new Random();
+public class StationShapedRecipe implements CraftingRecipe {
public final int width, height;
private final Either, ItemStack>[] grid;
public final ItemStack output;
@@ -84,25 +78,6 @@ public ItemStack getOutput() {
return output.copy();
}
- @Override
- public ItemStack[] getIngredients() {
- ItemStack[] stacks = new ItemStack[9];
- for (int h = 0; h < height; h++)
- for (int w = 0; w < width; w++) {
- int localId = (h * width) + w;
- Either, ItemStack> ingredient = grid[localId];
- if (ingredient == null) continue;
- int id = (h * 3) + w;
- stacks[id] = ingredient.map(tag -> new ItemStack(ItemRegistry.INSTANCE.getEntryList(tag).orElseThrow(() -> new RuntimeException("Identifier ingredient \"" + tag.id() + "\" has no entry in the tag registry!")).getRandom(RANDOM).orElseThrow().value()), Function.identity());
- }
- return stacks;
- }
-
- @Override
- public ItemStack[] getOutputs() {
- return new ItemStack[] { output };
- }
-
public Either, ItemStack>[] getGrid() {
//noinspection unchecked
return (Either, ItemStack>[]) Arrays.stream(grid).map(entry -> entry == null ? null : entry.mapRight(ItemStack::copy)).toArray(Either[]::new);
diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapelessRecipe.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapelessRecipe.java
index 8ba42a7b5..d981a7bca 100644
--- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapelessRecipe.java
+++ b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/StationShapelessRecipe.java
@@ -5,14 +5,11 @@
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.CraftingRecipe;
-import net.modificationstation.stationapi.api.recipe.StationRecipe;
-import net.modificationstation.stationapi.api.registry.ItemRegistry;
import net.modificationstation.stationapi.api.tag.TagKey;
import java.util.*;
-import java.util.function.Function;
-public class StationShapelessRecipe implements CraftingRecipe, StationRecipe {
+public class StationShapelessRecipe implements CraftingRecipe {
private static final Random RANDOM = new Random();
@@ -78,24 +75,7 @@ public ItemStack getOutput() {
return output.copy();
}
- @Override
- public ItemStack[] getIngredients() {
- ItemStack[] inputs = new ItemStack[ingredients.length];
- for (int i = 0, ingredientsLength = ingredients.length; i < ingredientsLength; i++)
- inputs[i] = ingredients[i].map(tag -> new ItemStack(ItemRegistry.INSTANCE.getEntryList(tag).orElseThrow(() -> new RuntimeException("Identifier ingredient \"" + tag.id() + "\" has no entry in the tag registry!")).getRandom(RANDOM).orElseThrow().value()), Function.identity());
- return inputs;
- }
-
- @Override
- public ItemStack[] getOutputs() {
- return new ItemStack[] { output };
- }
-
- /**
- * To be renamed to getIngredients in a3, use with caution.
- */
- @Deprecated
- public Either, ItemStack>[] getInputs() {
+ public Either, ItemStack>[] getIngredients() {
//noinspection unchecked
return (Either, ItemStack>[]) Arrays.stream(ingredients).map(entry -> entry == null ? null : entry.mapRight(ItemStack::copy)).toArray(Either[]::new);
}
diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/tag/TagConversionStorage.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/tag/TagConversionStorage.java
index 628e0dac7..51ae03cbd 100644
--- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/tag/TagConversionStorage.java
+++ b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/impl/recipe/tag/TagConversionStorage.java
@@ -1,11 +1,11 @@
package net.modificationstation.stationapi.impl.recipe.tag;
+import it.unimi.dsi.fastutil.objects.ReferenceIntPair;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.modificationstation.stationapi.api.registry.BlockRegistry;
-import net.modificationstation.stationapi.api.util.Identifier;
import net.modificationstation.stationapi.api.registry.ItemRegistry;
-import uk.co.benjiweber.expressions.tuple.BiTuple;
+import net.modificationstation.stationapi.api.util.Identifier;
import java.util.ArrayList;
import java.util.HashMap;
@@ -13,7 +13,7 @@
// TODO: replace in vanillafix by actually changing recipes
public class TagConversionStorage {
- public static final HashMap, Identifier> CONVERSION_TABLE = new HashMap<>();
+ public static final HashMap, Identifier> CONVERSION_TABLE = new HashMap<>();
private static ArrayList spammedNames = new ArrayList<>();
@@ -106,11 +106,11 @@ public static void init() {
// }
// }
- private static BiTuple getIdentifier(Object o, int meta) {
- return o instanceof Block block ? BiTuple.of(BlockRegistry.INSTANCE.getId(block), meta) : BiTuple.of(ItemRegistry.INSTANCE.getId((Item) o), meta);
+ private static ReferenceIntPair getIdentifier(Object o, int meta) {
+ return o instanceof Block block ? ReferenceIntPair.of(BlockRegistry.INSTANCE.getId(block), meta) : ReferenceIntPair.of(ItemRegistry.INSTANCE.getId((Item) o), meta);
}
- private static BiTuple getIdentifier(Object o) {
+ private static ReferenceIntPair getIdentifier(Object o) {
return getIdentifier(o, 0);
}
diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/CraftingRecipeMixin.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/CraftingRecipeMixin.java
deleted file mode 100644
index ccd3ac845..000000000
--- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/CraftingRecipeMixin.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package net.modificationstation.stationapi.mixin.recipe;
-
-import net.minecraft.item.ItemStack;
-import net.minecraft.recipe.CraftingRecipe;
-import net.modificationstation.stationapi.api.recipe.StationRecipe;
-import org.spongepowered.asm.mixin.Mixin;
-
-@Mixin(CraftingRecipe.class)
-public interface CraftingRecipeMixin extends StationRecipe {
- @Override
- default ItemStack[] getIngredients() {
- throw new UnsupportedOperationException("Your custom recipe registry needs to implement the methods found in \"net.modificationstation.stationapi.api.recipe.StationRecipe\"!");
- }
-
- @Override
- default ItemStack[] getOutputs() {
- throw new UnsupportedOperationException("Your custom recipe registry needs to implement the methods found in \"net.modificationstation.stationapi.api.recipe.StationRecipe\"!");
- }
-}
diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapedRecipeMixin.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapedRecipeMixin.java
deleted file mode 100644
index 9f9ed3f84..000000000
--- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapedRecipeMixin.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package net.modificationstation.stationapi.mixin.recipe;
-
-import net.minecraft.ShapedRecipe;
-import net.minecraft.item.ItemStack;
-import net.modificationstation.stationapi.api.recipe.StationRecipe;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-
-@Mixin(ShapedRecipe.class)
-class ShapedRecipeMixin implements StationRecipe {
- @Shadow private int width;
- @Shadow private int height;
- @Shadow private ItemStack output;
-
- @Shadow private ItemStack[] input;
-
- @Override
- public ItemStack[] getIngredients() {
- ItemStack[] stacks = new ItemStack[9];
- for (int h = 0; h < height; h++) {
- for (int w = 0; w < width; w++) {
- int localId = (h * width) + w;
- int id = (h * 3) + w;
- stacks[id] = input[localId];
- }
- }
- return stacks;
- }
-
- @Override
- public ItemStack[] getOutputs() {
- return new ItemStack[] { output };
- }
-}
diff --git a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapelessRecipeMixin.java b/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapelessRecipeMixin.java
deleted file mode 100644
index 2270e4279..000000000
--- a/station-recipes-v0/src/main/java/net/modificationstation/stationapi/mixin/recipe/ShapelessRecipeMixin.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package net.modificationstation.stationapi.mixin.recipe;
-
-import net.minecraft.item.ItemStack;
-import net.minecraft.recipe.ShapelessRecipe;
-import net.modificationstation.stationapi.api.recipe.StationRecipe;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-
-import java.util.List;
-
-@Mixin(ShapelessRecipe.class)
-class ShapelessRecipeMixin implements StationRecipe {
- @Shadow @Final private List input;
-
- @Shadow @Final private ItemStack output;
-
- @Override
- public ItemStack[] getIngredients() {
- return input.toArray(ItemStack[]::new);
- }
-
- @Override
- public ItemStack[] getOutputs() {
- return new ItemStack[] { output };
- }
-}
diff --git a/station-recipes-v0/src/main/resources/station-recipes-v0.mixins.json b/station-recipes-v0/src/main/resources/station-recipes-v0.mixins.json
index ff2373bb4..cb789d3bc 100644
--- a/station-recipes-v0/src/main/resources/station-recipes-v0.mixins.json
+++ b/station-recipes-v0/src/main/resources/station-recipes-v0.mixins.json
@@ -5,12 +5,9 @@
"compatibilityLevel": "JAVA_17",
"mixins": [
"CraftingRecipeManagerMixin",
- "CraftingRecipeMixin",
"CraftingResultMixin",
"FurnaceBlockEntityMixin",
"RecipeComparatorMixin",
- "ShapedRecipeMixin",
- "ShapelessRecipeMixin",
"SmeltingRecipeManagerAccessor",
"SmeltingRecipeManagerMixin",
"StatsMixin"
diff --git a/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/registry/RegistryEntryListCodec.java b/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/registry/RegistryEntryListCodec.java
index 415912eec..1276370d7 100644
--- a/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/registry/RegistryEntryListCodec.java
+++ b/station-registry-api-v0/src/main/java/net/modificationstation/stationapi/api/registry/RegistryEntryListCodec.java
@@ -78,7 +78,7 @@ private DataResult, T>> decodeDirect(DynamicOps
}
return DataResult.error(() -> "Can't decode element " + registryEntry + " without registry");
}
- return DataResult.success(new Pair<>(RegistryEntryList.of(list), pair.getSecond()));
+ return DataResult.success(Pair.of(RegistryEntryList.of(list), pair.getSecond()));
});
}
diff --git a/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/client/network/ClientRegistryNetworkingInit.java b/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/client/network/ClientRegistryNetworkingInit.java
index bd926b333..c2da9d2bc 100644
--- a/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/client/network/ClientRegistryNetworkingInit.java
+++ b/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/client/network/ClientRegistryNetworkingInit.java
@@ -2,13 +2,12 @@
import net.fabricmc.api.ClientModInitializer;
import net.minecraft.network.NetworkHandler;
-import net.modificationstation.stationapi.api.network.packet.IdentifiablePacket;
import net.modificationstation.stationapi.impl.network.packet.s2c.play.RemapClientRegistryS2CPacket;
public final class ClientRegistryNetworkingInit implements ClientModInitializer {
@Override
public void onInitializeClient() {
NetworkHandler handler = new ClientRegistryNetworkHandler();
- IdentifiablePacket.setHandler(RemapClientRegistryS2CPacket.PACKET_ID, handler);
+ RemapClientRegistryS2CPacket.TYPE.setHandler(handler);
}
}
diff --git a/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/network/RegistryNetworkingInit.java b/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/network/RegistryNetworkingInit.java
index cebaf4df0..074c68c72 100644
--- a/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/network/RegistryNetworkingInit.java
+++ b/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/network/RegistryNetworkingInit.java
@@ -1,12 +1,22 @@
package net.modificationstation.stationapi.impl.network;
-import net.fabricmc.api.ModInitializer;
-import net.modificationstation.stationapi.api.network.packet.IdentifiablePacket;
+import net.mine_diver.unsafeevents.listener.EventListener;
+import net.modificationstation.stationapi.api.StationAPI;
+import net.modificationstation.stationapi.api.event.network.packet.PacketRegisterEvent;
+import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint;
+import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy;
+import net.modificationstation.stationapi.api.registry.PacketTypeRegistry;
+import net.modificationstation.stationapi.api.registry.Registry;
import net.modificationstation.stationapi.impl.network.packet.s2c.play.RemapClientRegistryS2CPacket;
-public final class RegistryNetworkingInit implements ModInitializer {
- @Override
- public void onInitialize() {
- IdentifiablePacket.register(RemapClientRegistryS2CPacket.PACKET_ID, true, false, RemapClientRegistryS2CPacket::new);
+import static net.mine_diver.unsafeevents.listener.ListenerPriority.HIGH;
+import static net.modificationstation.stationapi.api.StationAPI.NAMESPACE;
+
+@Entrypoint(eventBus = @EventBusPolicy(registerInstance = false))
+@EventListener(phase = StationAPI.INTERNAL_PHASE, priority = HIGH)
+public final class RegistryNetworkingInit {
+ @EventListener
+ private static void onInitialize(PacketRegisterEvent event) {
+ Registry.register(PacketTypeRegistry.INSTANCE, NAMESPACE.id("registry/remap_client"), RemapClientRegistryS2CPacket.TYPE);
}
}
diff --git a/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/s2c/play/RemapClientRegistryS2CPacket.java b/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/s2c/play/RemapClientRegistryS2CPacket.java
index a1cade8d3..07fbbbbb0 100644
--- a/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/s2c/play/RemapClientRegistryS2CPacket.java
+++ b/station-registry-sync-v0/src/main/java/net/modificationstation/stationapi/impl/network/packet/s2c/play/RemapClientRegistryS2CPacket.java
@@ -9,22 +9,26 @@
import net.fabricmc.api.Environment;
import net.minecraft.network.NetworkHandler;
import net.minecraft.network.packet.Packet;
-import net.modificationstation.stationapi.api.network.packet.IdentifiablePacket;
+import net.modificationstation.stationapi.api.network.packet.ManagedPacket;
+import net.modificationstation.stationapi.api.network.packet.PacketType;
import net.modificationstation.stationapi.api.util.Identifier;
import net.modificationstation.stationapi.impl.network.RegistryPacketHandler;
+import org.jetbrains.annotations.NotNull;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-import static net.modificationstation.stationapi.api.StationAPI.NAMESPACE;
-
-public class RemapClientRegistryS2CPacket extends Packet implements IdentifiablePacket {
- public static final Identifier PACKET_ID = NAMESPACE.id("registry/remap_client");
+public class RemapClientRegistryS2CPacket extends Packet implements ManagedPacket {
+ public static final PacketType TYPE = PacketType
+ .builder(true, false, RemapClientRegistryS2CPacket::new)
+ .rawId(0)
+ .blocking()
+ .build();
public Reference2ReferenceMap> map;
- public RemapClientRegistryS2CPacket() {}
+ private RemapClientRegistryS2CPacket() {}
@Environment(EnvType.SERVER)
public RemapClientRegistryS2CPacket(Reference2ReferenceMap> map) {
@@ -94,7 +98,7 @@ public int size() {
}
@Override
- public Identifier getId() {
- return PACKET_ID;
+ public @NotNull PacketType getType() {
+ return TYPE;
}
}
diff --git a/station-registry-sync-v0/src/main/resources/fabric.mod.json b/station-registry-sync-v0/src/main/resources/fabric.mod.json
index 00f825647..f5d04754b 100644
--- a/station-registry-sync-v0/src/main/resources/fabric.mod.json
+++ b/station-registry-sync-v0/src/main/resources/fabric.mod.json
@@ -27,7 +27,7 @@
"net.modificationstation.stationapi.impl.client.registry.ClientServerRegistryRemapper",
"net.modificationstation.stationapi.impl.client.registry.ClientRegistryRestorer"
],
- "main": [
+ "stationapi:event_bus": [
"net.modificationstation.stationapi.impl.network.RegistryNetworkingInit"
],
"client": [
diff --git a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/event/render/model/PreLoadUnbakedModelEvent.java b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/event/render/model/PreLoadUnbakedModelEvent.java
index c8fd9ca4a..707dc947f 100644
--- a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/event/render/model/PreLoadUnbakedModelEvent.java
+++ b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/event/render/model/PreLoadUnbakedModelEvent.java
@@ -5,13 +5,17 @@
import net.modificationstation.stationapi.api.client.render.model.ModelLoader;
import net.modificationstation.stationapi.api.client.render.model.UnbakedModel;
import net.modificationstation.stationapi.api.util.Identifier;
-import uk.co.benjiweber.expressions.function.ExceptionalFunction;
import java.io.IOException;
@SuperBuilder
public class PreLoadUnbakedModelEvent extends Event {
+ @FunctionalInterface
+ public interface Loader {
+ UnbakedModel load(Identifier identifier) throws IOException;
+ }
+
public final Identifier identifier;
public final ModelLoader modelLoader;
- public ExceptionalFunction loader;
+ public Loader loader;
}
diff --git a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/render/model/ModelLoader.java b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/render/model/ModelLoader.java
index 84ca963bc..23ab77d35 100644
--- a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/render/model/ModelLoader.java
+++ b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/render/model/ModelLoader.java
@@ -27,11 +27,11 @@
import net.modificationstation.stationapi.api.client.texture.Sprite;
import net.modificationstation.stationapi.api.client.texture.SpriteIdentifier;
import net.modificationstation.stationapi.api.registry.BlockRegistry;
-import net.modificationstation.stationapi.api.util.Identifier;
import net.modificationstation.stationapi.api.registry.ItemRegistry;
import net.modificationstation.stationapi.api.resource.ResourceFinder;
import net.modificationstation.stationapi.api.state.StateManager;
import net.modificationstation.stationapi.api.state.property.Property;
+import net.modificationstation.stationapi.api.util.Identifier;
import net.modificationstation.stationapi.api.util.Util;
import net.modificationstation.stationapi.api.util.math.AffineTransformation;
import net.modificationstation.stationapi.api.util.profiler.Profiler;
@@ -316,7 +316,7 @@ private UnbakedModel loadModelFromResource(Identifier id) throws IOException {
.modelLoader(this)
.loader(this::loadModelFromJson)
.build()
- ).loader.apply(id)
+ ).loader.load(id)
)
.build()
).model;
diff --git a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/texture/SpritesheetHelper.java b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/texture/SpritesheetHelper.java
index f60bda6e7..824c77a3e 100644
--- a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/texture/SpritesheetHelper.java
+++ b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/texture/SpritesheetHelper.java
@@ -1,14 +1,13 @@
package net.modificationstation.stationapi.api.client.texture;
+import it.unimi.dsi.fastutil.ints.IntIntPair;
import net.modificationstation.stationapi.api.util.Identifier;
-import uk.co.benjiweber.expressions.tuple.BiTuple;
-import uk.co.benjiweber.expressions.tuple.Tuple;
public interface SpritesheetHelper {
- BiTuple DEFAULT_RESOLUTION_MULTIPLIER = Tuple.tuple(1, 1);
+ IntIntPair DEFAULT_RESOLUTION_MULTIPLIER = IntIntPair.of(1, 1);
Identifier generateIdentifier(int textureIndex);
- BiTuple getResolutionMultiplier(int textureIndex);
+ IntIntPair getResolutionMultiplier(int textureIndex);
}
diff --git a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/texture/atlas/Atlas.java b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/texture/atlas/Atlas.java
index 0b0721adf..3e83bc74b 100644
--- a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/texture/atlas/Atlas.java
+++ b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/client/texture/atlas/Atlas.java
@@ -14,7 +14,6 @@
import net.modificationstation.stationapi.api.util.Identifier;
import net.modificationstation.stationapi.api.util.Util;
import org.jetbrains.annotations.ApiStatus;
-import uk.co.benjiweber.expressions.function.ObjIntFunction;
import java.util.IdentityHashMap;
import java.util.List;
@@ -55,13 +54,18 @@ public abstract class Atlas {
this.parent = parent;
}
- protected final T applyInherited(int textureIndex, IntFunction atlasBounds, ObjIntFunction parentBounds) {
+ @FunctionalInterface
+ protected interface ParentBoundsGetter {
+ T getBounds(Atlas atlas, int texture);
+ }
+
+ protected final T applyInherited(int textureIndex, IntFunction atlasBounds, ParentBoundsGetter parentBounds) {
if (parent == null) {
if (0 <= textureIndex && textureIndex < size)
return atlasBounds.apply(textureIndex);
} else {
if (textureIndex < parent.size)
- return parentBounds.apply(parent, textureIndex);
+ return parentBounds.getBounds(parent, textureIndex);
else if (textureIndex < size)
return atlasBounds.apply(textureIndex - parent.size);
}
diff --git a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/util/math/AffineTransformation.java b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/util/math/AffineTransformation.java
index bcf7c7957..872dffd13 100644
--- a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/util/math/AffineTransformation.java
+++ b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/api/util/math/AffineTransformation.java
@@ -1,10 +1,9 @@
package net.modificationstation.stationapi.api.util.math;
+import com.mojang.datafixers.util.Pair;
import net.modificationstation.stationapi.api.util.Util;
import org.apache.commons.lang3.tuple.Triple;
import org.jetbrains.annotations.Nullable;
-import uk.co.benjiweber.expressions.tuple.BiTuple;
-import uk.co.benjiweber.expressions.tuple.Tuple;
import java.util.Objects;
@@ -67,9 +66,9 @@ public AffineTransformation invert() {
private void init() {
if (!this.initialized) {
- BiTuple pair = getLinearTransformationAndTranslationFromAffine(this.matrix);
- Triple triple = pair.one().decomposeLinearTransformation();
- this.translation = pair.two();
+ Pair pair = getLinearTransformationAndTranslationFromAffine(this.matrix);
+ Triple triple = pair.getFirst().decomposeLinearTransformation();
+ this.translation = pair.getSecond();
this.rotation2 = triple.getLeft();
this.scale = triple.getMiddle();
this.rotation1 = triple.getRight();
@@ -102,11 +101,11 @@ private static Matrix4f setup(@Nullable Vec3f translation, @Nullable Quaternion
return matrix4f;
}
- public static BiTuple getLinearTransformationAndTranslationFromAffine(Matrix4f affineTransform) {
+ public static Pair getLinearTransformationAndTranslationFromAffine(Matrix4f affineTransform) {
affineTransform.multiply(1.0F / affineTransform.a33);
Vec3f vector3f = new Vec3f(affineTransform.a03, affineTransform.a13, affineTransform.a23);
Matrix3f matrix3f = new Matrix3f(affineTransform);
- return Tuple.tuple(matrix3f, vector3f);
+ return Pair.of(matrix3f, vector3f);
}
public Matrix4f getMatrix() {
diff --git a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/GuiItemsHelper.java b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/GuiItemsHelper.java
index 4cb7396c1..f4d61538f 100644
--- a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/GuiItemsHelper.java
+++ b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/GuiItemsHelper.java
@@ -2,12 +2,12 @@
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntIntPair;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import net.modificationstation.stationapi.api.client.texture.SpritesheetHelper;
import net.modificationstation.stationapi.api.util.Identifier;
import net.modificationstation.stationapi.api.util.Util;
-import uk.co.benjiweber.expressions.tuple.BiTuple;
import java.util.function.ObjIntConsumer;
@@ -149,7 +149,7 @@ public Identifier generateIdentifier(int textureIndex) {
}
@Override
- public BiTuple getResolutionMultiplier(int textureIndex) {
+ public IntIntPair getResolutionMultiplier(int textureIndex) {
return DEFAULT_RESOLUTION_MULTIPLIER;
}
}
diff --git a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/StationRenderImpl.java b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/StationRenderImpl.java
index 02ae98f85..6b089cd29 100644
--- a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/StationRenderImpl.java
+++ b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/StationRenderImpl.java
@@ -1,5 +1,6 @@
package net.modificationstation.stationapi.impl.client.texture;
+import com.mojang.datafixers.util.Pair;
import net.fabricmc.loader.api.FabricLoader;
import net.mine_diver.unsafeevents.listener.EventListener;
import net.minecraft.class_285;
@@ -26,8 +27,6 @@
import net.modificationstation.stationapi.api.util.Null;
import net.modificationstation.stationapi.api.util.profiler.Profiler;
import org.apache.logging.log4j.Logger;
-import uk.co.benjiweber.expressions.tuple.BiTuple;
-import uk.co.benjiweber.expressions.tuple.Tuple;
import java.util.Collection;
import java.util.Objects;
@@ -115,7 +114,7 @@ public void reload(ResourceManager manager) {
}
});
abstract class SPIResourceReloader extends SinglePreparationResourceReloader implements IdentifiableResourceReloadListener {}
- helper.registerReloadListener(new SPIResourceReloader>() {
+ helper.registerReloadListener(new SPIResourceReloader>() {
@Override
public String getName() {
@@ -133,7 +132,7 @@ public Collection getDependencies() {
}
@Override
- protected BiTuple prepare(ResourceManager manager, Profiler profiler) {
+ protected Pair prepare(ResourceManager manager, Profiler profiler) {
profiler.startTick();
profiler.push("legacy_atlases");
ExpandableAtlas
@@ -143,13 +142,13 @@ protected BiTuple prepare(ResourceManager mana
guiItems.addSpritesheet(16, GuiItemsHelper.INSTANCE);
profiler.pop();
profiler.endTick();
- return Tuple.tuple(terrain, guiItems);
+ return Pair.of(terrain, guiItems);
}
@Override
- protected void apply(BiTuple prepared, ResourceManager manager, Profiler profiler) {
- TERRAIN = prepared.one();
- GUI_ITEMS = prepared.two();
+ protected void apply(Pair prepared, ResourceManager manager, Profiler profiler) {
+ TERRAIN = prepared.getFirst();
+ GUI_ITEMS = prepared.getSecond();
profiler.startTick();
profiler.push("mod_textures");
StationAPI.EVENT_BUS.post(TextureRegisterEvent.builder().build());
diff --git a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/TerrainHelper.java b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/TerrainHelper.java
index bb2812f48..09013b8ca 100644
--- a/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/TerrainHelper.java
+++ b/station-renderer-api-v0/src/main/java/net/modificationstation/stationapi/impl/client/texture/TerrainHelper.java
@@ -2,13 +2,12 @@
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntIntPair;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import net.modificationstation.stationapi.api.client.texture.SpritesheetHelper;
import net.modificationstation.stationapi.api.util.Identifier;
import net.modificationstation.stationapi.api.util.Util;
-import uk.co.benjiweber.expressions.tuple.BiTuple;
-import uk.co.benjiweber.expressions.tuple.Tuple;
import java.util.function.ObjIntConsumer;
@@ -184,11 +183,11 @@ final class TerrainHelper implements SpritesheetHelper {
f.accept("destroy_stage_9", 249);
});
- private static final Int2ObjectMap> RESOLUTION_MULTIPLIERS = Util.make(new Int2ObjectOpenHashMap<>(), map -> {
+ private static final Int2ObjectMap RESOLUTION_MULTIPLIERS = Util.make(new Int2ObjectOpenHashMap<>(), map -> {
map.defaultReturnValue(DEFAULT_RESOLUTION_MULTIPLIER);
- ObjIntConsumer> f = (resMul, index) -> map.put(index, resMul);
- f.accept(Tuple.tuple(2, 2), 206);
- f.accept(Tuple.tuple(2, 2), 238);
+ ObjIntConsumer f = (resMul, index) -> map.put(index, resMul);
+ f.accept(IntIntPair.of(2, 2), 206);
+ f.accept(IntIntPair.of(2, 2), 238);
});
@Override
@@ -197,7 +196,7 @@ public Identifier generateIdentifier(int textureIndex) {
}
@Override
- public BiTuple getResolutionMultiplier(int textureIndex) {
+ public IntIntPair getResolutionMultiplier(int textureIndex) {
return RESOLUTION_MULTIPLIERS.get(textureIndex);
}
}
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java
index c088afc31..070b07814 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreen.java
@@ -2,9 +2,6 @@
import com.google.common.primitives.Floats;
import com.google.common.primitives.Longs;
-import cyclops.control.Option;
-import cyclops.function.Effect;
-import cyclops.function.FluentFunctions;
import it.unimi.dsi.fastutil.doubles.Double2DoubleFunction;
import it.unimi.dsi.fastutil.longs.Long2DoubleFunction;
import lombok.val;
@@ -16,11 +13,11 @@
import net.modificationstation.stationapi.api.util.math.ColorHelper;
import net.modificationstation.stationapi.impl.client.resource.ReloadScreenManagerImpl;
+import java.util.Optional;
import java.util.Random;
import java.util.concurrent.CompletionException;
import java.util.function.*;
-import static cyclops.function.FluentFunctions.expression;
import static java.util.Map.of;
import static net.modificationstation.stationapi.api.StationAPI.LOGGER;
import static net.modificationstation.stationapi.api.util.math.MathHelper.ceil;
@@ -77,7 +74,7 @@ private static UnaryOperator when(BooleanSupplier condition
private long initTimestamp;
private long currentTime;
private float progress;
- private final Effect
+ private final Runnable
backgroundEmitter,
stage0Emitter;
private boolean finished;
@@ -116,14 +113,12 @@ private static UnaryOperator when(BooleanSupplier condition
ToDoubleFunction deltaFunc = key -> deltaMap.get(key).applyAsDouble(currentTime);
- backgroundEmitter = FluentFunctions
- .>expression(this::renderBackground)
- .partiallyApply(deltaFunc)::get;
+ backgroundEmitter = () -> renderBackground(deltaFunc);
- stage0Emitter =
- expression(this::renderProgressBar)
- .before(this::renderLogo)
- .partiallyApply(deltaFunc)::get;
+ stage0Emitter = () -> {
+ renderLogo(deltaFunc);
+ renderProgressBar(deltaFunc);
+ };
}
private void renderBackground(ToDoubleFunction deltaFunc) {
@@ -275,7 +270,7 @@ public void render(int mouseX, int mouseY, float delta) {
val locationsSize = ReloadScreenManager.LOCATIONS.size();
if (!exceptionThrown && !finished && !(scrollProgress + .1 < locationsSize) && !(progress + .1 < 1) && ReloadScreenManager.isReloadComplete()) {
try {
- ReloadScreenManager.getCurrentReload().peek(ResourceReload::throwException);
+ ReloadScreenManager.getCurrentReload().ifPresent(ResourceReload::throwException);
finished = true;
fadeOutStart = currentTime;
} catch (CompletionException e) {
@@ -286,8 +281,8 @@ public void render(int mouseX, int mouseY, float delta) {
}
}
if (!partial) {
- Option reload;
- progress = Floats.constrainToRange(progress * .95F + (isReloadStarted() && (reload = ReloadScreenManager.getCurrentReload()).isPresent() ? reload.orElse(null/*safe*/).getProgress() : 0) * .05F, 0, 1);
+ Optional reload;
+ progress = Floats.constrainToRange(progress * .95F + (isReloadStarted() && (reload = ReloadScreenManager.getCurrentReload()).isPresent() ? reload.get().getProgress() : 0) * .05F, 0, 1);
scrollProgress = Floats.constrainToRange(scrollProgress * .95F + locationsSize * .05F, 0, locationsSize);
}
if ((finished ? currentTime <= fadeOutStart + GLOBAL_FADE_OUT : currentTime < BACKGROUND_START + BACKGROUND_FADE_IN) && parent != null)
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java
index 050c73880..64ec1c1f1 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/client/resource/ReloadScreenManager.java
@@ -1,6 +1,5 @@
package net.modificationstation.stationapi.api.client.resource;
-import cyclops.control.Option;
import lombok.Getter;
import lombok.val;
import net.fabricmc.loader.api.FabricLoader;
@@ -27,20 +26,20 @@
import org.lwjgl.opengl.SharedDrawable;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
-import static cyclops.control.Option.none;
-import static cyclops.control.Option.some;
-import static cyclops.function.FluentFunctions.expression;
import static org.lwjgl.opengl.GL11.*;
public class ReloadScreenManager {
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Getter
- private static @NotNull Option thread = none();
+ private static @NotNull Optional thread = Optional.empty();
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Getter
- private static @NotNull Option currentReload = none();
+ private static @NotNull Optional currentReload = Optional.empty();
static ReloadScreen reloadScreen;
static final List LOCATIONS = new CopyOnWriteArrayList<>();
private static final Executor EMPTY_EXECUTOR = command -> {};
@@ -57,18 +56,17 @@ public static void pushLocation(ResourceReloader resourceReloader, String format
public static void openEarly() throws LWJGLException {
ReloadScreenManagerImpl.isMinecraftDone = false;
applicationExecutor = ReloadScreenApplicationExecutor.INSTANCE;
- currentReload = some(new CompositeResourceReload());
+ currentReload = Optional.of(new CompositeResourceReload());
//noinspection deprecation
- thread = some(new Thread(expression(ReloadScreenManager::onStartup).partiallyApply(
- (Minecraft) FabricLoader.getInstance().getGameInstance(),
- new SharedDrawable(Display.getDrawable())
- )::get));
- thread.peek(Thread::start);
+ final Minecraft minecraft = (Minecraft) FabricLoader.getInstance().getGameInstance();
+ final Drawable drawable = new SharedDrawable(Display.getDrawable());
+ thread = Optional.of(new Thread(() -> ReloadScreenManager.onStartup(minecraft, drawable)));
+ thread.ifPresent(Thread::start);
}
public static void open() {
applicationExecutor = TickScheduler.CLIENT_RENDER_END::distributed;
- currentReload = some(new CompositeResourceReload());
+ currentReload = Optional.of(new CompositeResourceReload());
TickScheduler.CLIENT_RENDER_START.immediate(
() -> {
//noinspection deprecation
@@ -76,7 +74,7 @@ public static void open() {
val parentScreen = minecraft.currentScreen;
val reloadScreen = new ReloadScreen(
parentScreen,
- expression(minecraft::setScreen).applyLazy(parentScreen)::apply,
+ () -> minecraft.setScreen(parentScreen),
Tessellator.INSTANCE
);
minecraft.setScreen(reloadScreen);
@@ -100,7 +98,7 @@ static void onFinish() {
reloadScreen = null;
LOCATIONS.clear();
applicationExecutor = ReloadScreenManager.EMPTY_EXECUTOR;
- currentReload = none();
+ currentReload = Optional.empty();
}
private static void onStartup(
@@ -115,7 +113,7 @@ private static void onStartup(
val done = new AtomicBoolean();
val reloadScreen = new ReloadScreen(
minecraft.currentScreen,
- expression(done::set).applyLazy(true)::apply,
+ () -> done.set(true),
ReloadScreenTessellatorHolder.reloadScreenTessellator = TessellatorAccessor.stationapi_create(48)
);
val screenScaler = new class_564(minecraft.options, minecraft.displayWidth, minecraft.displayHeight);
@@ -157,6 +155,6 @@ private static void onStartup(
} catch (LWJGLException e) {
throw new RuntimeException(e);
}
- thread = none();
+ thread = Optional.empty();
}
}
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/CompositeResourceReload.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/CompositeResourceReload.java
index bbb1b6e80..e5f2b190c 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/CompositeResourceReload.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/CompositeResourceReload.java
@@ -1,47 +1,38 @@
package net.modificationstation.stationapi.api.resource;
import com.google.common.base.Supplier;
-import cyclops.control.Option;
-import cyclops.data.tuple.Tuple2;
-import cyclops.function.Function2;
+import com.mojang.datafixers.util.Pair;
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import lombok.val;
import net.modificationstation.stationapi.api.util.Identifier;
-import java.util.function.Function;
+import java.util.Optional;
import static com.google.common.base.Suppliers.memoize;
-import static cyclops.control.Option.none;
-import static cyclops.control.Option.some;
-import static cyclops.data.tuple.Tuple.tuple;
-import static cyclops.function.Function1.constant;
-import static cyclops.function.Function2._2;
public final class CompositeResourceReload implements ResourceReload {
private static final float DEFAULT_WEIGHT = 1;
- private static final Function2, Tuple2>, Float>, Tuple2 >, Float>> WEIGHT_MAPPER_FACTORY = Function2.>, Float>, Function, Tuple2>, Float>>λ(Tuple2::map2).reverse();
- private static final Function2>, Option>>, Tuple2>, Float>, Tuple2 >, Float>> RESOURCE_RELOAD_MAPPER_FACTORY = Function2.>, Float>, Function>, Option>>, Tuple2>, Float>>λ(Tuple2::map1).reverse();
- private final Reference2ObjectMap>, Float>> reloads = Reference2ObjectMaps.synchronize(new Reference2ObjectOpenHashMap<>());
+ private final Reference2ObjectMap>, Float>> reloads = Reference2ObjectMaps.synchronize(new Reference2ObjectOpenHashMap<>());
public void setWeight(Identifier id, float weight) {
reloads.merge(
- id, tuple(none(), weight),
- _2(WEIGHT_MAPPER_FACTORY.apply(constant(weight)))
+ id, Pair.of(Optional.empty(), weight),
+ (oldReload, newReload) -> Pair.of(oldReload.getFirst(), newReload.getSecond())
);
}
public void scheduleReload(Identifier id, Supplier reload) {
reloads.merge(
- id, tuple(some(memoize(reload)), DEFAULT_WEIGHT),
- _2(RESOURCE_RELOAD_MAPPER_FACTORY.apply(constant(some(memoize(reload)))))
+ id, Pair.of(Optional.of(memoize(reload)), DEFAULT_WEIGHT),
+ (oldReload, newReload) -> Pair.of(newReload.getFirst(), oldReload.getSecond())
);
}
public void scheduleReload(Identifier id, Supplier reload, float weight) {
- reloads.put(id, tuple(some(memoize(reload)), weight));
+ reloads.put(id, Pair.of(Optional.of(memoize(reload)), weight));
}
@Override
@@ -49,9 +40,9 @@ public float getProgress() {
var totalWeight = 0F;
var progress = 0F;
for (val weightedReload : reloads.values()) {
- totalWeight += weightedReload._2();
- if (!weightedReload._1().isPresent()) continue;
- progress += weightedReload._1().orElse(null/*safe*/).get().getProgress() * weightedReload._2();
+ totalWeight += weightedReload.getSecond();
+ if (weightedReload.getFirst().isEmpty()) continue;
+ progress += weightedReload.getFirst().get().get().getProgress() * weightedReload.getSecond();
}
return progress / totalWeight;
}
@@ -61,7 +52,7 @@ public boolean isComplete() {
if (reloads.values().isEmpty())
return false;
for (val weightedReload : reloads.values()) {
- if (weightedReload._1().isPresent() && !weightedReload._1().orElse(null/*safe*/).get().isComplete())
+ if (weightedReload.getFirst().map(reload -> !reload.get().isComplete()).orElse(false))
return false;
}
return true;
@@ -70,7 +61,6 @@ public boolean isComplete() {
@Override
public void throwException() {
for (val weightedReload : reloads.values())
- if (weightedReload._1().isPresent())
- weightedReload._1().orElse(null/*safe*/).get().throwException();
+ weightedReload.getFirst().ifPresent(reload -> reload.get().throwException());
}
}
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/ProfiledResourceReload.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/ProfiledResourceReload.java
index 9399916be..a864acf77 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/ProfiledResourceReload.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/ProfiledResourceReload.java
@@ -1,7 +1,6 @@
package net.modificationstation.stationapi.api.resource;
import com.google.common.base.Stopwatch;
-import cyclops.function.Consumer3;
import lombok.val;
import net.modificationstation.stationapi.api.util.Unit;
import net.modificationstation.stationapi.api.util.Util;
@@ -15,11 +14,10 @@
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
import java.util.function.Supplier;
-import static cyclops.function.FluentFunctions.expression;
-import static cyclops.function.Function0.λ;
-import static cyclops.function.Function1.lazy;
import static net.modificationstation.stationapi.api.StationAPI.LOGGER;
import static net.modificationstation.stationapi.api.util.profiler.Profiler.union;
@@ -28,12 +26,17 @@ public class ProfiledResourceReload extends SimpleResourceReload reloaders,
Executor prepareExecutor,
Executor applyExecutor,
- Consumer3 profilerListener,
+ ProfilerListener profilerListener,
CompletableFuture initialStage
) {
super(prepareExecutor, applyExecutor, manager, reloaders, (synchronizer, resourceManager, reloader, prepare, apply) -> {
@@ -44,29 +47,17 @@ public ProfiledResourceReload(
.getResourceType()
.map(ResourceType::getDirectory)
.map(StringUtils::capitalize)
- .orElseGet(
- λ(resourceManager::getClass)
- .andThen(Class::getSimpleName)
- );
+ .orElseGet(() -> resourceManager.getClass().getSimpleName());
val prepareProfiler = new ProfilerSystem(Util.nanoTimeSupplier, () -> 0, false);
val applyProfiler = new ProfilerSystem(Util.nanoTimeSupplier, () -> 0, false);
+ final BiConsumer reloaderListener = (prefix, location) -> profilerListener.push(reloader, prefix, location);
+ final Consumer preparationListener = location -> reloaderListener.accept(LOCATION_FORMAT.formatted(managerName, "%s", "preparation"), location);
+ final Consumer applicationListener = location -> reloaderListener.accept(LOCATION_FORMAT.formatted(managerName, "%s", "application"), location);
return reloader.reload(
synchronizer,
resourceManager,
- union(
- prepareProfiler,
- (ListenableProfiler) expression(profilerListener.apply(
- reloader,
- LOCATION_FORMAT.formatted(managerName, "%s", "preparation")
- )).compose(lazy(prepareProfiler::getFullPath))::apply
- ),
- union(
- applyProfiler,
- (ListenableProfiler) expression(profilerListener.apply(
- reloader,
- LOCATION_FORMAT.formatted(managerName, "%s", "application")
- )).compose(lazy(applyProfiler::getFullPath))::apply
- ),
+ union(prepareProfiler, (ListenableProfiler) location -> preparationListener.accept(prepareProfiler.getFullPath())),
+ union(applyProfiler, (ListenableProfiler) location -> applicationListener.accept(applyProfiler.getFullPath())),
preparation -> prepare.execute(() -> {
long prepareStart = Util.getMeasuringTimeNano();
preparation.run();
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/SimpleResourceReload.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/SimpleResourceReload.java
index d12fb915a..b66ceee97 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/SimpleResourceReload.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/api/resource/SimpleResourceReload.java
@@ -1,6 +1,5 @@
package net.modificationstation.stationapi.api.resource;
-import cyclops.function.Consumer3;
import net.modificationstation.stationapi.api.util.Unit;
import net.modificationstation.stationapi.api.util.Util;
import net.modificationstation.stationapi.api.util.profiler.DummyProfiler;
@@ -136,7 +135,7 @@ public static ResourceReload start(
final List reloaders,
Executor prepareExecutor,
Executor applyExecutor,
- Consumer3 profilerListener,
+ ProfiledResourceReload.ProfilerListener profilerListener,
CompletableFuture initialStage
) {
return new ProfiledResourceReload(
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/client/resource/AssetsReloaderImpl.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/client/resource/AssetsReloaderImpl.java
index de569ade7..191c1529c 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/client/resource/AssetsReloaderImpl.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/client/resource/AssetsReloaderImpl.java
@@ -16,10 +16,9 @@
import net.modificationstation.stationapi.impl.resource.TexturePackProvider;
import net.modificationstation.stationapi.impl.resource.loader.ModResourcePackCreator;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
-import static cyclops.control.Option.none;
-import static cyclops.control.Option.some;
import static net.modificationstation.stationapi.api.StationAPI.NAMESPACE;
@Entrypoint(eventBus = @EventBusPolicy(registerInstance = false))
@@ -40,11 +39,11 @@ private static void reload(TexturePackLoadedEvent.After event) {
@EventListener
private static void reloadResourceManager(final AssetsReloadEvent event) {
RESOURCE_PACK_MANAGER.scanPacks();
+ if (ReloadScreenManager.getCurrentReload().isEmpty())
+ ReloadScreenManager.open();
ReloadScreenManager.getCurrentReload()
- .onEmpty(ReloadScreenManager::open);
- ReloadScreenManager.getCurrentReload()
- .flatMap(reload1 -> reload1 instanceof CompositeResourceReload composite ? some(composite) : none())
- .peek(manager -> manager.scheduleReload(
+ .flatMap(reload1 -> reload1 instanceof CompositeResourceReload composite ? Optional.of(composite) : Optional.empty())
+ .ifPresent(manager -> manager.scheduleReload(
NAMESPACE.id("assets"),
() -> ReloadableAssetsManager.INSTANCE.reload(
Util.getMainWorkerExecutor(),
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/DataReloaderImpl.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/DataReloaderImpl.java
index b3986725a..7d0846b95 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/DataReloaderImpl.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/DataReloaderImpl.java
@@ -16,12 +16,11 @@
import net.modificationstation.stationapi.api.util.Util;
import net.modificationstation.stationapi.impl.resource.loader.ModResourcePackCreator;
+import java.util.Optional;
import java.util.Queue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
-import static cyclops.control.Option.none;
-import static cyclops.control.Option.some;
import static net.mine_diver.unsafeevents.listener.ListenerPriority.LOW;
import static net.modificationstation.stationapi.api.StationAPI.NAMESPACE;
@@ -59,8 +58,8 @@ private static void reloadResourceManager(DataReloadEvent event) {
@EventListener(priority = LOW)
private static void reloadResourceManagerClient(DataReloadEvent event) {
ReloadScreenManager.getCurrentReload()
- .flatMap(reload1 -> reload1 instanceof CompositeResourceReload composite ? some(composite) : none())
- .peek(manager -> manager.scheduleReload(
+ .flatMap(reload1 -> reload1 instanceof CompositeResourceReload composite ? Optional.of(composite) : Optional.empty())
+ .ifPresent(manager -> manager.scheduleReload(
NAMESPACE.id("data"),
() -> DataManager.INSTANCE.reload(
Util.getMainWorkerExecutor(),
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/ReloadableResourceManager.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/ReloadableResourceManager.java
index 85347b702..61c7f2060 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/ReloadableResourceManager.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/ReloadableResourceManager.java
@@ -1,7 +1,6 @@
package net.modificationstation.stationapi.impl.resource;
import com.google.common.collect.Lists;
-import cyclops.function.Consumer3;
import net.modificationstation.stationapi.api.util.Identifier;
import net.modificationstation.stationapi.api.util.Namespace;
import net.modificationstation.stationapi.api.resource.*;
@@ -68,7 +67,7 @@ public ResourceReload reload(
Executor prepareExecutor,
Executor applyExecutor,
CompletableFuture initialStage,
- Consumer3 profilerListener,
+ ProfiledResourceReload.ProfilerListener profilerListener,
List packs
) {
LOGGER.info("Reloading ResourceManager: {}", () -> packs.stream().map(ResourcePack::getName).collect(Collectors.joining(", ")));
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/loader/ResourceManagerHelperImpl.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/loader/ResourceManagerHelperImpl.java
index 6dc2e204c..d69d1639c 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/loader/ResourceManagerHelperImpl.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/impl/resource/loader/ResourceManagerHelperImpl.java
@@ -3,8 +3,8 @@
import com.google.common.collect.Lists;
import com.mojang.datafixers.util.Pair;
import net.fabricmc.loader.api.ModContainer;
-import net.modificationstation.stationapi.api.util.Identifier;
import net.modificationstation.stationapi.api.resource.*;
+import net.modificationstation.stationapi.api.util.Identifier;
import net.modificationstation.stationapi.impl.resource.ModNioResourcePack;
import net.modificationstation.stationapi.impl.resource.ResourcePackProfile;
import org.slf4j.Logger;
@@ -47,9 +47,9 @@ public static boolean registerBuiltinResourcePack(Identifier id, String subPath,
ModNioResourcePack dataPack = ModNioResourcePack.create(id, displayName, container, subPath, ResourceType.SERVER_DATA, activationType);
if (resourcePack == null && dataPack == null) return false;
- if (resourcePack != null) builtinResourcePacks.add(new Pair<>(displayName, resourcePack));
+ if (resourcePack != null) builtinResourcePacks.add(Pair.of(displayName, resourcePack));
- if (dataPack != null) builtinResourcePacks.add(new Pair<>(displayName, dataPack));
+ if (dataPack != null) builtinResourcePacks.add(Pair.of(displayName, dataPack));
return true;
}
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/MinecraftMixin.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/MinecraftMixin.java
index 954f27695..cb1abbb85 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/MinecraftMixin.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/MinecraftMixin.java
@@ -1,6 +1,5 @@
package net.modificationstation.stationapi.mixin.resourceloader.client;
-import com.oath.cyclops.util.ExceptionSoftener;
import lombok.val;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@@ -116,6 +115,12 @@ private void stationapi_applyReloadsAndWait(CallbackInfo ci) {
val command = ReloadScreenApplicationExecutor.INSTANCE.poll();
if (command != null) command.run();
}
- ReloadScreenManager.getThread().peek(ExceptionSoftener.softenConsumer(Thread::join));
+ ReloadScreenManager.getThread().ifPresent(thread -> {
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ });
}
}
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/TextRendererMixin.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/TextRendererMixin.java
index 0f12c5bfc..32de466be 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/TextRendererMixin.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/TextRendererMixin.java
@@ -1,7 +1,6 @@
package net.modificationstation.stationapi.mixin.resourceloader.client;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
-import cyclops.function.FluentFunctions;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.render.Tessellator;
import net.modificationstation.stationapi.api.client.resource.ReloadScreenManager;
@@ -23,6 +22,6 @@ class TextRendererMixin {
)
)
private Tessellator stationapi_changeTessellatorIfNecessary(Tessellator instance) {
- return ReloadScreenManager.getThread().map(FluentFunctions.of(Objects::equals).partiallyApply(Thread.currentThread())).orElse(false) ? ReloadScreenTessellatorHolder.reloadScreenTessellator : instance;
+ return ReloadScreenManager.getThread().map(thread -> Objects.equals(thread, Thread.currentThread())).orElse(false) ? ReloadScreenTessellatorHolder.reloadScreenTessellator : instance;
}
}
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/TexturePackMixin.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/TexturePackMixin.java
index e7e71b93e..5da714f38 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/TexturePackMixin.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/TexturePackMixin.java
@@ -2,14 +2,13 @@
import net.minecraft.class_285;
import net.modificationstation.stationapi.api.client.resource.ReloadableAssetsManager;
-import net.modificationstation.stationapi.api.resource.Resource;
import net.modificationstation.stationapi.api.util.Identifier;
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.CallbackInfoReturnable;
-import uk.co.benjiweber.expressions.exception.Exceptions;
+import java.io.IOException;
import java.io.InputStream;
@Mixin(class_285.class)
@@ -20,6 +19,12 @@ class TexturePackMixin {
cancellable = true
)
private void stationapi_getFromResourceManager(String path, CallbackInfoReturnable cir) {
- ReloadableAssetsManager.INSTANCE.getResource(Identifier.of(path)).map(Exceptions.unchecked(Resource::getInputStream)).ifPresent(cir::setReturnValue);
+ ReloadableAssetsManager.INSTANCE.getResource(Identifier.of(path)).map(resource -> {
+ try {
+ return resource.getInputStream();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }).ifPresent(cir::setReturnValue);
}
}
diff --git a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/ZipTexturePackMixin.java b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/ZipTexturePackMixin.java
index c820a09b0..656eb8f88 100644
--- a/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/ZipTexturePackMixin.java
+++ b/station-resource-loader-v0/src/main/java/net/modificationstation/stationapi/mixin/resourceloader/client/ZipTexturePackMixin.java
@@ -3,14 +3,13 @@
import net.minecraft.class_285;
import net.minecraft.class_592;
import net.modificationstation.stationapi.api.client.resource.ReloadableAssetsManager;
-import net.modificationstation.stationapi.api.resource.Resource;
import net.modificationstation.stationapi.api.util.Identifier;
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.CallbackInfoReturnable;
-import uk.co.benjiweber.expressions.exception.Exceptions;
+import java.io.IOException;
import java.io.InputStream;
@Mixin(class_592.class)
@@ -21,6 +20,12 @@ class ZipTexturePackMixin extends class_285 {
cancellable = true
)
private void stationapi_getFromResourceManager(String path, CallbackInfoReturnable cir) {
- ReloadableAssetsManager.INSTANCE.getResource(Identifier.of(path)).map(Exceptions.unchecked(Resource::getInputStream)).ifPresent(cir::setReturnValue);
+ ReloadableAssetsManager.INSTANCE.getResource(Identifier.of(path)).map(resource -> {
+ try {
+ return resource.getInputStream();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }).ifPresent(cir::setReturnValue);
}
}
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..6b869e821 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
@@ -6,8 +6,7 @@
import net.modificationstation.stationapi.api.tag.TagKey;
import net.modificationstation.stationapi.api.util.Util;
-public interface StationHoeItem extends ToolLevel {
-
+public interface StationHoeItem extends StationTool {
@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..ff628e69e 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
@@ -6,8 +6,7 @@
import net.modificationstation.stationapi.api.tag.TagKey;
import net.modificationstation.stationapi.api.util.Util;
-public interface StationShearsItem extends ToolLevel {
-
+public interface StationShearsItem extends StationTool {
@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..2cde051bf 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
@@ -6,8 +6,7 @@
import net.modificationstation.stationapi.api.tag.TagKey;
import net.modificationstation.stationapi.api.util.Util;
-public interface StationSwordItem extends ToolLevel {
-
+public interface StationSwordItem extends StationTool {
@Override
default void setEffectiveBlocks(TagKey effectiveBlocks) {
Util.assertImpl();
diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationTool.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationTool.java
new file mode 100644
index 000000000..efc82b5a3
--- /dev/null
+++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/StationTool.java
@@ -0,0 +1,18 @@
+package net.modificationstation.stationapi.api.item.tool;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.ToolMaterial;
+import net.modificationstation.stationapi.api.tag.TagKey;
+
+/**
+ * This interface is injected into all tool items and "pseudo" tool items (such as {@link StationHoeItem},
+ * {@link StationShearsItem} and {@link StationSwordItem}) to provide the StationAPI's extended tools functionality.
+ */
+public interface StationTool {
+ void setEffectiveBlocks(TagKey effectiveBlocks);
+
+ TagKey getEffectiveBlocks(ItemStack stack);
+
+ ToolMaterial getMaterial(ItemStack stack);
+}
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..9cab5054d 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
@@ -6,8 +6,7 @@
import net.modificationstation.stationapi.api.tag.TagKey;
import net.modificationstation.stationapi.api.util.Util;
-public interface StationToolItem extends ToolLevel {
-
+public interface StationToolItem extends StationTool {
@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..61a32d7e0 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 toolLevel(ToolLevel toolLevel) {
return Util.assertImpl();
}
- default ToolMaterial requiredBlockTag(Identifier tag) {
+ default ToolLevel getToolLevel() {
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/TagToolLevel.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/TagToolLevel.java
new file mode 100644
index 000000000..fcf3ad989
--- /dev/null
+++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/api/item/tool/TagToolLevel.java
@@ -0,0 +1,30 @@
+package net.modificationstation.stationapi.api.item.tool;
+
+import net.minecraft.block.Block;
+import net.modificationstation.stationapi.api.tag.TagKey;
+
+/**
+ * This class is a simple implementation of {@link ToolLevel} in a tag-based approach.
+ *
+ *
+ * It tests if the block state in the context is tagged with the {@link TagKey}
+ * that this tool level was instantiated with. For example, needs_iron_tool.
+ *
+ */
+public class TagToolLevel extends ToolLevel {
+ public final TagKey tag;
+
+ public TagToolLevel(TagKey tag) {
+ this.tag = tag;
+ }
+
+ @Override
+ protected boolean isSuitable(TestContext context) {
+ return context.blockState().isIn(tag);
+ }
+
+ @Override
+ public String toString() {
+ return tag.toString();
+ }
+}
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..756500df3 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
@@ -1,15 +1,154 @@
package net.modificationstation.stationapi.api.item.tool;
-import net.minecraft.block.Block;
-import net.minecraft.item.ItemStack;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.graph.GraphBuilder;
+import com.google.common.graph.MutableGraph;
+import it.unimi.dsi.fastutil.objects.Reference2BooleanMap;
+import it.unimi.dsi.fastutil.objects.Reference2BooleanOpenHashMap;
import net.minecraft.item.ToolMaterial;
+import net.modificationstation.stationapi.api.block.BlockState;
+import net.modificationstation.stationapi.api.registry.BlockRegistry;
import net.modificationstation.stationapi.api.tag.TagKey;
+import net.modificationstation.stationapi.api.util.Util;
-public interface ToolLevel {
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
- void setEffectiveBlocks(TagKey effectiveBlocks);
+import static net.modificationstation.stationapi.api.util.Identifier.of;
- TagKey getEffectiveBlocks(ItemStack stack);
+public abstract class ToolLevel {
+ /**
+ * @param blockState the block state the tool level is being tested against.
+ * @param failed a collection of successor tool levels (as defined in {@link #GRAPH}) already tested in a run of
+ * {@link #isSuitable(ToolLevel, BlockState)} that ended up being not suitable.
+ * Each index corresponds to a level of the search down to the current point,
+ * 0 being the tool level assigned to the tool item itself, and size-1 being immediate successors
+ * (and siblings of successors) of the current level.
+ * Current level isn't reflected in the collection, as its iteration isn't deterministic.
+ * Can be used for complex context-aware suitability testing - e.g. limiting suitability
+ * to a fixed set of levels in the graph instead of making all succeeding levels also suitable.
+ * Special cases:
+ *
+ *
+ * Optional is empty - this means that the level is being tested in an unordered manner,
+ * thus keeping track of failed levels would yield no useful context. For example, this is done
+ * in {@link #isSuitable(ToolLevel, BlockState)} when the initial level's hierarchy was exhausted,
+ * but no match was found. In this case we need to iterate through {@link #ALL_LEVELS}
+ * in order to determine if the tested block state requires any level at all,
+ * thus if a tool level performs a test involving the absent collection,
+ * it must assume the collection matches the conditions, as to not hide a case where the level
+ * can actually be suitable.
+ *
+ *
+ * Collection is empty - this means that this tool level is the first one to be tested,
+ * thus it's also the one that the tool item was assigned to.
+ * Shouldn't normally require any special handling.
+ *
+ *
+ */
+ protected record TestContext(
+ BlockState blockState,
+ Optional>> failed
+ ) {}
- ToolMaterial getMaterial(ItemStack stack);
+ private static final Set ALL_LEVELS_MUTABLE = Collections.newSetFromMap(new WeakHashMap<>());
+ public static final Set ALL_LEVELS = Collections.unmodifiableSet(ALL_LEVELS_MUTABLE);
+ public static final MutableGraph GRAPH = GraphBuilder.directed().build();
+ private static final List NUMERIC_LEVELS = Util.make(new ArrayList<>(), list -> {
+ var stone = new TagToolLevel(TagKey.of(BlockRegistry.KEY, of("needs_stone_tool")));
+ var iron = new TagToolLevel(TagKey.of(BlockRegistry.KEY, of("needs_iron_tool")));
+ var diamond = new TagToolLevel(TagKey.of(BlockRegistry.KEY, of("needs_diamond_tool")));
+ list.add(null);
+ list.add(stone);
+ list.add(iron);
+ list.add(diamond);
+ GRAPH.putEdge(stone, iron);
+ GRAPH.putEdge(iron, diamond);
+ ToolMaterial.STONE.toolLevel(stone);
+ ToolMaterial.IRON.toolLevel(iron);
+ ToolMaterial.DIAMOND.toolLevel(diamond);
+ });
+
+ public static ToolLevel getNumeric(int level) {
+ if (level >= NUMERIC_LEVELS.size())
+ for (int i = NUMERIC_LEVELS.size(); i < level + 1; i++) {
+ var toolLevel = new TagToolLevel(TagKey.of(BlockRegistry.KEY, of("needs_tool_level_" + i)));
+ NUMERIC_LEVELS.add(toolLevel);
+ GRAPH.putEdge(NUMERIC_LEVELS.get(i - 1), toolLevel);
+ }
+ return NUMERIC_LEVELS.get(level);
+ }
+
+ public static boolean isSuitable(ToolLevel toolLevel, BlockState state) {
+ if (toolLevel == null) {
+ // Tool provides no level - can only mine blocks that don't require a level
+ var context = new TestContext(state, Optional.empty());
+ return ALL_LEVELS.stream().noneMatch(level -> level.isSuitable(context));
+ }
+ return toolLevel.cache.computeIfAbsent(state, key -> {
+ var failed = new ArrayList>();
+ var context = new TestContext(state, Optional.of(Collections.unmodifiableList(failed)));
+ var toolLevels = new HashSet();
+ toolLevels.add(toolLevel);
+
+ // Breadth-first search for a suitable level in the hierarchy
+ while (!toolLevels.isEmpty()) {
+ // Add immediate siblings of levels that allow them
+ toolLevels.addAll(toolLevels.stream()
+ .filter(level -> level.equivalentToImmediateSiblings)
+ .flatMap(level -> Stream.concat(
+ GRAPH.predecessors(level).stream().map(GRAPH::successors).flatMap(Set::stream),
+ GRAPH.successors(level).stream().map(GRAPH::predecessors).flatMap(Set::stream)
+ )).collect(Collectors.toSet())
+ );
+
+ var failedBuilder = ImmutableSet.builder();
+ var nextSet = new HashSet();
+ for (var level : toolLevels) {
+ if (level.isSuitable(context)) return true;
+ failedBuilder.add(level);
+ nextSet.addAll(GRAPH.predecessors(level));
+ }
+ failed.add(failedBuilder.build());
+ toolLevels = nextSet;
+
+ // Check for loops
+ var reoccurred = failed.stream().flatMap(Set::stream).filter(toolLevels::contains).collect(Collectors.toSet());
+ if (!reoccurred.isEmpty()) throw new IllegalStateException(
+ "Infinite loop detected in tool levels graph. Tested level - %s, search depth - %d, reoccurred levels - %s"
+ .formatted(toolLevel, failed.size(), reoccurred)
+ );
+ }
+
+ // Hierarchy exhausted, but no exit,
+ // So we need to test if the block requires any level,
+ // Because if it doesn't, the tool level is suitable.
+ var noFailedContext = new TestContext(context.blockState, Optional.empty());
+ var failedFlat = failed.stream().flatMap(Set::stream).collect(Collectors.toSet());
+ return ALL_LEVELS.stream().filter(Predicate.not(failedFlat::contains)).noneMatch(level -> level.isSuitable(noFailedContext));
+ });
+ }
+
+ protected final Reference2BooleanMap cache = new Reference2BooleanOpenHashMap<>();
+ protected boolean equivalentToImmediateSiblings;
+
+ protected ToolLevel() {
+ ALL_LEVELS_MUTABLE.add(this);
+ }
+
+ public ToolLevel equivalentToImmediateSiblings() {
+ equivalentToImmediateSiblings = true;
+ return this;
+ }
+
+ /**
+ * @param context the record containing available parameters for testing this tool level's suitability.
+ * @return whether this and only this tool level is suitable in the given context.
+ * Unless you know what you're doing, preceding tool levels must NOT be taken into account,
+ * as they will be tested directly, with their own implementation and better context,
+ * if this specific level isn't suitable.
+ */
+ protected abstract boolean isSuitable(TestContext context);
}
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..8a59790fc 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
@@ -2,16 +2,15 @@
import net.mine_diver.unsafeevents.listener.EventListener;
import net.modificationstation.stationapi.api.StationAPI;
-import net.modificationstation.stationapi.api.item.tool.ToolLevel;
+import net.modificationstation.stationapi.api.item.tool.StationTool;
import net.modificationstation.stationapi.api.util.Identifier;
@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) {
- if(!event.overrideShears && event.itemStack.getItem() instanceof ToolLevel)
- event.overrideShears = ((ToolLevel) event.itemStack.getItem()).getEffectiveBlocks(event.itemStack).id().equals(Identifier.of("mineable/shears"));
+ if(!event.overrideShears && event.itemStack.getItem() instanceof StationTool)
+ event.overrideShears = ((StationTool) event.itemStack.getItem()).getEffectiveBlocks(event.itemStack).id().equals(Identifier.of("mineable/shears"));
}
}
diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImpl.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImpl.java
new file mode 100644
index 000000000..34537e966
--- /dev/null
+++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImpl.java
@@ -0,0 +1,34 @@
+package net.modificationstation.stationapi.impl.item;
+
+import net.minecraft.item.ItemStack;
+import net.modificationstation.stationapi.api.block.BlockState;
+import net.modificationstation.stationapi.api.item.tool.StationTool;
+import net.modificationstation.stationapi.api.item.tool.ToolLevel;
+import net.modificationstation.stationapi.api.registry.BlockRegistry;
+import net.modificationstation.stationapi.api.registry.ItemRegistry;
+import net.modificationstation.stationapi.api.util.Namespace;
+
+import java.util.Objects;
+
+public class ToolEffectivenessImpl {
+ public static boolean shouldApplyCustomLogic(ItemStack item, BlockState state) {
+ // 1. Disable custom tool logic if both the block and the tool are vanilla
+ // This is done to preserve the vanilla mining speeds
+ // 2. Disable custom tool logic if the tool doesn't provide its tool type tag
+ // This is done to allow tools to handle suitability and speed the vanilla way
+ return (Objects.requireNonNull(ItemRegistry.INSTANCE.getId(item.getItem())).namespace != Namespace.MINECRAFT
+ || Objects.requireNonNull(BlockRegistry.INSTANCE.getId(state.getBlock())).namespace != Namespace.MINECRAFT)
+ && (!(item.getItem() instanceof StationTool stationTool)
+ || stationTool.getEffectiveBlocks(item) != null);
+ }
+
+ public static boolean isSuitableFor(ItemStack item, BlockState state) {
+ return item.getItem() instanceof StationTool stationTool
+ && state.isIn(stationTool.getEffectiveBlocks(item))
+ && ToolLevel.isSuitable(stationTool.getMaterial(item).getToolLevel(), state);
+ }
+
+ public static float getMiningSpeedMultiplier(ItemStack item) {
+ return ((StationTool) item.getItem()).getMaterial(item).getMiningSpeedMultiplier();
+ }
+}
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
deleted file mode 100644
index 258205d1d..000000000
--- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/impl/item/ToolEffectivenessImplV1.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package net.modificationstation.stationapi.impl.item;
-
-import net.mine_diver.unsafeevents.listener.EventListener;
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemStack;
-import net.modificationstation.stationapi.api.StationAPI;
-import net.modificationstation.stationapi.api.block.BlockState;
-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.ToolLevel;
-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.registry.ItemRegistry;
-import net.modificationstation.stationapi.api.util.Identifier;
-import net.modificationstation.stationapi.api.util.Namespace;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import static net.mine_diver.unsafeevents.listener.ListenerPriority.LOW;
-
-@Entrypoint(eventBus = @EventBusPolicy(registerInstance = false))
-@EventListener(phase = StationAPI.INTERNAL_PHASE)
-public class ToolEffectivenessImplV1 {
-
- public static final List VANILLA_TOOLS = new ArrayList<>();
-
- @EventListener(priority = LOW)
- private static void getItems(ItemRegistryEvent event) {
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.SHEARS));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.WOODEN_AXE));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.WOODEN_PICKAXE));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.WOODEN_SHOVEL));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.WOODEN_SWORD));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.STONE_HATCHET));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.STONE_PICKAXE));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.STONE_SHOVEL));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.STONE_SWORD));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.IRON_AXE));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.IRON_PICKAXE));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.IRON_SHOVEL));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.IRON_SWORD));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.DIAMOND_AXE));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.DIAMOND_PICKAXE));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.DIAMOND_SHOVEL));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.DIAMOND_SWORD));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.GOLDEN_AXE));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.GOLDEN_PICKAXE));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.GOLDEN_SHOVEL));
- VANILLA_TOOLS.add(ItemRegistry.INSTANCE.getId(Item.GOLDEN_SWORD));
- }
-
- @EventListener
- private static void isEffective(IsItemSuitableForStateEvent event) {
- event.suitable = 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();
- }
-
- private static boolean isSuitable(ItemStack item, BlockState state) {
- return item.getItem() instanceof ToolLevel toolLevel && state.isIn(toolLevel.getEffectiveBlocks(item)) && toolLevel.getMaterial(item).matches(state);
- }
-}
diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/HoeItemMixin.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/HoeItemMixin.java
index d29881aae..13582b068 100644
--- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/HoeItemMixin.java
+++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/HoeItemMixin.java
@@ -1,13 +1,19 @@
package net.modificationstation.stationapi.mixin.tools;
import net.minecraft.block.Block;
+import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.HoeItem;
+import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ToolMaterial;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.BlockView;
+import net.modificationstation.stationapi.api.block.BlockState;
import net.modificationstation.stationapi.api.item.tool.StationHoeItem;
import net.modificationstation.stationapi.api.registry.BlockRegistry;
import net.modificationstation.stationapi.api.tag.TagKey;
import net.modificationstation.stationapi.api.util.Identifier;
+import net.modificationstation.stationapi.impl.item.ToolEffectivenessImpl;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@@ -15,12 +21,16 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(HoeItem.class)
-class HoeItemMixin implements StationHoeItem {
+class HoeItemMixin extends Item implements StationHoeItem {
@Unique
private ToolMaterial stationapi_toolMaterial;
@Unique
private TagKey stationapi_effectiveBlocks;
+ protected HoeItemMixin(int id) {
+ super(id);
+ }
+
@Inject(method = "", at = @At("RETURN"))
private void stationapi_captureToolMaterial(int i, ToolMaterial arg, CallbackInfo ci) {
stationapi_toolMaterial = arg;
@@ -41,4 +51,16 @@ public TagKey getEffectiveBlocks(ItemStack stack) {
public ToolMaterial getMaterial(ItemStack stack) {
return stationapi_toolMaterial;
}
+
+ @Override
+ public boolean isSuitableFor(PlayerEntity player, ItemStack itemStack, BlockView blockView, BlockPos blockPos, BlockState state) {
+ return ToolEffectivenessImpl.shouldApplyCustomLogic(itemStack, state)
+ ? ToolEffectivenessImpl.isSuitableFor(itemStack, state) : super.isSuitableFor(player, itemStack, blockView, blockPos, state);
+ }
+
+ @Override
+ public float getMiningSpeedMultiplier(PlayerEntity player, ItemStack itemStack, BlockView blockView, BlockPos blockPos, BlockState state) {
+ return ToolEffectivenessImpl.shouldApplyCustomLogic(itemStack, state) && ToolEffectivenessImpl.isSuitableFor(itemStack, state)
+ ? ToolEffectivenessImpl.getMiningSpeedMultiplier(itemStack) : super.getMiningSpeedMultiplier(player, itemStack, blockView, blockPos, state);
+ }
}
diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ShearsItemMixin.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ShearsItemMixin.java
index add09f3fa..2804e8d10 100644
--- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ShearsItemMixin.java
+++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ShearsItemMixin.java
@@ -1,13 +1,19 @@
package net.modificationstation.stationapi.mixin.tools;
import net.minecraft.block.Block;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ShearsItem;
import net.minecraft.item.ToolMaterial;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.BlockView;
+import net.modificationstation.stationapi.api.block.BlockState;
import net.modificationstation.stationapi.api.item.tool.StationShearsItem;
import net.modificationstation.stationapi.api.registry.BlockRegistry;
import net.modificationstation.stationapi.api.tag.TagKey;
import net.modificationstation.stationapi.api.util.Identifier;
+import net.modificationstation.stationapi.impl.item.ToolEffectivenessImpl;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@@ -15,12 +21,16 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ShearsItem.class)
-class ShearsItemMixin implements StationShearsItem {
+class ShearsItemMixin extends Item implements StationShearsItem {
@Unique
private ToolMaterial stationapi_toolMaterial;
@Unique
private TagKey stationapi_effectiveBlocks;
+ protected ShearsItemMixin(int id) {
+ super(id);
+ }
+
@Inject(method = "", at = @At("RETURN"))
private void stationapi_captureToolMaterial(int i, CallbackInfo ci) {
stationapi_toolMaterial = ToolMaterial.IRON;
@@ -41,4 +51,16 @@ public TagKey getEffectiveBlocks(ItemStack stack) {
public ToolMaterial getMaterial(ItemStack stack) {
return stationapi_toolMaterial;
}
+
+ @Override
+ public boolean isSuitableFor(PlayerEntity player, ItemStack itemStack, BlockView blockView, BlockPos blockPos, BlockState state) {
+ return ToolEffectivenessImpl.shouldApplyCustomLogic(itemStack, state)
+ ? ToolEffectivenessImpl.isSuitableFor(itemStack, state) : super.isSuitableFor(player, itemStack, blockView, blockPos, state);
+ }
+
+ @Override
+ public float getMiningSpeedMultiplier(PlayerEntity player, ItemStack itemStack, BlockView blockView, BlockPos blockPos, BlockState state) {
+ return ToolEffectivenessImpl.shouldApplyCustomLogic(itemStack, state) && ToolEffectivenessImpl.isSuitableFor(itemStack, state)
+ ? ToolEffectivenessImpl.getMiningSpeedMultiplier(itemStack) : super.getMiningSpeedMultiplier(player, itemStack, blockView, blockPos, state);
+ }
}
diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/SwordItemMixin.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/SwordItemMixin.java
index a98d59a6f..e6ef693b2 100644
--- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/SwordItemMixin.java
+++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/SwordItemMixin.java
@@ -1,13 +1,19 @@
package net.modificationstation.stationapi.mixin.tools;
import net.minecraft.block.Block;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.SwordItem;
import net.minecraft.item.ToolMaterial;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.BlockView;
+import net.modificationstation.stationapi.api.block.BlockState;
import net.modificationstation.stationapi.api.item.tool.StationSwordItem;
import net.modificationstation.stationapi.api.registry.BlockRegistry;
import net.modificationstation.stationapi.api.tag.TagKey;
import net.modificationstation.stationapi.api.util.Identifier;
+import net.modificationstation.stationapi.impl.item.ToolEffectivenessImpl;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@@ -15,12 +21,16 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(SwordItem.class)
-class SwordItemMixin implements StationSwordItem {
+class SwordItemMixin extends Item implements StationSwordItem {
@Unique
private ToolMaterial stationapi_toolMaterial;
@Unique
private TagKey stationapi_effectiveBlocks;
+ protected SwordItemMixin(int id) {
+ super(id);
+ }
+
@Inject(method = "", at = @At("RETURN"))
private void stationapi_captureToolMaterial(int i, ToolMaterial arg, CallbackInfo ci) {
stationapi_toolMaterial = arg;
@@ -41,4 +51,16 @@ public TagKey getEffectiveBlocks(ItemStack stack) {
public ToolMaterial getMaterial(ItemStack stack) {
return stationapi_toolMaterial;
}
+
+ @Override
+ public boolean isSuitableFor(PlayerEntity player, ItemStack itemStack, BlockView blockView, BlockPos blockPos, BlockState state) {
+ return ToolEffectivenessImpl.shouldApplyCustomLogic(itemStack, state)
+ ? ToolEffectivenessImpl.isSuitableFor(itemStack, state) : super.isSuitableFor(player, itemStack, blockView, blockPos, state);
+ }
+
+ @Override
+ public float getMiningSpeedMultiplier(PlayerEntity player, ItemStack itemStack, BlockView blockView, BlockPos blockPos, BlockState state) {
+ return ToolEffectivenessImpl.shouldApplyCustomLogic(itemStack, state) && ToolEffectivenessImpl.isSuitableFor(itemStack, state)
+ ? ToolEffectivenessImpl.getMiningSpeedMultiplier(itemStack) : super.getMiningSpeedMultiplier(player, itemStack, blockView, blockPos, state);
+ }
}
diff --git a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolItemMixin.java b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolItemMixin.java
index f1c4270a5..3c8cff61a 100644
--- a/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolItemMixin.java
+++ b/station-tools-api-v1/src/main/java/net/modificationstation/stationapi/mixin/tools/ToolItemMixin.java
@@ -1,21 +1,31 @@
package net.modificationstation.stationapi.mixin.tools;
import net.minecraft.block.Block;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ToolItem;
import net.minecraft.item.ToolMaterial;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.BlockView;
+import net.modificationstation.stationapi.api.block.BlockState;
import net.modificationstation.stationapi.api.item.tool.StationToolItem;
import net.modificationstation.stationapi.api.tag.TagKey;
+import net.modificationstation.stationapi.impl.item.ToolEffectivenessImpl;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@Mixin(ToolItem.class)
-class ToolItemMixin implements StationToolItem {
+class ToolItemMixin extends Item implements StationToolItem {
@Shadow protected ToolMaterial toolMaterial;
@Unique
private TagKey stationapi_effectiveBlocks;
+ private ToolItemMixin(int id) {
+ super(id);
+ }
+
@Override
public void setEffectiveBlocks(TagKey effectiveBlocks) {
stationapi_effectiveBlocks = effectiveBlocks;
@@ -30,4 +40,16 @@ public TagKey getEffectiveBlocks(ItemStack stack) {
public ToolMaterial getMaterial(ItemStack stack) {
return toolMaterial;
}
+
+ @Override
+ public boolean isSuitableFor(PlayerEntity player, ItemStack itemStack, BlockView blockView, BlockPos blockPos, BlockState state) {
+ return ToolEffectivenessImpl.shouldApplyCustomLogic(itemStack, state)
+ ? ToolEffectivenessImpl.isSuitableFor(itemStack, state) : super.isSuitableFor(player, itemStack, blockView, blockPos, state);
+ }
+
+ @Override
+ public float getMiningSpeedMultiplier(PlayerEntity player, ItemStack itemStack, BlockView blockView, BlockPos blockPos, BlockState state) {
+ return ToolEffectivenessImpl.shouldApplyCustomLogic(itemStack, state) && ToolEffectivenessImpl.isSuitableFor(itemStack, state)
+ ? ToolEffectivenessImpl.getMiningSpeedMultiplier(itemStack) : super.getMiningSpeedMultiplier(player, itemStack, blockView, blockPos, 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..d18906574 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.StationToolMaterial;
-import net.modificationstation.stationapi.api.registry.BlockRegistry;
-import net.modificationstation.stationapi.api.tag.TagKey;
-import net.modificationstation.stationapi.api.util.Identifier;
+import net.modificationstation.stationapi.api.item.tool.ToolLevel;
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 ToolLevel stationapi_toolLevel;
@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 toolLevel(ToolLevel toolLevel) {
+ stationapi_toolLevel = toolLevel;
return ToolMaterial.class.cast(this);
}
@Override
@Unique
- public ReferenceSet getParentMaterials() {
- return stationapi_parentMaterialsView;
- }
-
- @Override
- @Unique
- public TagKey getRequiredBlockTag() {
- return stationapi_requiredBlockTag;
+ public ToolLevel getToolLevel() {
+ return stationapi_toolLevel;
}
}
diff --git a/station-tools-api-v1/src/main/resources/fabric.mod.json b/station-tools-api-v1/src/main/resources/fabric.mod.json
index 74820c91d..486cd263e 100644
--- a/station-tools-api-v1/src/main/resources/fabric.mod.json
+++ b/station-tools-api-v1/src/main/resources/fabric.mod.json
@@ -20,7 +20,6 @@
"environment": "*",
"entrypoints": {
"stationapi:event_bus": [
- "net.modificationstation.stationapi.impl.item.ToolEffectivenessImplV1",
"net.modificationstation.stationapi.impl.item.HijackShearsImplV1"
]
},
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
deleted file mode 100644
index c9cffd6bc..000000000
--- a/station-vanilla-fix-v0/src/main/java/net/modificationstation/stationapi/impl/vanillafix/item/tool/VanillaToolFixImpl.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package net.modificationstation.stationapi.impl.vanillafix.item.tool;
-
-import net.mine_diver.unsafeevents.listener.EventListener;
-import net.minecraft.item.ToolMaterial;
-import net.modificationstation.stationapi.api.StationAPI;
-import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent;
-import net.modificationstation.stationapi.api.mod.entrypoint.Entrypoint;
-import net.modificationstation.stationapi.api.mod.entrypoint.EventBusPolicy;
-
-import static net.modificationstation.stationapi.api.util.Identifier.of;
-
-@Entrypoint(eventBus = @EventBusPolicy(registerInstance = false))
-@EventListener(phase = StationAPI.INTERNAL_PHASE)
-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"));
- }
-}
diff --git a/station-vanilla-fix-v0/src/main/resources/fabric.mod.json b/station-vanilla-fix-v0/src/main/resources/fabric.mod.json
index 3a62cd009..c795cf13d 100644
--- a/station-vanilla-fix-v0/src/main/resources/fabric.mod.json
+++ b/station-vanilla-fix-v0/src/main/resources/fabric.mod.json
@@ -23,7 +23,6 @@
"net.modificationstation.stationapi.impl.vanillafix.block.VanillaBlockFixImpl",
"net.modificationstation.stationapi.impl.vanillafix.item.VanillaItemFixImpl",
"net.modificationstation.stationapi.impl.vanillafix.dimension.VanillaDimensionFixImpl",
- "net.modificationstation.stationapi.impl.vanillafix.item.tool.VanillaToolFixImpl",
"net.modificationstation.stationapi.impl.vanillafix.recipe.VanillaFuelItemFixImpl",
"net.modificationstation.stationapi.impl.vanillafix.datafixer.VanillaDataFixerImpl"
],