diff --git a/src/main/java/net/jcm/vsch/blocks/VSCHBlocks.java b/src/main/java/net/jcm/vsch/blocks/VSCHBlocks.java index f4c909a..218a658 100644 --- a/src/main/java/net/jcm/vsch/blocks/VSCHBlocks.java +++ b/src/main/java/net/jcm/vsch/blocks/VSCHBlocks.java @@ -52,10 +52,10 @@ public class VSCHBlocks { .strength(5f) .noOcclusion())); - /*public static final RegistryObject MAGNET_BLOCK = registerBlock("magnet_block", + public static final RegistryObject MAGNET_BLOCK = registerBlock("magnet_block", () -> new MagnetBlock(BlockBehaviour.Properties.copy(Blocks.IRON_BLOCK).sound(SoundType.COPPER) .strength(5f) - .noOcclusion()));*/ + .noOcclusion())); //below is just tools used in adding the block diff --git a/src/main/java/net/jcm/vsch/blocks/custom/MagnetBlock.java b/src/main/java/net/jcm/vsch/blocks/custom/MagnetBlock.java index 2c0a879..0c87d0a 100644 --- a/src/main/java/net/jcm/vsch/blocks/custom/MagnetBlock.java +++ b/src/main/java/net/jcm/vsch/blocks/custom/MagnetBlock.java @@ -6,8 +6,10 @@ import net.jcm.vsch.blocks.entity.template.ParticleBlockEntity; import net.jcm.vsch.config.VSCHConfig; import net.jcm.vsch.ship.DraggerData; +import net.jcm.vsch.ship.MagnetData; import net.jcm.vsch.ship.ThrusterData; import net.jcm.vsch.ship.VSCHForceInducedShips; +import net.jcm.vsch.util.LevelBlockPos; import net.jcm.vsch.util.rot.DirectionalShape; import net.jcm.vsch.util.rot.RotShape; import net.jcm.vsch.util.rot.RotShapes; @@ -23,6 +25,7 @@ import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.DirectionalBlock; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.entity.BlockEntity; @@ -32,9 +35,11 @@ import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.phys.BlockHitResult; +import org.valkyrienskies.mod.common.util.DimensionIdProvider; +import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; -public class MagnetBlock extends BlockWithEntity { +public class MagnetBlock extends DirectionalBlock implements EntityBlock { public MagnetBlock(Properties properties) { super(properties); @@ -60,11 +65,26 @@ public void onRemove(BlockState state, Level level, BlockPos pos, BlockState new return; } - // ----- Remove the thruster from the force appliers for the current level ----- // - // I guess VS does this automatically when switching a shipyards dimension? VSCHForceInducedShips ships = VSCHForceInducedShips.get(level, pos); if (ships != null) { - //ships.removeDragger(pos); + ships.removeMagnet(pos); + } else { + VSCHForceInducedShips.worldMagnets.remove(new LevelBlockPos(pos, level)); + } + } + + @Override + public void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean pMovedByPiston) { + super.onPlace(state, level, pos, oldState, pMovedByPiston); + if (!(level instanceof ServerLevel)) { + return; + } + + VSCHForceInducedShips ships = VSCHForceInducedShips.get(level, pos); + if (ships != null) { + ships.addMagnet(pos, new MagnetData(VectorConversionsMCKt.toJOMLD(state.getValue(FACING).getNormal()))); + } else { + VSCHForceInducedShips.worldMagnets.put(new LevelBlockPos(pos, level), new MagnetData(VectorConversionsMCKt.toJOMLD(state.getValue(FACING).getNormal()))); } } @@ -78,46 +98,14 @@ public BlockState getStateForPlacement(BlockPlaceContext ctx) { .setValue(BlockStateProperties.FACING, dir); } - /*@Override - public List getDrops(BlockState state, LootContext.Builder builder) { - List drops = new ArrayList<>(super.getDrops(state, builder)); - int tier = state.getValue(TournamentProperties.TIER); - if (tier > 1) { - drops.add(new ItemStack(TournamentItems.UPGRADE_THRUSTER.get(), tier - 1)); - } - return drops; - }*/ - - @SuppressWarnings("deprecation") - @Override - public void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, BlockPos fromPos, boolean isMoving) { - super.neighborChanged(state, level, pos, block, fromPos, isMoving); - - if (!(level instanceof ServerLevel)) return; - - int signal = level.getBestNeighborSignal(pos); - VSCHForceInducedShips ships = VSCHForceInducedShips.get(level, pos); - - if (ships != null) { - /*DraggerData data = ships.getDraggerAtPos(pos); - - if (data != null) { - data.on = (signal > 0); - }*/ - } - } - // Attach block entity @Override public MagnetBlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new MagnetBlockEntity(pos, state); } - /*public static BlockEntityTicker getTickerHelper(Level level) { - return level.isClientSide() && !allowClient ? null : (level0, pos0, state0, blockEntity) -> ((TickableBlockEntity)blockEntity).tick(); - }*/ @Override public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType type) { - return level.isClientSide() ? (ParticleBlockEntity::clientTick) : ParticleBlockEntity::serverTick; + return (level0, pos, state0, be) -> ((MagnetBlockEntity) be).tick(); } } diff --git a/src/main/java/net/jcm/vsch/blocks/entity/MagnetBlockEntity.java b/src/main/java/net/jcm/vsch/blocks/entity/MagnetBlockEntity.java index e1299a5..24d4614 100644 --- a/src/main/java/net/jcm/vsch/blocks/entity/MagnetBlockEntity.java +++ b/src/main/java/net/jcm/vsch/blocks/entity/MagnetBlockEntity.java @@ -1,40 +1,16 @@ package net.jcm.vsch.blocks.entity; -import net.jcm.vsch.blocks.custom.template.BlockEntityWithEntity; -import net.jcm.vsch.entity.MagnetEntity; -import net.jcm.vsch.entity.VSCHEntities; -import net.jcm.vsch.ship.VSCHForceInducedShips; import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; -public class MagnetBlockEntity extends BlockEntityWithEntity { +public class MagnetBlockEntity extends BlockEntity { public MagnetBlockEntity(BlockPos pos, BlockState state) { - super(VSCHBlockEntities.DRAG_INDUCER_BLOCK_ENTITY.get(), pos, state); + super(VSCHBlockEntities.MAGNET_BLOCK_ENTITY.get(), pos, state); } - @Override - public void tickForce(ServerLevel level, BlockPos pos, BlockState state) { - this.spawnLinkedEntityIfNeeded(); - super.tickForce(level, pos, state); + public void tick() { - // ----- Add thruster to the force appliers for the current level ----- // - - int signal = level.getBestNeighborSignal(pos); - VSCHForceInducedShips ships = VSCHForceInducedShips.get(level, pos); - - if (ships != null) { - /*if (ships.getDraggerAtPos(pos) == null) { - ships.addDragger(pos, new DraggerData(signal > 0)); - }*/ - } - } - - @Override - public MagnetEntity createLinkedEntity(ServerLevel level, BlockPos pos) { - return new MagnetEntity(VSCHEntities.MAGNET_ENTITY.get(), level, pos); } } diff --git a/src/main/java/net/jcm/vsch/blocks/entity/VSCHBlockEntities.java b/src/main/java/net/jcm/vsch/blocks/entity/VSCHBlockEntities.java index b090fb3..545d8b0 100644 --- a/src/main/java/net/jcm/vsch/blocks/entity/VSCHBlockEntities.java +++ b/src/main/java/net/jcm/vsch/blocks/entity/VSCHBlockEntities.java @@ -32,6 +32,11 @@ public class VSCHBlockEntities { () -> BlockEntityType.Builder.of(DragInducerBlockEntity::new, VSCHBlocks.DRAG_INDUCER_BLOCK.get()) .build(null)); + public static final RegistryObject> MAGNET_BLOCK_ENTITY = + BLOCK_ENTITIES.register("magnet_block", + () -> BlockEntityType.Builder.of(MagnetBlockEntity::new, VSCHBlocks.MAGNET_BLOCK.get()) + .build(null)); + public static final RegistryObject> GRAVITY_INDUCER_BLOCK_ENTITY = BLOCK_ENTITIES.register("gravity_inducer_block", () -> BlockEntityType.Builder.of(GravityInducerBlockEntity::new, VSCHBlocks.GRAVITY_INDUCER_BLOCK.get()) diff --git a/src/main/java/net/jcm/vsch/event/AtmosphericCollision.java b/src/main/java/net/jcm/vsch/event/AtmosphericCollision.java index b3cd17e..89c8f28 100644 --- a/src/main/java/net/jcm/vsch/event/AtmosphericCollision.java +++ b/src/main/java/net/jcm/vsch/event/AtmosphericCollision.java @@ -1,6 +1,5 @@ package net.jcm.vsch.event; -import net.jcm.vsch.util.TeleportUtils; import net.jcm.vsch.util.TeleportationHandler; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.LevelAccessor; diff --git a/src/main/java/net/jcm/vsch/event/PhysTick.java b/src/main/java/net/jcm/vsch/event/PhysTick.java new file mode 100644 index 0000000..7b50a3c --- /dev/null +++ b/src/main/java/net/jcm/vsch/event/PhysTick.java @@ -0,0 +1,117 @@ +package net.jcm.vsch.event; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import net.jcm.vsch.ship.VSCHForceInducedShips; +import net.minecraft.util.Mth; +import org.joml.Vector3d; +import org.valkyrienskies.core.api.ships.QueryableShipData; +import org.valkyrienskies.core.api.ships.ServerShip; +import org.valkyrienskies.core.impl.game.ships.PhysShipImpl; +import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.ValkyrienSkiesMod; +import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; + +import java.text.NumberFormat; +import java.util.Map; + +public class PhysTick { + + public static final double PERMEABILITY = 0.05d; + public static final double MAX_FORCE = 100000000.0d; + public static final double MAX_LENGTH = 100.0d; + + + public static void apply(Map> dimensionToShipIdToPhysShip) { + double deltaTime = 1.0 / (VSGameUtilsKt.getVsPipeline(ValkyrienSkiesMod.getCurrentServer()).computePhysTps()); + + dimensionToShipIdToPhysShip.forEach((dim, idToPhysShip) -> { + + QueryableShipData allShips = VSGameUtilsKt.getShipObjectWorld(ValkyrienSkiesMod.getCurrentServer()).getAllShips(); + + idToPhysShip.forEach((id1, physShip1) -> { + ServerShip ship1 = allShips.getById(id1); + + if (ship1 == null) return; + + VSCHForceInducedShips attach1 = ship1.getAttachment(VSCHForceInducedShips.class); + + if (attach1 == null) return; + + idToPhysShip.forEach((id2, physShip2) -> { + + if (physShip1.getPoseVel().getPos().sub(physShip2.getPoseVel().getPos(), new Vector3d()).lengthSquared() > MAX_LENGTH) return; + + ServerShip ship2 = allShips.getById(id2); + + if (ship2 == null || id1.equals(id2)) return; + + VSCHForceInducedShips attach2 = ship2.getAttachment(VSCHForceInducedShips.class); + + if (attach2 == null) return; + + attach1.magnets.forEach((bPos1, data1) -> { + + Vector3d acc1 = new Vector3d(); + Vector3d acc2 = new Vector3d(); + + Vector3d shipPos1 = VectorConversionsMCKt.toJOMLD(bPos1).add(.5,.5,.5); + + Vector3d shipPos1N = shipPos1.fma(0.45, data1.direction, new Vector3d()); + Vector3d shipPos1S = shipPos1.fma(-0.45, data1.direction, new Vector3d()); + + Vector3d pos1N = physShip1.getTransform().getShipToWorld().transformPosition(shipPos1N, new Vector3d()); + Vector3d pos1S = physShip1.getTransform().getShipToWorld().transformPosition(shipPos1S, new Vector3d()); + + attach2.magnets.forEach((bPos2, data2) -> { + + + Vector3d shipPos2 = VectorConversionsMCKt.toJOMLD(bPos2).add(.5,.5,.5); + + + Vector3d pos2N = shipPos2.fma(0.45, data2.direction, new Vector3d()); + Vector3d pos2S = shipPos2.fma(-0.45, data2.direction, new Vector3d()); + + double totalForce = data1.force * data2.force * 10000; + + physShip2.getTransform().getShipToWorld().transformPosition(pos2N); + physShip2.getTransform().getShipToWorld().transformPosition(pos2S); + + acc1.add(calculateGilbertForce(pos1N, data1.force, pos2N, data2.force, true).mul(totalForce)); + acc1.add(calculateGilbertForce(pos1N, data1.force, pos2S, data2.force, false).mul(totalForce)); + + acc2.add(calculateGilbertForce(pos1S, data1.force, pos2N, data2.force, false).mul(totalForce)); + acc2.add(calculateGilbertForce(pos1S, data1.force, pos2S, data2.force, true).mul(totalForce)); + + + }); + + if (acc1.lengthSquared() > MAX_FORCE * MAX_FORCE) acc1.normalize(MAX_FORCE); + if (acc2.lengthSquared() > MAX_FORCE * MAX_FORCE) acc2.normalize(MAX_FORCE); + + physShip1.applyInvariantForceToPos(acc1, shipPos1N.sub(physShip1.getTransform().getPositionInShip(), new Vector3d())); + physShip1.applyInvariantForceToPos(acc2, shipPos1S.sub(physShip1.getTransform().getPositionInShip(), new Vector3d())); + + }); + }); + }); + }); + } + + private static Vector3d calculateGilbertForce(Vector3d pos1, double force1, Vector3d pos2, double force2, boolean samePole) { + Vector3d r = pos2.sub(pos1, new Vector3d()); + double dist = r.length(); + double part0 = PERMEABILITY * force1 * force2; + double part1 = 4 * Math.PI * dist; + + double f = (part0 / part1); + + if (samePole) + f = -f; + + r.normalize(f); + + System.out.println(r.toString(NumberFormat.getInstance())); + + return r; + } +} diff --git a/src/main/java/net/jcm/vsch/mixin/VSPhysicsPipelineStageMixin.java b/src/main/java/net/jcm/vsch/mixin/VSPhysicsPipelineStageMixin.java new file mode 100644 index 0000000..84428f7 --- /dev/null +++ b/src/main/java/net/jcm/vsch/mixin/VSPhysicsPipelineStageMixin.java @@ -0,0 +1,28 @@ +package net.jcm.vsch.mixin; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import net.jcm.vsch.event.PhysTick; +import org.joml.Vector3dc; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.valkyrienskies.core.impl.game.ships.PhysShipImpl; +import org.valkyrienskies.core.impl.shadow.Ao; +import org.valkyrienskies.core.impl.shadow.Aq; + +import java.util.Map; + +/**@deprecated really, really sus vscore reference*/ +@Deprecated +@Mixin(value = Aq.class, remap = false) +public class VSPhysicsPipelineStageMixin { + @Shadow @Final private Map> h; + + @Inject(method = "a(Lorg/joml/Vector3dc;DZ)Lorg/valkyrienskies/core/impl/shadow/Ao;", at = @At("TAIL")) + public void physTickHook(Vector3dc par1, double par2, boolean par3, CallbackInfoReturnable cir) { + PhysTick.apply(h); + } +} diff --git a/src/main/java/net/jcm/vsch/ship/MagnetData.java b/src/main/java/net/jcm/vsch/ship/MagnetData.java new file mode 100644 index 0000000..9eb1cc4 --- /dev/null +++ b/src/main/java/net/jcm/vsch/ship/MagnetData.java @@ -0,0 +1,22 @@ +package net.jcm.vsch.ship; + +import org.joml.Vector3d; + +public class MagnetData { + + public volatile double force = 10.0; + + public final Vector3d direction; + + public MagnetData() { + direction = null; + } + + public MagnetData(Vector3d direction, double force) { + this.direction = direction; + this.force = force; + } + public MagnetData(Vector3d direction) { + this.direction = direction; + } +} diff --git a/src/main/java/net/jcm/vsch/ship/VSCHForceInducedShips.java b/src/main/java/net/jcm/vsch/ship/VSCHForceInducedShips.java index bfd39e5..3607b7a 100644 --- a/src/main/java/net/jcm/vsch/ship/VSCHForceInducedShips.java +++ b/src/main/java/net/jcm/vsch/ship/VSCHForceInducedShips.java @@ -1,18 +1,18 @@ package net.jcm.vsch.ship; -import java.util.Map; +import java.text.NumberFormat; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import javax.annotation.Nullable; +import com.mojang.datafixers.util.Pair; +import net.jcm.vsch.util.LevelBlockPos; import org.jetbrains.annotations.NotNull; import org.joml.Vector3d; import org.joml.Vector3dc; -import org.valkyrienskies.core.api.ships.PhysShip; -import org.valkyrienskies.core.api.ships.ServerShip; -import org.valkyrienskies.core.api.ships.ShipForcesInducer; +import org.valkyrienskies.core.api.ships.*; import org.valkyrienskies.core.impl.game.ships.PhysShipImpl; -import org.valkyrienskies.core.impl.program.VSCoreImpl; import org.valkyrienskies.mod.common.VSGameUtilsKt; import org.valkyrienskies.mod.common.ValkyrienSkiesMod; import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; @@ -38,10 +38,16 @@ public class VSCHForceInducedShips implements ShipForcesInducer { */ public Map draggers = new ConcurrentHashMap<>(); + public Map magnets = new ConcurrentHashMap<>(); + public static Map worldMagnets = new ConcurrentHashMap<>(); + private String dimensionId = null; public VSCHForceInducedShips() {} + public static final float PERMEABILITY = 0.05f; + public static final float MAX_FORCE = 10000.0f; + public VSCHForceInducedShips(String dimensionId) { this.dimensionId = dimensionId; } @@ -49,6 +55,11 @@ public VSCHForceInducedShips(String dimensionId) { @Override public void applyForces(@NotNull PhysShip physicShip) { PhysShipImpl physShip = (PhysShipImpl) physicShip; + + + double deltaTime = 1.0 / (VSGameUtilsKt.getVsPipeline(ValkyrienSkiesMod.getCurrentServer()).computePhysTps()); + +// ((ShipObjectServer)VSGameUtilsKt.getShipObjectWorld(ValkyrienSkiesMod.getCurrentServer()).getAllShips().getById(physShip.getId())). // Apply thrusters force thrusters.forEach((pos, data) -> { // Get current thrust from thruster @@ -152,6 +163,89 @@ public void applyForces(@NotNull PhysShip physicShip) { physShip.applyInvariantForce(force); physShip.applyInvariantTorque(rotForce); }); + + + QueryableShipData allShips = VSGameUtilsKt.getShipObjectWorld(ValkyrienSkiesMod.getCurrentServer()).getAllShips(); + ServerShip shipOn = allShips.getById(physShip.getId()); + + if (shipOn != null) { +// Map> allMagnets = new HashMap<>(); +// +// new HashMap<>(worldMagnets).forEach((levelPos, data) -> { +// if (Objects.equals(levelPos.level, shipOn.getChunkClaimDimension())) allMagnets.put(VectorConversionsMCKt.toJOMLD(levelPos), new Pair<>(data.direction, data.force)); +// }); +// +// allShips.getIntersecting(VectorConversionsMCKt.toJOML(VectorConversionsMCKt.toMinecraft(shipOn.getWorldAABB()).inflate(25.0))).forEach(ship -> { +// if (!ship.getChunkClaimDimension().equals(shipOn.getChunkClaimDimension()) || ship == shipOn) return; +// new HashMap<>(getOrCreate(ship).magnets).forEach((pos, data) -> { +// allMagnets.put(ship.getTransform().getShipToWorld().transformPosition(VectorConversionsMCKt.toJOMLD(pos).add(.5,.5,.5)), new Pair<>(ship.getTransform().getShipToWorldRotation().transform(data.direction, new Vector3d()), data.force)); +// }); +// }); +// +// +// new HashMap<>(magnets).forEach((bPos, data) -> { +// Vector3d pos0 = physShip.getTransform().getShipToWorld().transformPosition(VectorConversionsMCKt.toJOMLD(bPos).add(.5,.5,.5), new Vector3d()); +// +// Vector3d dir0 = physShip.getTransform().getShipToWorldRotation().transform(data.direction, new Vector3d()); +// +// double force0 = data.force; +// +// Vector3d accF1 = new Vector3d(); +// Vector3d accF2 = new Vector3d(); +// System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); +// allMagnets.forEach((pos1, pair) -> { +// if (pos0.equals(pos1)) return; +// Vector3d force1 = calculateGilbertForce(pos0.fma(0.5, dir0), dir0, force0, pos1.fma(0.5, pair.getFirst()), pair.getFirst(), pair.getSecond()).negate(); +// Vector3d force2 = calculateGilbertForce(pos0.fma(-0.5, dir0), dir0, force0, pos1.fma(0.5, pair.getFirst()), pair.getFirst(), pair.getSecond()); +// Vector3d force3 = calculateGilbertForce(pos0.fma(0.5, dir0), dir0, force0, pos1.fma(-0.5, pair.getFirst()), pair.getFirst(), pair.getSecond()); +// Vector3d force4 = calculateGilbertForce(pos0.fma(-0.5, dir0), dir0, force0, pos1.fma(-0.5, pair.getFirst()), pair.getFirst(), pair.getSecond()).negate(); +// +// double force = force0 * pair.getSecond(); +// +// accF1.add(force1.mul(force)); +// accF2.add(force2.mul(force)); +// accF1.add(force3.mul(force)); +// accF2.add(force4.mul(force)); +// +// System.out.println(); +// System.out.println(accF1.toString(NumberFormat.getInstance())); +// System.out.println(accF2.toString(NumberFormat.getInstance())); +// System.out.println(); +// }); +// +// Vector3d posShip0 = VectorConversionsMCKt.toJOMLD(bPos).add(.5,.5,.5).fma(0.5, data.direction).sub(physShip.getTransform().getPositionInShip()); +// Vector3d posShip1 = VectorConversionsMCKt.toJOMLD(bPos).add(-.5,.5,.5).fma(0.5, data.direction).sub(physShip.getTransform().getPositionInShip()); +// +// if (accF1.lengthSquared() > MAX_FORCE * MAX_FORCE) accF1.normalize(MAX_FORCE); +// if (accF2.lengthSquared() > MAX_FORCE * MAX_FORCE) accF1.normalize(MAX_FORCE); +// +//// System.out.println(); +//// System.out.println(accF1.toString(NumberFormat.getInstance())); +//// System.out.println(accF2.toString(NumberFormat.getInstance())); +//// System.out.println(posShip0.toString(NumberFormat.getInstance())); +//// System.out.println(posShip1.toString(NumberFormat.getInstance())); +// +// physShip.applyInvariantForceToPos(accF1, posShip0); +// physShip.applyInvariantForceToPos(accF2, posShip1); +// +// }); + } + } + + + private Vector3d calculateGilbertForce(Vector3d m1, Vector3d dir1, double force1, Vector3d m2, Vector3d dir2, double force2) { + + Vector3d r = m2.sub(m1, new Vector3d()); + double dist = r.length(); + double part0 = PERMEABILITY * force1 * force2; + double part1 = 4 * Math.PI * dist; + + double f = (part0 / part1); + System.out.println(); + System.out.println(f); + System.out.println(); + + return r.normalize(new Vector3d()).mul(f); } private static void applyScaledForce(PhysShipImpl physShip, Vector3dc linearVelocity, Vector3d tForce, int maxSpeed) { @@ -193,6 +287,14 @@ public void removeDragger(BlockPos pos) { draggers.remove(pos); } + public void addMagnet(BlockPos pos, MagnetData data) { + magnets.put(pos, data); + } + + public void removeMagnet(BlockPos pos) { + magnets.remove(pos); + } + @Nullable public DraggerData getDraggerAtPos(BlockPos pos) { return draggers.get(pos); diff --git a/src/main/java/net/jcm/vsch/util/LevelBlockPos.java b/src/main/java/net/jcm/vsch/util/LevelBlockPos.java new file mode 100644 index 0000000..e8734eb --- /dev/null +++ b/src/main/java/net/jcm/vsch/util/LevelBlockPos.java @@ -0,0 +1,37 @@ +package net.jcm.vsch.util; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; +import org.valkyrienskies.mod.common.VSGameUtilsKt; + +import java.util.Objects; + +public class LevelBlockPos extends BlockPos { + public final String level; + + public LevelBlockPos(int pX, int pY, int pZ, @NotNull String level) { + super(pX, pY, pZ); + this.level = level; + } + + public LevelBlockPos(Vec3i vec3i, @NotNull String level) { + super(vec3i); + this.level = level; + } + + public LevelBlockPos(int pX, int pY, int pZ, Level level) { + this(pX, pY, pZ, VSGameUtilsKt.getDimensionId(level)); + } + + public LevelBlockPos(Vec3i vec3i, Level level) { + this(vec3i, VSGameUtilsKt.getDimensionId(level)); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof LevelBlockPos blockPos)) return false; + return Objects.equals(blockPos.level, level) && super.equals(obj); + } +} diff --git a/src/main/java/net/jcm/vsch/util/VSCHUtils.java b/src/main/java/net/jcm/vsch/util/VSCHUtils.java index 78a990a..fbef602 100644 --- a/src/main/java/net/jcm/vsch/util/VSCHUtils.java +++ b/src/main/java/net/jcm/vsch/util/VSCHUtils.java @@ -98,8 +98,8 @@ public static String dimToVSDim(String dimensionString) { * {@link org.valkyrienskies.core.api.ships.properties.ShipTransform * ShipTransform} and its ship {@link org.joml.primitives.AABBic AABBic} (its * shipyard {@link org.joml.primitives.AABBic AABBic}) and returns a - * world-based {@link org.joml.primitives.AABBd AABBd} using the transform
- *
+ * world-based {@link org.joml.primitives.AABBd AABBd} using the transform + *
* Basically the same as * {@link org.valkyrienskies.core.api.ships.Ship#getWorldAABB() * Ship#getWorldAABB()} but can take in a specified transform and ship AABBic @@ -132,7 +132,7 @@ public static AABBd transformToAABBd(ShipTransform transform, AABBic shipAABB) { * @return A {@link net.minecraft.server.level.ServerLevel ServerLevel} object * in the VS dimension given * @see #dimToVSDim(String) - * @todo Add error handling for if string isn't an existing dimension + * TODO Add error handling for if string isn't an existing dimension */ public static ServerLevel VSDimToLevel(MinecraftServer server, String VSdimensionString) { // Split 'minecraft:dimension:namespace:dimension_name' into [minecraft, @@ -185,11 +185,11 @@ public static void DimensionTeleportShip(Ship ship, ServerLevel level, String ne } /** - * This function took us like 3 days to make. You better appreciate it.
- *
+ * This function took us like 3 days to make. You better appreciate it. + *
* It will teleport the given ship, using the level, to the - * dimension with id of newDim at x, y, z.
- *
+ * dimension with id of newDim at x, y, z. + *
* But most importantly, it will also teleport any players or entities that are * currently being dragged by the ship to the new dimension, and their correct * position relative to the ship that was moved. @@ -473,7 +473,7 @@ public static boolean isCollidingWithPlanet(@Nonnull CompoundTag planetData, Vec /** * Gets a players Cosmos variables capability, or if it doesn't exist, creates a new one. * @param player The player to get the capability of - * @todo Investigate: Is it giving the newly made variables cap to the player, or just returning a blank one to us + * TODO Investigate: Is it giving the newly made variables cap to the player, or just returning a blank one to us */ public static CosmosModVariables.PlayerVariables getOrSetPlayerCap(Player player) { return player.getCapability(CosmosModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new CosmosModVariables.PlayerVariables()); @@ -514,8 +514,9 @@ public static double getMax(Vector3d vec) { /** * Using the ServerLevel, returns the nearest entity of entityType from the sourceEntity in the maxDistance. - * If no entities are found, returns null. - * @todo change this to use a Vec3 instead of sourceEntity + * If no entities are found, returns null. + *
+ * TODO change this to use a Vec3 instead of sourceEntity */ public static Entity getNearestEntityOfType(ServerLevel level, EntityType entityType, Entity sourceEntity, double maxDistance) { // Define the search bounding box diff --git a/src/main/resources/vsch.mixins.json b/src/main/resources/vsch.mixins.json index 7734412..ebd85b4 100644 --- a/src/main/resources/vsch.mixins.json +++ b/src/main/resources/vsch.mixins.json @@ -12,6 +12,7 @@ "MixinShipAssemblyKt", "MixinSpacesuitwornLogicProcedure", "MixinVSGameUtilsKt", + "VSPhysicsPipelineStageMixin", "accessor.ServerShipObjectWorldAccessor" ], "client": [