Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ subprojects {

dependencies {
minecraft "com.mojang:minecraft:${minecraft_version}"
implementation(annotationProcessor("io.github.llamalad7:mixinextras-common:0.3.5"))

// layered mappings - Mojmap names, parchment and QM docs and parameters
mappings(loom.layered {
it.parchment("org.parchmentmc.data:parchment-${minecraft_version}:${parchment_version}@zip")
Expand Down
1 change: 0 additions & 1 deletion common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ sourceSets {

dependencies {
modImplementation("net.fabricmc:fabric-loader:${fabric_loader_version}")
implementation(annotationProcessor("io.github.llamalad7:mixinextras-common:0.3.5"))
implementation(annotationProcessor("com.github.bawnorton.mixinsquared:mixinsquared-fabric:0.3.7-beta.1"))

implementation(("io.github.llamalad7:mixinextras-common:0.4.1"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.valkyrienskies.clockwork;

import net.minecraft.core.Direction;

/**
* This rather sus class exists for the purpose of storing a public static variable (clicked face)
* to be set in MixinLinkedControllerItem and accessed from MixinLinkedControllerClientHandler
*/
public class LinkedControllerClientHandlerMixinStorage {
public static Direction face;

public static void doNothing() {
System.out.println("I hate kotlin sometimes");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package org.valkyrienskies.clockwork.mixin.content.flap_bearing;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import com.simibubi.create.content.redstone.link.LinkBehaviour;
import com.simibubi.create.content.redstone.link.controller.LinkedControllerClientHandler;
import com.simibubi.create.content.redstone.link.controller.LinkedControllerItem;
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Coerce;
import org.valkyrienskies.clockwork.ClockworkBlocks;
import org.valkyrienskies.clockwork.ClockworkPackets;
import org.valkyrienskies.clockwork.LinkedControllerClientHandlerMixinStorage;
import org.valkyrienskies.clockwork.content.contraptions.flap.smart_flap.FlapLinkedControllerBindPacket;


@Mixin(LinkedControllerClientHandler.class)
public class MixinLinkedControllerClientHandler {

@Shadow
private static BlockPos selectedLocation;

@WrapOperation(
method = "tick",
at = @At(value = "INVOKE", target = "Lcom/simibubi/create/foundation/blockEntity/behaviour/BlockEntityBehaviour;get(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lcom/simibubi/create/foundation/blockEntity/behaviour/BehaviourType;)Lcom/simibubi/create/foundation/blockEntity/behaviour/BlockEntityBehaviour;"),
remap = false
)
private static <T extends BlockEntityBehaviour> T wrapGetBehaviour(BlockGetter be, BlockPos e, BehaviourType<T> reader, Operation<T> original) {
// Clockwork flap bearing will never return the LinkBehaviour create is wanting, since it's using a custom behaviour.
// However, we still have to pass a null check, hence the weird sus null LinkBehaviour.
if (!ClockworkBlocks.SMART_FLAP_BEARING.has(be.getBlockState(e))) return original.call(be, e, reader);

// Just needs to be a not-null be behaviour to pass a null check
return (T) LinkBehaviour.receiver(null, Pair.of(null, null), null);
}


@WrapOperation(
method = "tick",
at = @At(value = "INVOKE", target = "Lme/pepperbell/simplenetworking/SimpleChannel;sendToServer(Lme/pepperbell/simplenetworking/C2SPacket;)V", ordinal = 3),
require = 0,
remap = false
)
private static void wrapSendToServerFabric(@Coerce Object instance, @Coerce Object packet, Operation<Void> original, @Local LinkBehaviour l, @Local Integer button) {
wrapSendToServerCommon(instance, packet, original, l, button);
}

@WrapOperation(
method = "tick",
at = @At(value = "INVOKE", target = "Lnet/minecraftforge/network/simple/SimpleChannel;sendToServer(Ljava/lang/Object;)V", ordinal = 3),
require = 0,
remap = false
)
private static void wrapSendToServerForge(@Coerce Object instance, @Coerce Object packet, Operation<Void> original, @Local LinkBehaviour l, @Local Integer button) {
wrapSendToServerCommon(instance, packet, original, l, button);
}

@Unique
private static void wrapSendToServerCommon(Object instance, Object packet, Operation<Void> original, LinkBehaviour l, Integer button) {
// No one else should be stupid enough to be passing in a LinkBehaviour with a null be
if (l.blockEntity != null) {
original.call(instance, packet);
return;
}
ClockworkPackets.sendToServer(new FlapLinkedControllerBindPacket(button, selectedLocation, LinkedControllerClientHandlerMixinStorage.face, LinkedControllerItem.class.getName()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.valkyrienskies.clockwork.mixin.content.flap_bearing;

import com.simibubi.create.content.redstone.link.controller.LinkedControllerClientHandler;
import com.simibubi.create.content.redstone.link.controller.LinkedControllerItem;
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import net.createmod.catnip.data.Iterate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.valkyrienskies.clockwork.ClockworkBlocks;
import org.valkyrienskies.clockwork.LinkedControllerClientHandlerMixinStorage;
import org.valkyrienskies.clockwork.content.contraptions.flap.dual_link.DualLinkBehaviour;
import org.valkyrienskies.clockwork.platform.PlatformUtils;

import static org.valkyrienskies.clockwork.content.contraptions.flap.dual_link.DualLinkHandler.getFrontFacing;

@Mixin(LinkedControllerItem.class)
public class MixinLinkedControllerItem {
@Shadow
private void toggleBindMode(BlockPos pos) {}

@Unique
public Direction clickedFace = null;

@Inject(
method = "onItemUseFirst",
at = @At("HEAD"),
remap = false,
cancellable = true
)
private void injectStateCheck(ItemStack stack, UseOnContext ctx, CallbackInfoReturnable<InteractionResult> cir) {
// region Copied from beginning of create method
Player player = ctx.getPlayer();
if (player == null) return;
Level world = ctx.getLevel();
BlockPos pos = ctx.getClickedPos();
BlockState hitState = world.getBlockState(pos);
// endregion

if (!player.mayBuild()) return;
if (player.isShiftKeyDown()) return;

if (ClockworkBlocks.SMART_FLAP_BEARING.has(hitState)) {
clickedFace = ctx.getClickedFace();

if (!(clickedFace == getFrontFacing(hitState) || clickedFace == getFrontFacing(hitState).getOpposite())) return;

if (world.isClientSide)
PlatformUtils.getEnvExecutor(() -> () -> toggleBindMode(ctx.getClickedPos()));
player.getCooldowns()
.addCooldown((Item)(Object)this, 2);
cir.setReturnValue(InteractionResult.SUCCESS);
cir.cancel();
}

}

@Inject(
method = "toggleBindMode",
at = @At("HEAD"),
remap = false
)
private void injectToggleBindMode(BlockPos pos, CallbackInfo ci) {
LinkedControllerClientHandlerMixinStorage.face = clickedFace;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.Entity
import net.minecraft.world.level.Level
import org.valkyrienskies.clockwork.client.render.airpocket.AirpocketSyncPacket
import org.valkyrienskies.clockwork.content.contraptions.flap.smart_flap.FlapLinkedControllerBindPacket
import org.valkyrienskies.clockwork.content.curiosities.altmeter.UpdateAltMeterPacket
import org.valkyrienskies.clockwork.content.contraptions.phys.infuser.PhysicsInfuserSyncPacket
import org.valkyrienskies.clockwork.content.contraptions.phys.slicker.SlickerAttachmentSyncPacket
Expand Down Expand Up @@ -76,7 +77,9 @@ enum class ClockworkPackets(
NODE_SYNC(KNodeSyncPacket::class.java, ::KNodeSyncPacket),

UNIVERSAL_JOINT_ITEM_PACKET(UniversalJointItemPacket::class.java, ::UniversalJointItemPacket),
AIRPOCKET_SYNC_PACKET(AirpocketSyncPacket::class.java, ::AirpocketSyncPacket)
AIRPOCKET_SYNC_PACKET(AirpocketSyncPacket::class.java, ::AirpocketSyncPacket),

FLAP_LINKED_CONTROLLER_BIND_PACKET(FlapLinkedControllerBindPacket::class.java, ::FlapLinkedControllerBindPacket),

;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,10 @@ object DualLinkHandler {

if (!state.hasProperty(BlockStateProperties.FACING) || !state.hasProperty(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE)) return EventResult.pass()


val type: BehaviourType<DualLinkBehaviour>
if (face == getFrontFacing(state)) type = DualLinkBehaviour.FRONT_TYPE
else type = DualLinkBehaviour.BACK_TYPE



val behaviour = BlockEntityBehaviour.get(world, pos, type)
?: return EventResult.pass()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package org.valkyrienskies.clockwork.content.contraptions.flap.smart_flap

import com.simibubi.create.AllItems
import com.simibubi.create.content.redstone.link.RedstoneLinkNetworkHandler
import com.simibubi.create.content.redstone.link.controller.LinkedControllerItem
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.nbt.Tag
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.world.InteractionHand
import net.minecraft.world.item.ItemStack
import org.valkyrienskies.clockwork.LinkedControllerClientHandlerMixinStorage
import org.valkyrienskies.clockwork.LinkedControllerClientHandlerMixinStorage.doNothing
import org.valkyrienskies.clockwork.content.contraptions.flap.dual_link.DualLinkBehaviour
import org.valkyrienskies.clockwork.content.contraptions.flap.dual_link.DualLinkHandler.getFrontFacing
import org.valkyrienskies.clockwork.platform.api.network.C2SCWPacket
import org.valkyrienskies.clockwork.platform.api.network.ServerNetworkContext

class FlapLinkedControllerBindPacket(var button: Int, var linkLocation: BlockPos, var face: Direction, var itemClassName: String): C2SCWPacket {
constructor(buffer: FriendlyByteBuf) : this(buffer.readVarInt(), buffer.readBlockPos(), buffer.readEnum(Direction::class.java), buffer.readUtf())

override fun write(buffer: FriendlyByteBuf) {
buffer.writeVarInt(button)
buffer.writeBlockPos(linkLocation)
buffer.writeEnum(face)
buffer.writeUtf(itemClassName)
}

override fun handle(context: ServerNetworkContext) {
context.enqueueWork {
val player = context.sender
if (player.isSpectator) return@enqueueWork

var controller = player.mainHandItem

// We use reflection for this as a lazy way to use TweakedLinkedControllerItem instead of LinkedControllerItem
// (also we have to use reflection on it later anyway, so we might as well)
val itemClass = Class.forName(itemClassName)

if (!itemClass.isInstance(controller.item)) {
controller = player.offhandItem
if (!itemClass.isInstance(controller.item)) return@enqueueWork
}

doNothing()

val getFrequencyItems = itemClass.getDeclaredMethod("getFrequencyItems", ItemStack::class.java)

val frequencyItems = getFrequencyItems.invoke(null, controller)

val type: BehaviourType<DualLinkBehaviour> =
if (face == getFrontFacing(player.level().getBlockState(linkLocation))) DualLinkBehaviour.FRONT_TYPE
else DualLinkBehaviour.BACK_TYPE

val linkBehaviour = BlockEntityBehaviour.get(player.level(), linkLocation, type) ?: return@enqueueWork

// For some BRAIN DEAD REASON, the package for ItemHandler in porting lib and ItemHandler in forge are DIFFERENT
// They don't even extend a common class, so I'm just using reflection because fuck it.
val setStackInSlot = frequencyItems::class.java.getDeclaredMethod("setStackInSlot", Integer::class.javaPrimitiveType, ItemStack::class.java)
val serializeNbt = frequencyItems::class.java.getDeclaredMethod("serializeNBT")

linkBehaviour.networkKey
.forEachWithContext { f: RedstoneLinkNetworkHandler.Frequency, first: Boolean ->
setStackInSlot.invoke(frequencyItems, button * 2 + (if (first) 0 else 1), f.stack
.copy())
}

controller.tag!!
.put("Items", serializeNbt.invoke(frequencyItems) as Tag)
}
context.setPacketHandled(true)
}
}
2 changes: 2 additions & 0 deletions common/src/main/resources/vs_clockwork-common.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"content.blade.RepairItemRecipeMixin",
"content.blade.SawBladeRecipeMixin",
"content.exhaust.MixinAirCurrent",
"content.flap_bearing.MixinLinkedControllerClientHandler",
"content.flap_bearing.MixinLinkedControllerItem",
"content.gas.MixinBacktankUtil",
"content.gas.MixinComposterBlock",
"content.gas_engine.MixinSteamEngineBlock",
Expand Down
6 changes: 4 additions & 2 deletions fabric/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ dependencies {
exclude(group: "net.fabricmc.fabric-api")
}

modCompileOnly("cc.tweaked:cc-tweaked-${minecraft_version}-fabric-api:${cc_version}")
//modRuntimeOnly("cc.tweaked:cc-tweaked-${minecraft_version}-fabric:${cc_version}")

modCompileOnly("cc.tweaked:cc-tweaked-$minecraft_version-fabric-api:$cc_version")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my attempts at fixing CC, not what caused it to break

modRuntimeOnly("cc.tweaked:cc-tweaked-$minecraft_version-fabric:$cc_version")

//JEI
//modRuntimeOnly("mezz.jei:jei-${minecraft_version}-fabric:${jei_version_fabric}")
Expand Down Expand Up @@ -169,6 +170,7 @@ components.java {
}
}


publishing {
publications {
mavenFabric(MavenPublication) {
Expand Down
17 changes: 17 additions & 0 deletions forge/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ repositories {
}
}
maven { url = "https://jitpack.io/" }

exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
filter {
includeGroup "maven.modrinth"
}
}
}
}

Expand Down Expand Up @@ -109,6 +121,8 @@ dependencies {
modCompileOnly("dev.engine-room.flywheel:flywheel-forge-api-${minecraft_version}:${flywheel_forge_version}")
modRuntimeOnly("dev.engine-room.flywheel:flywheel-forge-${minecraft_version}:${flywheel_forge_version}")

modCompileOnly("maven.modrinth:valkyrien-warium:0.3.1")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops how did that sneak in


// JOML
compileOnly("org.joml:joml:1.10.4")
compileOnly("org.joml:joml-primitives:1.10.0")
Expand All @@ -121,6 +135,9 @@ dependencies {
modCompileOnly("cc.tweaked:cc-tweaked-$minecraft_version-forge-api:$cc_version")
modRuntimeOnly("cc.tweaked:cc-tweaked-$minecraft_version-forge:$cc_version")

//modRuntimeOnly("maven.modrinth:create-connected:saiZ8AwJ")
modImplementation ("maven.modrinth:create-tweaked-controllers:aHqvR8LC")

//Spark profiler
//modRuntimeOnly("maven.modrinth:spark:1.10.53-forge")

Expand Down
Loading