diff --git a/src/main/java/com/blockninja/counterclockwise/mixin/PhysShipAttachmentAccessor.java b/src/main/java/com/blockninja/counterclockwise/mixin/PhysShipAttachmentAccessor.java new file mode 100644 index 0000000..079a6d6 --- /dev/null +++ b/src/main/java/com/blockninja/counterclockwise/mixin/PhysShipAttachmentAccessor.java @@ -0,0 +1,14 @@ +package com.blockninja.counterclockwise.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.valkyrienskies.core.api.ships.ShipPhysicsListener; +import org.valkyrienskies.core.impl.game.ships.PhysShipImpl; + +import java.util.List; + +@Mixin(PhysShipImpl.class) +public interface PhysShipAttachmentAccessor { + @Accessor("physicsListeners") + List getPhysicsListeners(); +} diff --git a/src/main/kotlin/com/blockninja/counterclockwise/VSEvents.kt b/src/main/kotlin/com/blockninja/counterclockwise/VSEvents.kt index a133668..fdb0828 100644 --- a/src/main/kotlin/com/blockninja/counterclockwise/VSEvents.kt +++ b/src/main/kotlin/com/blockninja/counterclockwise/VSEvents.kt @@ -1,5 +1,6 @@ package com.blockninja.counterclockwise +import com.blockninja.counterclockwise.mixin.PhysShipAttachmentAccessor import com.blockninja.counterclockwise.ships.BeltStorageForceInducer import com.mojang.datafixers.util.Pair import net.minecraft.core.BlockPos @@ -8,16 +9,13 @@ import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerLevel import net.minecraft.world.level.Level import net.minecraft.world.phys.AABB -import net.minecraftforge.server.ServerLifecycleHooks import org.joml.Vector3d import org.joml.Vector3dc import org.valkyrienskies.core.api.event.RegisteredListener import org.valkyrienskies.core.api.events.CollisionEvent -import org.valkyrienskies.core.api.ships.LoadedServerShip import org.valkyrienskies.core.api.util.GameTickOnly import org.valkyrienskies.core.api.util.PhysTickOnly import org.valkyrienskies.mod.common.ValkyrienSkiesMod -import org.valkyrienskies.mod.common.shipObjectWorld import org.valkyrienskies.mod.common.util.toMinecraft import kotlin.math.abs @@ -35,7 +33,7 @@ object VSEvents { // Shouldn't ever happen, would be a world-world collision if (mainShip == null) return - val server = ServerLifecycleHooks.getCurrentServer() + // val server = ServerLifecycleHooks.getCurrentServer() val level = registeryDimToLevel(collisionEvent.dimensionId) @@ -53,72 +51,69 @@ object VSEvents { println("Cme wuh oh") } + // should be better than try catching a ConcurrentModificationException right? even if it has to iterate through + // every attachment. + val physicsListeners = (mainShip as PhysShipAttachmentAccessor).physicsListeners + var inducer : BeltStorageForceInducer? = null - // HELLA sussy - // But ruby said I could do it - val serverShip: LoadedServerShip? - try { - serverShip = server.shipObjectWorld.loadedShips.getById(mainShip.id) - } catch (cme: ConcurrentModificationException) { - // Bad luck, do nothing, better luck next time - return + for (listener in physicsListeners) { + if (listener is BeltStorageForceInducer) { + inducer = listener + } } - if (serverShip != null) { - val inducer = serverShip.getAttachment(BeltStorageForceInducer::class.java) - if (inducer != null) { - val matchingContacts: MutableList> = - ArrayList>() - - for (contact in collisionEvent.contactPoints) { - val contactWorldPos = contact.position - - for (blockPosLong in inducer.beltLocations.keys) { - // Belt is in shipyard, but collision is in world, so we transform world -> ship to check against belt AABB - val shipCollisionPos = - mainShip.transform.worldToShip.transformPosition(contactWorldPos, Vector3d()) - - // TODO: replace with collision shape - val beltPos = BlockPos.of(blockPosLong) - var beltAABB = AABB( - beltPos.x.toDouble(), - beltPos.y.toDouble(), - beltPos.z.toDouble(), - (beltPos.x + 1).toDouble(), - (beltPos.y + 1).toDouble(), - (beltPos.z + 1).toDouble() - ) - beltAABB = beltAABB.inflate(0.1) - - if (beltAABB.contains(shipCollisionPos.toMinecraft())) { - println("e") - matchingContacts.add( - Pair( - contactWorldPos, - inducer.beltLocations.get(blockPosLong) - ) + if (inducer != null) { + val matchingContacts: MutableList> = + ArrayList>() + + for (contact in collisionEvent.contactPoints) { + val contactWorldPos = contact.position + + for (blockPosLong in inducer.beltLocations.keys) { + // Belt is in shipyard, but collision is in world, so we transform world -> ship to check against belt AABB + val shipCollisionPos = + mainShip.transform.worldToShip.transformPosition(contactWorldPos, Vector3d()) + + // TODO: replace with collision shape + val beltPos = BlockPos.of(blockPosLong) + var beltAABB = AABB( + beltPos.x.toDouble(), + beltPos.y.toDouble(), + beltPos.z.toDouble(), + (beltPos.x + 1).toDouble(), + (beltPos.y + 1).toDouble(), + (beltPos.z + 1).toDouble() + ) + beltAABB = beltAABB.inflate(0.1) + + if (beltAABB.contains(shipCollisionPos.toMinecraft())) { + println("e") + matchingContacts.add( + Pair( + contactWorldPos, + inducer.beltLocations.get(blockPosLong) ) - } + ) } } + } - for (pair in matchingContacts) { - // Collision point world -> ship - val forcePos = Vector3d(pair.getFirst()) - mainShip.transform.worldToShip.transformPosition(forcePos) + for (pair in matchingContacts) { + // Collision point world -> ship + val forcePos = Vector3d(pair.getFirst()) + mainShip.transform.worldToShip.transformPosition(forcePos) - // Collision point ship -> COM offset - forcePos.add(0.5, 0.5, 0.5) - .sub(mainShip.transform.positionInShip) + // Collision point ship -> COM offset + forcePos.add(0.5, 0.5, 0.5) + .sub(mainShip.transform.positionInShip) - val forceDir = pair.getSecond()!!.direction.step() - mainShip.transform.shipToWorld.transformDirection(forceDir) + val forceDir = pair.getSecond()!!.direction.step() + mainShip.transform.shipToWorld.transformDirection(forceDir) - mainShip.applyInvariantForceToPos( - Vector3d(forceDir).mul(mainShip.mass).mul((abs(pair.getSecond()!!.speed) * 48).toDouble()), - forcePos - ) - } + mainShip.applyInvariantForceToPos( + Vector3d(forceDir).mul(mainShip.mass).mul((abs(pair.getSecond()!!.speed) * 48).toDouble()), + forcePos + ) } } diff --git a/src/main/resources/counterclockwise.mixins.json b/src/main/resources/counterclockwise.mixins.json index 5ea3480..1c8e898 100644 --- a/src/main/resources/counterclockwise.mixins.json +++ b/src/main/resources/counterclockwise.mixins.json @@ -5,6 +5,7 @@ "compatibilityLevel": "JAVA_17", "refmap": "counterclockwise.refmap.json", "mixins": [ + "PhysShipAttachmentAccessor", "create.belt_tracks.MixinBeltBlock", "create.belt_tracks.MixinBeltBlockEntity", "create.fan.MixinEncasedFanBlock",