From 759f511b00a5918dc66c44633cb9c4ae60f38223 Mon Sep 17 00:00:00 2001 From: craisinlord Date: Fri, 9 Oct 2026 23:56:18 -0500 Subject: [PATCH] MINIONS... TONIGHT WE STEAL THE MOON --- .../content/client/MoonSkyTracker.java | 52 ++++++++ .../content/entity/HoverboardEntity.java | 29 ++--- .../entity/glimmer/GlimmerNightSpawner.java | 108 +++++++++++++++++ .../antarchy/content/item/PortalGunItem.java | 7 ++ .../network/PortalGunMoonAimPayload.java | 22 ++++ .../portalgun/PortalGunMoonAimSync.java | 48 ++++++++ .../portalgun/PortalGunPortalEntity.java | 113 +++++++++++++----- .../portalgun/PortalGunProjectileEntity.java | 85 +++++++++---- .../StellarViewLunaDirectionMixin.java | 29 +++++ .../resources/antarchy-common.mixins.json | 1 + .../data/antarchy/dimension/elythia.json | 10 +- .../worldgen/biome/elythia_meadow.json | 4 - .../biome/fungal_ouranwood_forest.json | 4 - .../worldgen/biome/ouranwood_forest.json | 4 - .../antarchy/worldgen/biome/peach_forest.json | 4 - .../biome/sparse_ouranwood_forest.json | 4 - .../worldgen/biome/truffalo_forest.json | 4 - fabric-1.21.1/build.gradle | 1 + .../antarchy/fabric/AntarchyFabricEvents.java | 2 + .../fabric/client/PortalGunClientHandler.java | 1 + .../AntarchyFabricClientNetworking.java | 2 + .../network/AntarchyFabricNetworking.java | 3 + gradle.properties | 2 +- neoforge-1.21.1/build.gradle | 1 + .../client/PortalGunClientHandler.java | 3 + .../network/AntarchyGravityNetworking.java | 8 ++ .../registry/AntarchyNeoForgeEvents.java | 1 + .../registry/PortalGunServerEvents.java | 1 + 28 files changed, 450 insertions(+), 103 deletions(-) create mode 100644 common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/MoonSkyTracker.java create mode 100644 common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/glimmer/GlimmerNightSpawner.java create mode 100644 common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/PortalGunMoonAimPayload.java create mode 100644 common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunMoonAimSync.java create mode 100644 common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/stellarview/StellarViewLunaDirectionMixin.java diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/MoonSkyTracker.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/MoonSkyTracker.java new file mode 100644 index 00000000..444d94bb --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/MoonSkyTracker.java @@ -0,0 +1,52 @@ +package com.craisinlord.antarchy.content.client; + +import com.craisinlord.antarchy.content.network.PortalGunMoonAimPayload; +import com.craisinlord.antarchy.content.portalgun.PortalGunMoonMath; +import java.util.function.Consumer; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.phys.Vec3; +import org.joml.Matrix4f; +import org.joml.Quaterniond; +import org.joml.Vector3d; +import org.joml.Vector3f; + +public final class MoonSkyTracker { + private static final long MAX_AGE_MILLIS = 1500L; + private static final double AIM_COSINE = Math.cos(Math.toRadians(PortalGunMoonMath.AIM_TOLERANCE_DEGREES)); + private static Vec3 direction; + private static ClientLevel level; + private static long recordedAt; + private static Consumer sender = payload -> {}; + + private MoonSkyTracker() { + } + + public static void setSender(Consumer payloadSender) { + sender = payloadSender; + } + + public static void recordSphericalMoon(ClientLevel renderedLevel, Camera camera, Matrix4f skyMatrix, double theta, double phi) { + Vector3d local = new Quaterniond().rotateY(theta).mul(new Quaterniond().rotateX(phi)).transform(new Vector3d(0.0D, 1.0D, 0.0D)); + Vector3f view = skyMatrix.transformDirection(new Vector3f((float) local.x, (float) local.y, (float) local.z)); + if (view.lengthSquared() < 1.0E-8F) { + return; + } + Vector3f world = camera.rotation().transform(view.normalize()); + direction = new Vec3(world.x, world.y, world.z).normalize(); + level = renderedLevel; + recordedAt = System.currentTimeMillis(); + } + + public static void report() { + Minecraft minecraft = Minecraft.getInstance(); + if (minecraft.player == null) { + return; + } + boolean tracked = direction != null && level == minecraft.level && System.currentTimeMillis() - recordedAt <= MAX_AGE_MILLIS; + boolean aiming = tracked && minecraft.gameRenderer.getMainCamera().getLookVector().dot( + new Vector3f((float) direction.x, (float) direction.y, (float) direction.z)) >= AIM_COSINE; + sender.accept(new PortalGunMoonAimPayload(tracked, aiming)); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HoverboardEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HoverboardEntity.java index ac2ce6c4..509567d7 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HoverboardEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HoverboardEntity.java @@ -222,33 +222,18 @@ public class HoverboardEntity extends PathfinderMob implements GeoEntity { private double resolveVerticalMotion(boolean holdingJump) { AntarchyGravityDirection gravityDirection = AntarchyGravityApi.getGravityDirection(this); double supportHeight = this.findSupportHeight(gravityDirection); - if (!gravityDirection.isInverted()) { - double maxY = supportHeight + MAX_HOVER_HEIGHT; - if (holdingJump) { - return this.getY() >= maxY ? 0.0D : ASCEND_SPEED; - } - if (this.getY() <= supportHeight) { - return 0.0D; - } - double heightAboveBand = this.getY() - maxY; - if (heightAboveBand > 0.0D) { - return -Mth.clamp(SETTLE_DESCEND_SPEED + heightAboveBand * FAST_DESCEND_RAMP, SETTLE_DESCEND_SPEED, FAST_DESCEND_SPEED); - } - return -SETTLE_DESCEND_SPEED; - } - - double minY = supportHeight - MAX_HOVER_HEIGHT; + double height = gravityDirection.isInverted() ? supportHeight - this.getY() : this.getY() - supportHeight; if (holdingJump) { - return this.getY() <= minY ? 0.0D : -ASCEND_SPEED; + return height >= MAX_HOVER_HEIGHT ? 0.0D : ASCEND_SPEED; } - if (this.getY() >= supportHeight) { + if (height <= 0.0D) { return 0.0D; } - double depthBelowBand = minY - this.getY(); - if (depthBelowBand > 0.0D) { - return Mth.clamp(SETTLE_DESCEND_SPEED + depthBelowBand * FAST_DESCEND_RAMP, SETTLE_DESCEND_SPEED, FAST_DESCEND_SPEED); + double heightAboveBand = height - MAX_HOVER_HEIGHT; + if (heightAboveBand > 0.0D) { + return -Mth.clamp(SETTLE_DESCEND_SPEED + heightAboveBand * FAST_DESCEND_RAMP, SETTLE_DESCEND_SPEED, FAST_DESCEND_SPEED); } - return SETTLE_DESCEND_SPEED; + return -SETTLE_DESCEND_SPEED; } private double findSupportHeight(AntarchyGravityDirection gravityDirection) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/glimmer/GlimmerNightSpawner.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/glimmer/GlimmerNightSpawner.java new file mode 100644 index 00000000..d625665f --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/glimmer/GlimmerNightSpawner.java @@ -0,0 +1,108 @@ +package com.craisinlord.antarchy.content.entity.glimmer; + +import com.craisinlord.antarchy.Antarchy; +import com.craisinlord.antarchy.content.AntarchyObjects; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.SpawnPlacements; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.phys.AABB; + +public final class GlimmerNightSpawner { + private static final ResourceKey ELYTHIA = ResourceKey.create( + Registries.DIMENSION, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia") + ); + + private static final int CHECK_INTERVAL_TICKS = 20 * 10; + private static final float SPAWN_CHANCE = 0.35F; + private static final double NEARBY_RADIUS = 64.0D; + private static final int MAX_NEARBY_WILD = 2; + private static final double MIN_SPAWN_DISTANCE = 24.0D; + private static final double MAX_SPAWN_DISTANCE = 56.0D; + private static final int COLUMN_ATTEMPTS = 8; + + private GlimmerNightSpawner() { + } + + public static void tick(ServerLevel level) { + if (!level.dimension().equals(ELYTHIA)) { + return; + } + if (level.getGameTime() % CHECK_INTERVAL_TICKS != 0L || !level.isNight()) { + return; + } + if (!level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { + return; + } + + EntityType type = AntarchyObjects.GLIMMER.get(); + for (ServerPlayer player : level.players()) { + if (player.isSpectator() || !player.isAlive()) { + continue; + } + if (level.random.nextFloat() >= SPAWN_CHANCE) { + continue; + } + if (countNearbyWild(level, player, type) >= MAX_NEARBY_WILD) { + continue; + } + attemptSpawnNear(level, player, type); + } + } + + private static int countNearbyWild(ServerLevel level, ServerPlayer player, EntityType type) { + AABB box = player.getBoundingBox().inflate(NEARBY_RADIUS); + return level.getEntities(type, box, glimmer -> !glimmer.isTame()).size(); + } + + private static void attemptSpawnNear(ServerLevel level, ServerPlayer player, EntityType type) { + RandomSource random = level.random; + BlockPos origin = player.blockPosition(); + for (int attempt = 0; attempt < COLUMN_ATTEMPTS; attempt++) { + double angle = random.nextDouble() * Math.PI * 2.0D; + double distance = MIN_SPAWN_DISTANCE + random.nextDouble() * (MAX_SPAWN_DISTANCE - MIN_SPAWN_DISTANCE); + int x = origin.getX() + Mth.floor(Math.cos(angle) * distance); + int z = origin.getZ() + Mth.floor(Math.sin(angle) * distance); + if (!level.hasChunkAt(new BlockPos(x, origin.getY(), z))) { + continue; + } + BlockPos pos = level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, new BlockPos(x, 0, z)); + if (!biomeSpawnsGlimmers(level.getBiome(pos), type)) { + continue; + } + if (!SpawnPlacements.checkSpawnRules(type, level, MobSpawnType.NATURAL, pos, random)) { + continue; + } + if (!level.noCollision(type.getSpawnAABB(pos.getX() + 0.5D, pos.getY(), pos.getZ() + 0.5D))) { + continue; + } + GlimmerEntity glimmer = type.create(level); + if (glimmer == null) { + return; + } + glimmer.moveTo(pos.getX() + 0.5D, pos.getY(), pos.getZ() + 0.5D, random.nextFloat() * 360.0F, 0.0F); + glimmer.finalizeSpawn(level, level.getCurrentDifficultyAt(pos), MobSpawnType.NATURAL, null); + level.addFreshEntity(glimmer); + return; + } + } + + private static boolean biomeSpawnsGlimmers(Holder biome, EntityType type) { + return biome.value().getMobSettings().getMobs(MobCategory.CREATURE).unwrap().stream() + .anyMatch(data -> data.type == type); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/PortalGunItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/PortalGunItem.java index dbc1478c..5971d8b3 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/PortalGunItem.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/PortalGunItem.java @@ -113,6 +113,9 @@ public class PortalGunItem extends Item implements GeoItem { public InteractionResultHolder use(Level level, Player player, InteractionHand usedHand) { ItemStack stack = player.getItemInHand(usedHand); if (level.isClientSide) { + if (!player.isShiftKeyDown()) { + com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.reportFromClient(); + } return InteractionResultHolder.consume(stack); } ServerLevel serverLevel = (ServerLevel) level; @@ -312,6 +315,10 @@ public class PortalGunItem extends Item implements GeoItem { if (!level.dimensionType().hasSkyLight() || level.dimensionType().hasCeiling()) { return false; } + Boolean clientAim = player instanceof ServerPlayer serverPlayer ? com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.clientAim(serverPlayer) : null; + if (clientAim != null) { + return clientAim; + } return PortalGunMoonMath.isAimedAtMoon(this.worldLook(player), level.getTimeOfDay(1.0F)); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/PortalGunMoonAimPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/PortalGunMoonAimPayload.java new file mode 100644 index 00000000..9170583a --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/PortalGunMoonAimPayload.java @@ -0,0 +1,22 @@ +package com.craisinlord.antarchy.content.network; + +import com.craisinlord.antarchy.Antarchy; +import io.netty.buffer.ByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record PortalGunMoonAimPayload(boolean tracked, boolean aiming) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "portal_gun_moon_aim")); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL, PortalGunMoonAimPayload::tracked, + ByteBufCodecs.BOOL, PortalGunMoonAimPayload::aiming, + PortalGunMoonAimPayload::new + ); + + @Override + public Type type() { + return TYPE; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunMoonAimSync.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunMoonAimSync.java new file mode 100644 index 00000000..1b34687b --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunMoonAimSync.java @@ -0,0 +1,48 @@ +package com.craisinlord.antarchy.content.portalgun; + +import com.craisinlord.antarchy.content.network.PortalGunMoonAimPayload; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import net.minecraft.server.level.ServerPlayer; + +public final class PortalGunMoonAimSync { + private static final long MAX_REPORT_AGE_TICKS = 10L; + private static final Map REPORTS = new ConcurrentHashMap<>(); + private static Runnable clientReporter = () -> {}; + + private PortalGunMoonAimSync() { + } + + public static void setClientReporter(Runnable reporter) { + clientReporter = reporter; + } + + public static void reportFromClient() { + clientReporter.run(); + } + + public static void handle(ServerPlayer player, PortalGunMoonAimPayload payload) { + REPORTS.put(player.getUUID(), new Report(payload.tracked(), payload.aiming(), player.serverLevel().getGameTime())); + } + + public static Boolean clientAim(ServerPlayer player) { + Report report = REPORTS.get(player.getUUID()); + if (report == null || !report.tracked()) { + return null; + } + long age = player.serverLevel().getGameTime() - report.gameTime(); + return age < 0L || age > MAX_REPORT_AGE_TICKS ? null : report.aiming(); + } + + public static void forget(UUID playerId) { + REPORTS.remove(playerId); + } + + public static void clear() { + REPORTS.clear(); + } + + private record Report(boolean tracked, boolean aiming, long gameTime) { + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunPortalEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunPortalEntity.java index eed48480..7648389d 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunPortalEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunPortalEntity.java @@ -30,6 +30,7 @@ import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket; import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; @@ -99,7 +100,7 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { private static final double MAX_CLIENT_TRANSIT_MOVEMENT_SQR = 100.0D; private static final double PROJECTILE_PLANE_TOLERANCE = 0.1D; private static final double MOON_RANGE = 14.0D; - private static final double MOON_SPREAD = 0.9D; + private static final double MOON_RAY_MIN_OUTWARD = -0.2D; private static final double MOON_PULL_STRENGTH = 0.15D; private static final double MOON_MAX_SPEED = 1.8D; private static final double MOON_MOUTH_DEPTH = 0.9D; @@ -112,6 +113,8 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { private static final int MOON_VACUUM_INTERVAL = 10; private static final float MOON_VACUUM_DAMAGE = 2.0F; private static final int MOON_WIND_INTERVAL = 40; + private static final int MOON_BLOCK_MAX_FLIGHT_TICKS = 80; + private static final double MOON_BLOCK_SWALLOW_RADIUS = 2.0D; private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); private final Map teleportCooldowns = new HashMap<>(); private UUID ownerId; @@ -122,6 +125,7 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { private int pairTime; private int moonTicks; private int moonSuckedBlocks; + private final Map moonLiftedBlocks = new HashMap<>(); private BlockPos supportOrigin = BlockPos.ZERO; private BlockPos masterPos = BlockPos.ZERO; private BlockPos basePos = BlockPos.ZERO; @@ -663,26 +667,23 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { PortalGunWorldPortalShape shape = this.getWorldPortalShape(); Player owner = this.getOwnerId() == null ? null : level.getPlayerByUUID(this.getOwnerId()); this.pullMoonEntities(level, shape, owner); + this.tickMoonLiftedBlocks(level, shape); if (AntarchySettings.portalGunMoonPullsBlocks() && this.moonTicks % MOON_BLOCK_INTERVAL == 0) { this.pullMoonBlocks(level, shape, owner); } } - private static double moonLateralLimit(PortalGunWorldPortalShape shape, double depth) { - return Math.max(shape.halfWidth(), shape.halfHeight()) + 0.5D + Math.max(0.0D, depth) * MOON_SPREAD; - } - private void pullMoonEntities(ServerLevel level, PortalGunWorldPortalShape shape, Player owner) { Vec3 center = shape.center(); - AABB area = new AABB(center, center.add(shape.normal().scale(MOON_RANGE))).inflate(moonLateralLimit(shape, MOON_RANGE)); + AABB area = new AABB(center, center).inflate(MOON_RANGE); Vec3 target = center.add(shape.normal().scale(0.3D)); boolean vacuumTick = this.moonTicks % MOON_VACUUM_INTERVAL == 0; for (Entity entity : level.getEntities(this, area, this::canMoonAffect)) { Vec3 position = entity.getBoundingBox().getCenter(); PortalGunWorldPortalShape.PortalLocalCoords local = shape.localCoords(position); double depth = local.depth(); - double lateral = Math.sqrt(local.horizontal() * local.horizontal() + local.vertical() * local.vertical()); - if (depth < -0.5D || depth > MOON_RANGE || lateral > moonLateralLimit(shape, depth)) { + double distance = position.distanceTo(center); + if (depth < -0.5D || distance > MOON_RANGE) { continue; } boolean atMouth = depth <= MOON_MOUTH_DEPTH + entity.getBbWidth() * 0.5D @@ -694,7 +695,7 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { } continue; } - double falloff = 1.0D - depth / MOON_RANGE; + double falloff = 1.0D - distance / MOON_RANGE; double strength = MOON_PULL_STRENGTH * (0.35D + falloff * falloff * 1.6D); Vec3 worldMotion = PortalGunTransitMath.entityVelocityToWorld(entity, entity.getDeltaMovement()) .scale(0.92D) @@ -752,20 +753,20 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { int cap = AntarchySettings.portalGunMoonBlockCap(); int pulled = 0; for (int ray = 0; ray < MOON_BLOCK_RAYS && pulled < MOON_BLOCKS_PER_PULL && this.moonSuckedBlocks < cap; ray++) { - double limit = moonLateralLimit(shape, MOON_RANGE); - double horizontal = (this.random.nextDouble() * 2.0D - 1.0D) * limit; - double vertical = (this.random.nextDouble() * 2.0D - 1.0D) * limit; - if (horizontal * horizontal + vertical * vertical > limit * limit) { + Vec3 direction = new Vec3(this.random.nextGaussian(), this.random.nextGaussian(), this.random.nextGaussian()); + if (direction.lengthSqr() < 1.0E-6D) { continue; } + direction = direction.normalize(); + double outward = direction.dot(shape.normal()); + if (outward < MOON_RAY_MIN_OUTWARD) { + direction = direction.subtract(shape.normal().scale(outward - MOON_RAY_MIN_OUTWARD - this.random.nextDouble() * 0.3D)).normalize(); + } Vec3 start = shape.center() .add(shape.right().scale((this.random.nextDouble() * 2.0D - 1.0D) * shape.halfWidth())) .add(shape.up().scale((this.random.nextDouble() * 2.0D - 1.0D) * shape.halfHeight())) - .add(shape.normal().scale(0.5D)); - Vec3 end = shape.center() - .add(shape.right().scale(horizontal)) - .add(shape.up().scale(vertical)) - .add(shape.normal().scale(MOON_RANGE)); + .add(shape.normal().scale(0.3D)); + Vec3 end = start.add(direction.scale(MOON_RANGE)); BlockPos hit = this.firstBlockAlong(level, shape, start, end); if (hit == null) { continue; @@ -775,16 +776,44 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { || owner != null && !level.mayInteract(owner, hit)) { continue; } - FallingBlockEntity falling = BlockSuction.lift(level, hit, state, shape.center(), MOON_BLOCK_SPEED); + FallingBlockEntity falling = BlockSuction.lift(level, hit, state, shape.center().add(shape.normal().scale(1.2D)), MOON_BLOCK_SPEED); if (falling == null) { continue; } falling.setNoGravity(true); + this.moonLiftedBlocks.put(falling.getUUID(), this.moonTicks); pulled++; this.moonSuckedBlocks++; } } + private void tickMoonLiftedBlocks(ServerLevel level, PortalGunWorldPortalShape shape) { + Iterator> iterator = this.moonLiftedBlocks.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + if (!(level.getEntity(entry.getKey()) instanceof FallingBlockEntity falling) || !falling.isAlive()) { + iterator.remove(); + continue; + } + if (this.moonTicks - entry.getValue() > MOON_BLOCK_MAX_FLIGHT_TICKS + || falling.getBoundingBox().getCenter().distanceTo(shape.center()) <= MOON_BLOCK_SWALLOW_RADIUS) { + falling.discard(); + iterator.remove(); + } + } + } + + private void releaseMoonLiftedBlocks(ServerLevel level) { + for (UUID id : this.moonLiftedBlocks.keySet()) { + if (level.getEntity(id) instanceof FallingBlockEntity falling && falling.isAlive()) { + falling.setNoGravity(false); + falling.setDeltaMovement(falling.getDeltaMovement().scale(0.2D)); + falling.hurtMarked = true; + } + } + this.moonLiftedBlocks.clear(); + } + private BlockPos firstBlockAlong(ServerLevel level, PortalGunWorldPortalShape shape, Vec3 start, Vec3 end) { Vec3 delta = end.subtract(start); int steps = Math.max(1, (int) Math.ceil(delta.length() / MOON_RAY_STEP)); @@ -795,9 +824,6 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { continue; } previous = pos; - if (shape.localCoords(Vec3.atCenterOf(pos)).depth() < 0.5D) { - continue; - } if (!level.isInWorldBounds(pos) || !level.getWorldBorder().isWithinBounds(pos)) { return null; } @@ -805,9 +831,19 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { if (state == null) { return null; } - if (!state.isAir()) { - return pos; + if (state.isAir() || this.containsPortalSpot(pos)) { + continue; } + PortalGunWorldPortalShape.PortalLocalCoords local = shape.localCoords(Vec3.atCenterOf(pos)); + if (local.depth() < -1.0D) { + return null; + } + if (local.depth() < 0.5D + && Math.abs(local.horizontal()) <= shape.halfWidth() + 1.0D + && Math.abs(local.vertical()) <= shape.halfHeight() + 1.0D) { + return null; + } + return pos; } return null; } @@ -821,13 +857,16 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { private void spawnMoonParticles() { PortalGunWorldPortalShape shape = this.getWorldPortalShape(); Vec3 center = shape.center(); - for (int i = 0; i < 4; i++) { - double depth = 1.0D + this.random.nextDouble() * MOON_RANGE * 0.6D; - double limit = moonLateralLimit(shape, depth); - Vec3 start = center - .add(shape.right().scale((this.random.nextDouble() * 2.0D - 1.0D) * limit)) - .add(shape.up().scale((this.random.nextDouble() * 2.0D - 1.0D) * limit)) - .add(shape.normal().scale(depth)); + for (int i = 0; i < 6; i++) { + Vec3 direction = new Vec3(this.random.nextGaussian(), this.random.nextGaussian(), this.random.nextGaussian()); + if (direction.lengthSqr() < 1.0E-6D) { + continue; + } + direction = direction.normalize(); + if (direction.dot(shape.normal()) < 0.1D) { + direction = direction.add(shape.normal().scale(0.1D - direction.dot(shape.normal()))).normalize(); + } + Vec3 start = center.add(direction.scale(1.5D + this.random.nextDouble() * MOON_RANGE * 0.6D)); Vec3 velocity = center.subtract(start).normalize().scale(0.35D + this.random.nextDouble() * 0.3D); this.level().addParticle(ParticleTypes.CLOUD, start.x, start.y, start.z, velocity.x, velocity.y, velocity.z); } @@ -1072,6 +1111,11 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { tag.putBoolean("Moon", true); tag.putInt("MoonTicks", this.moonTicks); tag.putInt("MoonSuckedBlocks", this.moonSuckedBlocks); + ListTag lifted = new ListTag(); + for (UUID id : this.moonLiftedBlocks.keySet()) { + lifted.add(NbtUtils.createUUID(id)); + } + tag.put("MoonLiftedBlocks", lifted); } tag.putInt("Side", this.getPortalSide().ordinal()); tag.putInt("Facing", this.getFacingDirection().get3DDataValue()); @@ -1125,6 +1169,10 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { this.entityData.set(MOON, tag.getBoolean("Moon")); this.moonTicks = tag.getInt("MoonTicks"); this.moonSuckedBlocks = tag.getInt("MoonSuckedBlocks"); + this.moonLiftedBlocks.clear(); + for (Tag lifted : tag.getList("MoonLiftedBlocks", Tag.TAG_INT_ARRAY)) { + this.moonLiftedBlocks.put(NbtUtils.loadUUID(lifted), this.moonTicks); + } this.entityData.set(SIDE, tag.getInt("Side")); this.entityData.set(FACING, tag.getInt("Facing")); this.entityData.set(UP_AXIS, tag.getInt("UpAxis")); @@ -1153,6 +1201,9 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity { @Override public void remove(Entity.RemovalReason reason) { + if (this.isMoonPortal() && this.level() instanceof ServerLevel moonLevel) { + this.releaseMoonLiftedBlocks(moonLevel); + } Level level = this.level(); UUID ownerId = this.ownerId; boolean destroyPortal = reason.shouldDestroy(); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunProjectileEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunProjectileEntity.java index 477a8d2e..64fe075e 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunProjectileEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunProjectileEntity.java @@ -5,11 +5,14 @@ import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; import com.craisinlord.antarchy.content.gravity.AntarchyGravityTransition; import com.craisinlord.antarchy.config.AntarchySettings; +import java.util.ArrayList; import java.util.Comparator; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.UUID; import net.minecraft.core.BlockPos; +import net.minecraft.core.SectionPos; import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; @@ -49,6 +52,7 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile { private static final TagKey GLASS_PANES = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "glass_panes")); private static final int MAX_TICKETED_PROJECTILES = 20; private static final int PROJECTILE_TICKET_LEVEL = 31; + private static final int MAX_CHUNK_WAIT_TICKS = 200; private static final TicketType PROJECTILE_TICKET = TicketType.create("antarchy_portal_projectile", Comparator.comparing(UUID::toString)); private static final LinkedHashMap PROJECTILE_TICKETS = new LinkedHashMap<>(); private static final EntityDataAccessor SIDE = SynchedEntityData.defineId(PortalGunProjectileEntity.class, EntityDataSerializers.INT); @@ -74,6 +78,7 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile { private UUID gunId; private boolean spawnSynced; private boolean ticketRegistered; + private int chunkWaitTicks; public int portalWidth = 1; public int portalHeight = 2; @@ -207,8 +212,8 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile { this.setDeltaMovement(this.getSyncedVelocity()); this.spawnSynced = true; } - if (!this.level().isClientSide && !this.isRemoved()) { - this.updateProjectileTicket(); + if (this.level() instanceof ServerLevel serverLevel && !this.isRemoved() && !this.prepareServerStep(serverLevel)) { + return; } this.baseTick(); if (this.isRemoved()) { @@ -260,9 +265,6 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile { if (this.isRemoved()) { return; } - if (!this.level().isClientSide && !this.isRemoved()) { - this.updateProjectileTicket(); - } if (this.isInWater()) { for (int i = 0; i < 4; i++) { float backtrack = 0.25F; @@ -293,34 +295,78 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile { super.remove(reason); } - private void updateProjectileTicket() { - if (!(this.level() instanceof ServerLevel serverLevel)) { - return; + private boolean prepareServerStep(ServerLevel level) { + Vec3 position = this.position(); + Vec3 motion = this.getDeltaMovement(); + if (position.y > level.getMaxBuildHeight() + 2.0D && motion.y >= 0.0D + || position.y < level.getMinBuildHeight() - 2.0D && motion.y <= 0.0D) { + this.discard(); + return false; } - if (!AntarchySettings.portalGunCanPortalProjectilesChunkload()) { + List path = chunksAlong(position, position.add(motion)); + boolean chunkload = AntarchySettings.portalGunCanPortalProjectilesChunkload(); + if (chunkload) { + this.updateProjectileTicket(level, path); + } else { this.releaseProjectileTicket(); - return; } - ChunkPos chunkPos = this.chunkPosition(); + for (ChunkPos chunk : path) { + if (level.getChunkSource().getChunkNow(chunk.x, chunk.z) == null) { + if (!chunkload || ++this.chunkWaitTicks > MAX_CHUNK_WAIT_TICKS) { + this.discard(); + } + return false; + } + } + this.chunkWaitTicks = 0; + return true; + } + + private static List chunksAlong(Vec3 start, Vec3 end) { + int minX = SectionPos.blockToSectionCoord(Math.min(start.x, end.x)); + int maxX = SectionPos.blockToSectionCoord(Math.max(start.x, end.x)); + int minZ = SectionPos.blockToSectionCoord(Math.min(start.z, end.z)); + int maxZ = SectionPos.blockToSectionCoord(Math.max(start.z, end.z)); + if (maxX - minX > 1 || maxZ - minZ > 1) { + return List.of(new ChunkPos(minX, minZ), new ChunkPos(maxX, maxZ)); + } + List chunks = new ArrayList<>(4); + for (int x = minX; x <= maxX; x++) { + for (int z = minZ; z <= maxZ; z++) { + chunks.add(new ChunkPos(x, z)); + } + } + return chunks; + } + + private void updateProjectileTicket(ServerLevel serverLevel, List chunks) { UUID ticketId = this.getUUID(); ProjectileTicket current = PROJECTILE_TICKETS.get(ticketId); - if (current != null && current.level == serverLevel && current.chunkPos.equals(chunkPos)) { + if (current != null && current.level == serverLevel && current.chunks.equals(chunks)) { return; } if (current != null) { - current.level.getChunkSource().removeRegionTicket(PROJECTILE_TICKET, current.chunkPos, PROJECTILE_TICKET_LEVEL, ticketId); + removeTicket(ticketId, current); PROJECTILE_TICKETS.remove(ticketId); } while (PROJECTILE_TICKETS.size() >= MAX_TICKETED_PROJECTILES) { Map.Entry oldest = PROJECTILE_TICKETS.entrySet().iterator().next(); - oldest.getValue().level.getChunkSource().removeRegionTicket(PROJECTILE_TICKET, oldest.getValue().chunkPos, PROJECTILE_TICKET_LEVEL, oldest.getKey()); + removeTicket(oldest.getKey(), oldest.getValue()); PROJECTILE_TICKETS.remove(oldest.getKey()); } - serverLevel.getChunkSource().addRegionTicket(PROJECTILE_TICKET, chunkPos, PROJECTILE_TICKET_LEVEL, ticketId); - PROJECTILE_TICKETS.put(ticketId, new ProjectileTicket(serverLevel, chunkPos)); + for (ChunkPos chunk : chunks) { + serverLevel.getChunkSource().addRegionTicket(PROJECTILE_TICKET, chunk, PROJECTILE_TICKET_LEVEL, ticketId); + } + PROJECTILE_TICKETS.put(ticketId, new ProjectileTicket(serverLevel, List.copyOf(chunks))); this.ticketRegistered = true; } + private static void removeTicket(UUID ticketId, ProjectileTicket ticket) { + for (ChunkPos chunk : ticket.chunks()) { + ticket.level().getChunkSource().removeRegionTicket(PROJECTILE_TICKET, chunk, PROJECTILE_TICKET_LEVEL, ticketId); + } + } + private void releaseProjectileTicket() { if (!this.ticketRegistered) { return; @@ -328,20 +374,19 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile { UUID ticketId = this.getUUID(); ProjectileTicket ticket = PROJECTILE_TICKETS.remove(ticketId); if (ticket != null) { - ticket.level.getChunkSource().removeRegionTicket(PROJECTILE_TICKET, ticket.chunkPos, PROJECTILE_TICKET_LEVEL, ticketId); + removeTicket(ticketId, ticket); } this.ticketRegistered = false; } public static void releaseAllProjectileTickets() { for (Map.Entry entry : PROJECTILE_TICKETS.entrySet()) { - ProjectileTicket ticket = entry.getValue(); - ticket.level.getChunkSource().removeRegionTicket(PROJECTILE_TICKET, ticket.chunkPos, PROJECTILE_TICKET_LEVEL, entry.getKey()); + removeTicket(entry.getKey(), entry.getValue()); } PROJECTILE_TICKETS.clear(); } - private record ProjectileTicket(ServerLevel level, ChunkPos chunkPos) { + private record ProjectileTicket(ServerLevel level, List chunks) { } @Override diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/stellarview/StellarViewLunaDirectionMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/stellarview/StellarViewLunaDirectionMixin.java new file mode 100644 index 00000000..fdcf843e --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/stellarview/StellarViewLunaDirectionMixin.java @@ -0,0 +1,29 @@ +package com.craisinlord.antarchy.mixins.compat.stellarview; + +import com.craisinlord.antarchy.content.client.MoonSkyTracker; +import com.craisinlord.antarchy.content.client.renderer.PortalGunPortalSceneRenderer; +import com.mojang.blaze3d.vertex.Tesselator; +import net.minecraft.client.Camera; +import net.minecraft.client.multiplayer.ClientLevel; +import net.povstalec.stellarview.client.resourcepack.ViewCenter; +import net.povstalec.stellarview.common.util.SphericalCoords; +import org.joml.Matrix4f; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Pseudo +@Mixin(targets = "net.povstalec.stellarview.client.render.space_objects.distinct.LunaRenderer", remap = false) +public abstract class StellarViewLunaDirectionMixin { + @Inject(method = "renderTextureLayers", at = @At("HEAD"), remap = false) + private void antarchy$recordMoonDirection(ViewCenter viewCenter, ClientLevel level, Camera camera, Tesselator tesselator, + Matrix4f lastMatrix, SphericalCoords sphericalCoords, long ticks, double distance, + float partialTicks, CallbackInfo ci) { + if (PortalGunPortalSceneRenderer.isRenderingScene() || sphericalCoords == null || camera == null || lastMatrix == null) { + return; + } + MoonSkyTracker.recordSphericalMoon(level, camera, lastMatrix, sphericalCoords.theta, sphericalCoords.phi); + } +} diff --git a/common-1.21.1/src/main/resources/antarchy-common.mixins.json b/common-1.21.1/src/main/resources/antarchy-common.mixins.json index 4786b371..8aff0c03 100644 --- a/common-1.21.1/src/main/resources/antarchy-common.mixins.json +++ b/common-1.21.1/src/main/resources/antarchy-common.mixins.json @@ -147,6 +147,7 @@ ], "client": [ "client.CameraBasisAccessor", + "compat.stellarview.StellarViewLunaDirectionMixin", "client.LevelRendererPortalViewAreaAccessor", "client.LevelRendererPortalViewAreaMixin", "client.LevelRendererPortalLifecycleMixin", diff --git a/common-1.21.1/src/main/resources/data/antarchy/dimension/elythia.json b/common-1.21.1/src/main/resources/data/antarchy/dimension/elythia.json index 13aa0378..3ab158b8 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/dimension/elythia.json +++ b/common-1.21.1/src/main/resources/data/antarchy/dimension/elythia.json @@ -74,7 +74,7 @@ "humidity": [0.84, 1.0], "continentalness": [0.25, 0.72], "erosion": [-0.5, 0.55], - "weirdness": [-0.55, 0.62], + "weirdness": [-0.35, 0.62], "depth": [0.0, 1.0], "offset": 0.0 } @@ -94,11 +94,11 @@ { "biome": "antarchy:glimmering_pools", "parameters": { - "temperature": [0.58, 0.76], - "humidity": [0.88, 1.0], + "temperature": [0.52, 0.78], + "humidity": [0.84, 1.0], "continentalness": [0.3, 0.65], - "erosion": [-0.05, 0.45], - "weirdness": [-0.7, -0.25], + "erosion": [-0.3, 0.45], + "weirdness": [-0.8, -0.35], "depth": [0.0, 0.25], "offset": 0.0 } diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/elythia_meadow.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/elythia_meadow.json index 96e0c455..4a5b0b5e 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/elythia_meadow.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/elythia_meadow.json @@ -31,10 +31,6 @@ "antarchy:mantis": { "energy_budget": 0.1, "charge": 15.0 - }, - "antarchy:glimmer": { - "energy_budget": 0.1, - "charge": 9 } }, "carvers": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/fungal_ouranwood_forest.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/fungal_ouranwood_forest.json index a04e102b..89bd9d6f 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/fungal_ouranwood_forest.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/fungal_ouranwood_forest.json @@ -37,10 +37,6 @@ "antarchy:basilisk": { "energy_budget": 0.1, "charge": 14.0 - }, - "antarchy:glimmer": { - "energy_budget": 0.1, - "charge": 9 } }, "carvers": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/ouranwood_forest.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/ouranwood_forest.json index 6fa3779e..f2d76eba 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/ouranwood_forest.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/ouranwood_forest.json @@ -37,10 +37,6 @@ "antarchy:basilisk": { "energy_budget": 0.1, "charge": 14.0 - }, - "antarchy:glimmer": { - "energy_budget": 0.1, - "charge": 9 } }, "carvers": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/peach_forest.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/peach_forest.json index c867af44..e2eb45c6 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/peach_forest.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/peach_forest.json @@ -24,10 +24,6 @@ } }, "spawn_costs": { - "antarchy:glimmer": { - "energy_budget": 0.1, - "charge": 9 - } }, "carvers": { "air": [], diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/sparse_ouranwood_forest.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/sparse_ouranwood_forest.json index d4d1ae92..cd17014d 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/sparse_ouranwood_forest.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/sparse_ouranwood_forest.json @@ -34,10 +34,6 @@ } }, "spawn_costs": { - "antarchy:glimmer": { - "energy_budget": 0.1, - "charge": 9 - } }, "carvers": { "air": [], diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/truffalo_forest.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/truffalo_forest.json index fcc77b51..a5e7228c 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/truffalo_forest.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/truffalo_forest.json @@ -31,10 +31,6 @@ "antarchy:mantis": { "energy_budget": 0.1, "charge": 15.0 - }, - "antarchy:glimmer": { - "energy_budget": 0.1, - "charge": 9 } }, "carvers": { diff --git a/fabric-1.21.1/build.gradle b/fabric-1.21.1/build.gradle index d875167c..286fb763 100644 --- a/fabric-1.21.1/build.gradle +++ b/fabric-1.21.1/build.gradle @@ -59,6 +59,7 @@ dependencies { compileOnly(files("$rootDir/infinite_dimensions_jars/infinity-2.7.3+1.21.1-neoforge.jar")) compileOnly(files("$rootDir/infinite_dimensions_jars/gravity-api-1.0.7-1.20.1.jar")) compileOnly(files("$rootDir/infinite_dimensions_jars/sable-neoforge-1.21.1-2.0.3.jar")) + compileOnly(files("$rootDir/infinite_dimensions_jars/stellarview-1.21.1-0.5.3-neoforge.jar")) // Cloth Config — optional, powers the in-game settings screen (AntarchyClothConfigScreenBuilder) // via the Mod Menu integration below. compileOnly + modLocalRuntime only: never bundled or diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricEvents.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricEvents.java index ced1168d..8b2e8f61 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricEvents.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricEvents.java @@ -79,6 +79,7 @@ public final class AntarchyFabricEvents { ServerLifecycleEvents.SERVER_STOPPING.register(server -> PortalGunProjectileEntity.releaseAllProjectileTickets()); ServerLifecycleEvents.SERVER_STOPPING.register(com.craisinlord.antarchy.content.portalgun.PortalGunResetManager::clear); ServerLifecycleEvents.SERVER_STOPPING.register(server -> com.craisinlord.antarchy.content.entity.ant.AntArrivalScheduler.clear()); + ServerLifecycleEvents.SERVER_STOPPING.register(server -> com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.clear()); ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { ChronosphereManager.refresh(handler.player); TimeDilationManager.resyncPersistentEffects(handler.player); @@ -214,6 +215,7 @@ public final class AntarchyFabricEvents { for (ServerLevel level : server.getAllLevels()) { CavarynHordeManager.tick(level); com.craisinlord.antarchy.content.horde.CavarynCreatureSpawner.tick(level); + com.craisinlord.antarchy.content.entity.glimmer.GlimmerNightSpawner.tick(level); ThoraxisUndersideManager.tick(level); com.craisinlord.antarchy.content.worldgen.elythia.KingsTreeGridFeature.tickPendingSpawns(level); tickInvertedPlayers(level, activeThisTick); diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/PortalGunClientHandler.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/PortalGunClientHandler.java index 7b3ef0ca..f259dee0 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/PortalGunClientHandler.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/PortalGunClientHandler.java @@ -46,6 +46,7 @@ public final class PortalGunClientHandler { boolean attackDown = mc.options.keyAttack.isDown(); if (attackDown && !lastAttackDown && !resetActive) { + com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.reportFromClient(); ClientPlayNetworking.send(new PortalGunPrimaryPayload(offhand)); } lastAttackDown = attackDown; diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricClientNetworking.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricClientNetworking.java index 0466ff56..522b256d 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricClientNetworking.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricClientNetworking.java @@ -43,6 +43,8 @@ public final class AntarchyFabricClientNetworking { context.client().execute(() -> com.craisinlord.antarchy.content.client.AntarchyGameClientState.update(payload))); com.craisinlord.antarchy.content.network.AntarchyGameNetworking.setSender(ClientPlayNetworking::send); com.craisinlord.antarchy.content.client.PortalGunIndicatorClientState.setRequestSender(ClientPlayNetworking::send); + com.craisinlord.antarchy.content.client.MoonSkyTracker.setSender(ClientPlayNetworking::send); + com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.setClientReporter(com.craisinlord.antarchy.content.client.MoonSkyTracker::report); ClientPlayNetworking.registerGlobalReceiver(PortalGunIndicatorPayload.TYPE, (payload, context) -> context.client().execute(() -> com.craisinlord.antarchy.content.client.PortalGunIndicatorClientState.update(payload))); ClientPlayNetworking.registerGlobalReceiver(GravityStatePayload.TYPE, (payload, context) -> diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java index e6d38d58..bdaef55f 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java @@ -93,6 +93,7 @@ public final class AntarchyFabricNetworking { PayloadTypeRegistry.playC2S().register(com.craisinlord.antarchy.content.network.PortalGunTransitPayload.TYPE, com.craisinlord.antarchy.content.network.PortalGunTransitPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(PortalGunIndicatorRequestPayload.TYPE, PortalGunIndicatorRequestPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(PortalGunResetPayload.TYPE, PortalGunResetPayload.STREAM_CODEC); + PayloadTypeRegistry.playC2S().register(com.craisinlord.antarchy.content.network.PortalGunMoonAimPayload.TYPE, com.craisinlord.antarchy.content.network.PortalGunMoonAimPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(EyeOfStormPrimaryPayload.TYPE, EyeOfStormPrimaryPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(OpenGiantFryingPanPayload.TYPE, OpenGiantFryingPanPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(RoyalMountActionPayload.TYPE, RoyalMountActionPayload.STREAM_CODEC); @@ -135,6 +136,8 @@ public final class AntarchyFabricNetworking { }); ServerPlayNetworking.registerGlobalReceiver(PortalGunIndicatorRequestPayload.TYPE, (payload, context) -> context.server().execute(() -> com.craisinlord.antarchy.content.portalgun.PortalGunIndicatorSync.handleRequest(context.player(), payload))); + ServerPlayNetworking.registerGlobalReceiver(com.craisinlord.antarchy.content.network.PortalGunMoonAimPayload.TYPE, (payload, context) -> + context.server().execute(() -> com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.handle(context.player(), payload))); ServerPlayNetworking.registerGlobalReceiver(PortalGunResetPayload.TYPE, (payload, context) -> context.server().execute(() -> com.craisinlord.antarchy.content.portalgun.PortalGunResetManager.handleInput(context.player(), payload.action()))); ServerPlayNetworking.registerGlobalReceiver(EyeOfStormPrimaryPayload.TYPE, (payload, context) -> diff --git a/gradle.properties b/gradle.properties index 02846585..bccaf1c6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.configureondemand=true minecraft_version_1_21_1=1.21.1 modid=antarchy mod_id=antarchy -mod_version=2.2.0 +mod_version=2.2.1 maven_group=com.craisinlord mixin_version=0.15.4+mixin.0.8.7 diff --git a/neoforge-1.21.1/build.gradle b/neoforge-1.21.1/build.gradle index b425ba34..ff2de315 100644 --- a/neoforge-1.21.1/build.gradle +++ b/neoforge-1.21.1/build.gradle @@ -60,6 +60,7 @@ dependencies { runtimeOnly("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_neoforge}") implementation "software.bernie.geckolib:geckolib-neoforge-1.21.1:${geckolib_version}" compileOnly(files(rootProject.file("infinite_dimensions_jars/infinity-2.7.3+1.21.1-neoforge.jar"))) + compileOnly(files(rootProject.file("infinite_dimensions_jars/stellarview-1.21.1-0.5.3-neoforge.jar"))) runtimeOnly(files(rootProject.file("infinite_dimensions_jars/infinity-2.7.3+1.21.1-neoforge.jar"))) runtimeOnly("dev.architectury:architectury-neoforge:${architectury_api_version}") diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/PortalGunClientHandler.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/PortalGunClientHandler.java index 28c27a4f..13deb983 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/PortalGunClientHandler.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/PortalGunClientHandler.java @@ -25,6 +25,8 @@ public final class PortalGunClientHandler { com.craisinlord.antarchy.content.client.PortalGunResetClientState.clear(); } com.craisinlord.antarchy.content.client.PortalGunIndicatorClientState.setRequestSender(net.neoforged.neoforge.network.PacketDistributor::sendToServer); + com.craisinlord.antarchy.content.client.MoonSkyTracker.setSender(net.neoforged.neoforge.network.PacketDistributor::sendToServer); + com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.setClientReporter(com.craisinlord.antarchy.content.client.MoonSkyTracker::report); boolean hasPortalGun = mc.player != null && (mc.player.getMainHandItem().getItem() instanceof PortalGunItem || mc.player.getOffhandItem().getItem() instanceof PortalGunItem); boolean gameplayInput = mc.screen == null; boolean held = hasPortalGun && gameplayInput; @@ -50,6 +52,7 @@ public final class PortalGunClientHandler { boolean attackDown = mc.options.keyAttack.isDown(); if (attackDown && !lastAttackDown && !resetActive) { + com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.reportFromClient(); PacketDistributor.sendToServer(new PortalGunPrimaryPayload(offhand)); } lastAttackDown = attackDown; diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/network/AntarchyGravityNetworking.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/network/AntarchyGravityNetworking.java index 64e80ce6..3181cb3a 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/network/AntarchyGravityNetworking.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/network/AntarchyGravityNetworking.java @@ -69,6 +69,14 @@ public final class AntarchyGravityNetworking { } }); } + ).playToServer( + com.craisinlord.antarchy.content.network.PortalGunMoonAimPayload.TYPE, + com.craisinlord.antarchy.content.network.PortalGunMoonAimPayload.STREAM_CODEC, + (payload, context) -> context.enqueueWork(() -> { + if (context.player() instanceof ServerPlayer serverPlayer) { + com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.handle(serverPlayer, payload); + } + }) ).playToServer( com.craisinlord.antarchy.content.network.PortalGunResetPayload.TYPE, com.craisinlord.antarchy.content.network.PortalGunResetPayload.STREAM_CODEC, diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoForgeEvents.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoForgeEvents.java index e37c1368..691bd8b7 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoForgeEvents.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoForgeEvents.java @@ -247,6 +247,7 @@ public final class AntarchyNeoForgeEvents { for (ServerLevel level : event.getServer().getAllLevels()) { CavarynHordeManager.tick(level); com.craisinlord.antarchy.content.horde.CavarynCreatureSpawner.tick(level); + com.craisinlord.antarchy.content.entity.glimmer.GlimmerNightSpawner.tick(level); com.craisinlord.antarchy.content.worldgen.elythia.KingsTreeGridFeature.tickPendingSpawns(level); } } diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/PortalGunServerEvents.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/PortalGunServerEvents.java index 235f4543..17847162 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/PortalGunServerEvents.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/PortalGunServerEvents.java @@ -15,6 +15,7 @@ public final class PortalGunServerEvents { public static void onServerStopping(ServerStoppingEvent event) { com.craisinlord.antarchy.content.portalgun.PortalGunResetManager.clear(event.getServer()); com.craisinlord.antarchy.content.entity.ant.AntArrivalScheduler.clear(); + com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.clear(); } @SubscribeEvent