MINIONS... TONIGHT WE STEAL THE MOON

This commit is contained in:
craisinlord committed 2026-10-09 23:56:18 -05:00
1 parent e3b4e50f2b
commit 759f511b00
28 files changed
+447 -100

No files matched your search

@@ -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<PortalGunMoonAimPayload> sender = payload -> {};
private MoonSkyTracker() {
}
public static void setSender(Consumer<PortalGunMoonAimPayload> 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));
}
}
@@ -222,35 +222,20 @@ public class HoverboardEntity extends PathfinderMob implements GeoEntity {
private double resolveVerticalMotion(boolean holdingJump) { private double resolveVerticalMotion(boolean holdingJump) {
AntarchyGravityDirection gravityDirection = AntarchyGravityApi.getGravityDirection(this); AntarchyGravityDirection gravityDirection = AntarchyGravityApi.getGravityDirection(this);
double supportHeight = this.findSupportHeight(gravityDirection); double supportHeight = this.findSupportHeight(gravityDirection);
if (!gravityDirection.isInverted()) { double height = gravityDirection.isInverted() ? supportHeight - this.getY() : this.getY() - supportHeight;
double maxY = supportHeight + MAX_HOVER_HEIGHT;
if (holdingJump) { if (holdingJump) {
return this.getY() >= maxY ? 0.0D : ASCEND_SPEED; return height >= MAX_HOVER_HEIGHT ? 0.0D : ASCEND_SPEED;
} }
if (this.getY() <= supportHeight) { if (height <= 0.0D) {
return 0.0D; return 0.0D;
} }
double heightAboveBand = this.getY() - maxY; double heightAboveBand = height - MAX_HOVER_HEIGHT;
if (heightAboveBand > 0.0D) { if (heightAboveBand > 0.0D) {
return -Mth.clamp(SETTLE_DESCEND_SPEED + heightAboveBand * FAST_DESCEND_RAMP, SETTLE_DESCEND_SPEED, FAST_DESCEND_SPEED); return -Mth.clamp(SETTLE_DESCEND_SPEED + heightAboveBand * FAST_DESCEND_RAMP, SETTLE_DESCEND_SPEED, FAST_DESCEND_SPEED);
} }
return -SETTLE_DESCEND_SPEED; return -SETTLE_DESCEND_SPEED;
} }
double minY = supportHeight - MAX_HOVER_HEIGHT;
if (holdingJump) {
return this.getY() <= minY ? 0.0D : -ASCEND_SPEED;
}
if (this.getY() >= supportHeight) {
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);
}
return SETTLE_DESCEND_SPEED;
}
private double findSupportHeight(AntarchyGravityDirection gravityDirection) { private double findSupportHeight(AntarchyGravityDirection gravityDirection) {
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(Mth.floor(this.getX()), Mth.floor(this.getY()), Mth.floor(this.getZ())); BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(Mth.floor(this.getX()), Mth.floor(this.getY()), Mth.floor(this.getZ()));
if (!gravityDirection.isInverted()) { if (!gravityDirection.isInverted()) {
@@ -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<Level> 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<GlimmerEntity> 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<GlimmerEntity> 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<GlimmerEntity> 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> biome, EntityType<GlimmerEntity> type) {
return biome.value().getMobSettings().getMobs(MobCategory.CREATURE).unwrap().stream()
.anyMatch(data -> data.type == type);
}
}
@@ -113,6 +113,9 @@ public class PortalGunItem extends Item implements GeoItem {
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand usedHand) { public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand usedHand) {
ItemStack stack = player.getItemInHand(usedHand); ItemStack stack = player.getItemInHand(usedHand);
if (level.isClientSide) { if (level.isClientSide) {
if (!player.isShiftKeyDown()) {
com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.reportFromClient();
}
return InteractionResultHolder.consume(stack); return InteractionResultHolder.consume(stack);
} }
ServerLevel serverLevel = (ServerLevel) level; ServerLevel serverLevel = (ServerLevel) level;
@@ -312,6 +315,10 @@ public class PortalGunItem extends Item implements GeoItem {
if (!level.dimensionType().hasSkyLight() || level.dimensionType().hasCeiling()) { if (!level.dimensionType().hasSkyLight() || level.dimensionType().hasCeiling()) {
return false; 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)); return PortalGunMoonMath.isAimedAtMoon(this.worldLook(player), level.getTimeOfDay(1.0F));
} }
@@ -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<PortalGunMoonAimPayload> TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "portal_gun_moon_aim"));
public static final StreamCodec<ByteBuf, PortalGunMoonAimPayload> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.BOOL, PortalGunMoonAimPayload::tracked,
ByteBufCodecs.BOOL, PortalGunMoonAimPayload::aiming,
PortalGunMoonAimPayload::new
);
@Override
public Type<PortalGunMoonAimPayload> type() {
return TYPE;
}
}
@@ -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<UUID, Report> 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) {
}
}
@@ -30,6 +30,7 @@ import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket; import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; 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 MAX_CLIENT_TRANSIT_MOVEMENT_SQR = 100.0D;
private static final double PROJECTILE_PLANE_TOLERANCE = 0.1D; private static final double PROJECTILE_PLANE_TOLERANCE = 0.1D;
private static final double MOON_RANGE = 14.0D; 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_PULL_STRENGTH = 0.15D;
private static final double MOON_MAX_SPEED = 1.8D; private static final double MOON_MAX_SPEED = 1.8D;
private static final double MOON_MOUTH_DEPTH = 0.9D; 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 int MOON_VACUUM_INTERVAL = 10;
private static final float MOON_VACUUM_DAMAGE = 2.0F; private static final float MOON_VACUUM_DAMAGE = 2.0F;
private static final int MOON_WIND_INTERVAL = 40; 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 AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
private final Map<UUID, Integer> teleportCooldowns = new HashMap<>(); private final Map<UUID, Integer> teleportCooldowns = new HashMap<>();
private UUID ownerId; private UUID ownerId;
@@ -122,6 +125,7 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity {
private int pairTime; private int pairTime;
private int moonTicks; private int moonTicks;
private int moonSuckedBlocks; private int moonSuckedBlocks;
private final Map<UUID, Integer> moonLiftedBlocks = new HashMap<>();
private BlockPos supportOrigin = BlockPos.ZERO; private BlockPos supportOrigin = BlockPos.ZERO;
private BlockPos masterPos = BlockPos.ZERO; private BlockPos masterPos = BlockPos.ZERO;
private BlockPos basePos = BlockPos.ZERO; private BlockPos basePos = BlockPos.ZERO;
@@ -663,26 +667,23 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity {
PortalGunWorldPortalShape shape = this.getWorldPortalShape(); PortalGunWorldPortalShape shape = this.getWorldPortalShape();
Player owner = this.getOwnerId() == null ? null : level.getPlayerByUUID(this.getOwnerId()); Player owner = this.getOwnerId() == null ? null : level.getPlayerByUUID(this.getOwnerId());
this.pullMoonEntities(level, shape, owner); this.pullMoonEntities(level, shape, owner);
this.tickMoonLiftedBlocks(level, shape);
if (AntarchySettings.portalGunMoonPullsBlocks() && this.moonTicks % MOON_BLOCK_INTERVAL == 0) { if (AntarchySettings.portalGunMoonPullsBlocks() && this.moonTicks % MOON_BLOCK_INTERVAL == 0) {
this.pullMoonBlocks(level, shape, owner); 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) { private void pullMoonEntities(ServerLevel level, PortalGunWorldPortalShape shape, Player owner) {
Vec3 center = shape.center(); 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)); Vec3 target = center.add(shape.normal().scale(0.3D));
boolean vacuumTick = this.moonTicks % MOON_VACUUM_INTERVAL == 0; boolean vacuumTick = this.moonTicks % MOON_VACUUM_INTERVAL == 0;
for (Entity entity : level.getEntities(this, area, this::canMoonAffect)) { for (Entity entity : level.getEntities(this, area, this::canMoonAffect)) {
Vec3 position = entity.getBoundingBox().getCenter(); Vec3 position = entity.getBoundingBox().getCenter();
PortalGunWorldPortalShape.PortalLocalCoords local = shape.localCoords(position); PortalGunWorldPortalShape.PortalLocalCoords local = shape.localCoords(position);
double depth = local.depth(); double depth = local.depth();
double lateral = Math.sqrt(local.horizontal() * local.horizontal() + local.vertical() * local.vertical()); double distance = position.distanceTo(center);
if (depth < -0.5D || depth > MOON_RANGE || lateral > moonLateralLimit(shape, depth)) { if (depth < -0.5D || distance > MOON_RANGE) {
continue; continue;
} }
boolean atMouth = depth <= MOON_MOUTH_DEPTH + entity.getBbWidth() * 0.5D boolean atMouth = depth <= MOON_MOUTH_DEPTH + entity.getBbWidth() * 0.5D
@@ -694,7 +695,7 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity {
} }
continue; 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); double strength = MOON_PULL_STRENGTH * (0.35D + falloff * falloff * 1.6D);
Vec3 worldMotion = PortalGunTransitMath.entityVelocityToWorld(entity, entity.getDeltaMovement()) Vec3 worldMotion = PortalGunTransitMath.entityVelocityToWorld(entity, entity.getDeltaMovement())
.scale(0.92D) .scale(0.92D)
@@ -752,20 +753,20 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity {
int cap = AntarchySettings.portalGunMoonBlockCap(); int cap = AntarchySettings.portalGunMoonBlockCap();
int pulled = 0; int pulled = 0;
for (int ray = 0; ray < MOON_BLOCK_RAYS && pulled < MOON_BLOCKS_PER_PULL && this.moonSuckedBlocks < cap; ray++) { for (int ray = 0; ray < MOON_BLOCK_RAYS && pulled < MOON_BLOCKS_PER_PULL && this.moonSuckedBlocks < cap; ray++) {
double limit = moonLateralLimit(shape, MOON_RANGE); Vec3 direction = new Vec3(this.random.nextGaussian(), this.random.nextGaussian(), this.random.nextGaussian());
double horizontal = (this.random.nextDouble() * 2.0D - 1.0D) * limit; if (direction.lengthSqr() < 1.0E-6D) {
double vertical = (this.random.nextDouble() * 2.0D - 1.0D) * limit;
if (horizontal * horizontal + vertical * vertical > limit * limit) {
continue; 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() Vec3 start = shape.center()
.add(shape.right().scale((this.random.nextDouble() * 2.0D - 1.0D) * shape.halfWidth())) .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.up().scale((this.random.nextDouble() * 2.0D - 1.0D) * shape.halfHeight()))
.add(shape.normal().scale(0.5D)); .add(shape.normal().scale(0.3D));
Vec3 end = shape.center() Vec3 end = start.add(direction.scale(MOON_RANGE));
.add(shape.right().scale(horizontal))
.add(shape.up().scale(vertical))
.add(shape.normal().scale(MOON_RANGE));
BlockPos hit = this.firstBlockAlong(level, shape, start, end); BlockPos hit = this.firstBlockAlong(level, shape, start, end);
if (hit == null) { if (hit == null) {
continue; continue;
@@ -775,16 +776,44 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity {
|| owner != null && !level.mayInteract(owner, hit)) { || owner != null && !level.mayInteract(owner, hit)) {
continue; 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) { if (falling == null) {
continue; continue;
} }
falling.setNoGravity(true); falling.setNoGravity(true);
this.moonLiftedBlocks.put(falling.getUUID(), this.moonTicks);
pulled++; pulled++;
this.moonSuckedBlocks++; this.moonSuckedBlocks++;
} }
} }
private void tickMoonLiftedBlocks(ServerLevel level, PortalGunWorldPortalShape shape) {
Iterator<Map.Entry<UUID, Integer>> iterator = this.moonLiftedBlocks.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<UUID, Integer> 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) { private BlockPos firstBlockAlong(ServerLevel level, PortalGunWorldPortalShape shape, Vec3 start, Vec3 end) {
Vec3 delta = end.subtract(start); Vec3 delta = end.subtract(start);
int steps = Math.max(1, (int) Math.ceil(delta.length() / MOON_RAY_STEP)); 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; continue;
} }
previous = pos; previous = pos;
if (shape.localCoords(Vec3.atCenterOf(pos)).depth() < 0.5D) {
continue;
}
if (!level.isInWorldBounds(pos) || !level.getWorldBorder().isWithinBounds(pos)) { if (!level.isInWorldBounds(pos) || !level.getWorldBorder().isWithinBounds(pos)) {
return null; return null;
} }
@@ -805,9 +831,19 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity {
if (state == null) { if (state == null) {
return null; return null;
} }
if (!state.isAir()) { if (state.isAir() || this.containsPortalSpot(pos)) {
return 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; return null;
} }
@@ -821,13 +857,16 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity {
private void spawnMoonParticles() { private void spawnMoonParticles() {
PortalGunWorldPortalShape shape = this.getWorldPortalShape(); PortalGunWorldPortalShape shape = this.getWorldPortalShape();
Vec3 center = shape.center(); Vec3 center = shape.center();
for (int i = 0; i < 4; i++) { for (int i = 0; i < 6; i++) {
double depth = 1.0D + this.random.nextDouble() * MOON_RANGE * 0.6D; Vec3 direction = new Vec3(this.random.nextGaussian(), this.random.nextGaussian(), this.random.nextGaussian());
double limit = moonLateralLimit(shape, depth); if (direction.lengthSqr() < 1.0E-6D) {
Vec3 start = center continue;
.add(shape.right().scale((this.random.nextDouble() * 2.0D - 1.0D) * limit)) }
.add(shape.up().scale((this.random.nextDouble() * 2.0D - 1.0D) * limit)) direction = direction.normalize();
.add(shape.normal().scale(depth)); 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); 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); 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.putBoolean("Moon", true);
tag.putInt("MoonTicks", this.moonTicks); tag.putInt("MoonTicks", this.moonTicks);
tag.putInt("MoonSuckedBlocks", this.moonSuckedBlocks); 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("Side", this.getPortalSide().ordinal());
tag.putInt("Facing", this.getFacingDirection().get3DDataValue()); 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.entityData.set(MOON, tag.getBoolean("Moon"));
this.moonTicks = tag.getInt("MoonTicks"); this.moonTicks = tag.getInt("MoonTicks");
this.moonSuckedBlocks = tag.getInt("MoonSuckedBlocks"); 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(SIDE, tag.getInt("Side"));
this.entityData.set(FACING, tag.getInt("Facing")); this.entityData.set(FACING, tag.getInt("Facing"));
this.entityData.set(UP_AXIS, tag.getInt("UpAxis")); this.entityData.set(UP_AXIS, tag.getInt("UpAxis"));
@@ -1153,6 +1201,9 @@ public class PortalGunPortalEntity extends Entity implements GeoEntity {
@Override @Override
public void remove(Entity.RemovalReason reason) { public void remove(Entity.RemovalReason reason) {
if (this.isMoonPortal() && this.level() instanceof ServerLevel moonLevel) {
this.releaseMoonLiftedBlocks(moonLevel);
}
Level level = this.level(); Level level = this.level();
UUID ownerId = this.ownerId; UUID ownerId = this.ownerId;
boolean destroyPortal = reason.shouldDestroy(); boolean destroyPortal = reason.shouldDestroy();
@@ -5,11 +5,14 @@ import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi;
import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection;
import com.craisinlord.antarchy.content.gravity.AntarchyGravityTransition; import com.craisinlord.antarchy.content.gravity.AntarchyGravityTransition;
import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.config.AntarchySettings;
import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@@ -49,6 +52,7 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile {
private static final TagKey<Block> GLASS_PANES = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "glass_panes")); private static final TagKey<Block> GLASS_PANES = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "glass_panes"));
private static final int MAX_TICKETED_PROJECTILES = 20; private static final int MAX_TICKETED_PROJECTILES = 20;
private static final int PROJECTILE_TICKET_LEVEL = 31; private static final int PROJECTILE_TICKET_LEVEL = 31;
private static final int MAX_CHUNK_WAIT_TICKS = 200;
private static final TicketType<UUID> PROJECTILE_TICKET = TicketType.create("antarchy_portal_projectile", Comparator.comparing(UUID::toString)); private static final TicketType<UUID> PROJECTILE_TICKET = TicketType.create("antarchy_portal_projectile", Comparator.comparing(UUID::toString));
private static final LinkedHashMap<UUID, ProjectileTicket> PROJECTILE_TICKETS = new LinkedHashMap<>(); private static final LinkedHashMap<UUID, ProjectileTicket> PROJECTILE_TICKETS = new LinkedHashMap<>();
private static final EntityDataAccessor<Integer> SIDE = SynchedEntityData.defineId(PortalGunProjectileEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor<Integer> SIDE = SynchedEntityData.defineId(PortalGunProjectileEntity.class, EntityDataSerializers.INT);
@@ -74,6 +78,7 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile {
private UUID gunId; private UUID gunId;
private boolean spawnSynced; private boolean spawnSynced;
private boolean ticketRegistered; private boolean ticketRegistered;
private int chunkWaitTicks;
public int portalWidth = 1; public int portalWidth = 1;
public int portalHeight = 2; public int portalHeight = 2;
@@ -207,8 +212,8 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile {
this.setDeltaMovement(this.getSyncedVelocity()); this.setDeltaMovement(this.getSyncedVelocity());
this.spawnSynced = true; this.spawnSynced = true;
} }
if (!this.level().isClientSide && !this.isRemoved()) { if (this.level() instanceof ServerLevel serverLevel && !this.isRemoved() && !this.prepareServerStep(serverLevel)) {
this.updateProjectileTicket(); return;
} }
this.baseTick(); this.baseTick();
if (this.isRemoved()) { if (this.isRemoved()) {
@@ -260,9 +265,6 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile {
if (this.isRemoved()) { if (this.isRemoved()) {
return; return;
} }
if (!this.level().isClientSide && !this.isRemoved()) {
this.updateProjectileTicket();
}
if (this.isInWater()) { if (this.isInWater()) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
float backtrack = 0.25F; float backtrack = 0.25F;
@@ -293,34 +295,78 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile {
super.remove(reason); super.remove(reason);
} }
private void updateProjectileTicket() { private boolean prepareServerStep(ServerLevel level) {
if (!(this.level() instanceof ServerLevel serverLevel)) { Vec3 position = this.position();
return; 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<ChunkPos> path = chunksAlong(position, position.add(motion));
boolean chunkload = AntarchySettings.portalGunCanPortalProjectilesChunkload();
if (chunkload) {
this.updateProjectileTicket(level, path);
} else {
this.releaseProjectileTicket(); 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<ChunkPos> 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<ChunkPos> 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<ChunkPos> chunks) {
UUID ticketId = this.getUUID(); UUID ticketId = this.getUUID();
ProjectileTicket current = PROJECTILE_TICKETS.get(ticketId); 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; return;
} }
if (current != null) { if (current != null) {
current.level.getChunkSource().removeRegionTicket(PROJECTILE_TICKET, current.chunkPos, PROJECTILE_TICKET_LEVEL, ticketId); removeTicket(ticketId, current);
PROJECTILE_TICKETS.remove(ticketId); PROJECTILE_TICKETS.remove(ticketId);
} }
while (PROJECTILE_TICKETS.size() >= MAX_TICKETED_PROJECTILES) { while (PROJECTILE_TICKETS.size() >= MAX_TICKETED_PROJECTILES) {
Map.Entry<UUID, ProjectileTicket> oldest = PROJECTILE_TICKETS.entrySet().iterator().next(); Map.Entry<UUID, ProjectileTicket> 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()); PROJECTILE_TICKETS.remove(oldest.getKey());
} }
serverLevel.getChunkSource().addRegionTicket(PROJECTILE_TICKET, chunkPos, PROJECTILE_TICKET_LEVEL, ticketId); for (ChunkPos chunk : chunks) {
PROJECTILE_TICKETS.put(ticketId, new ProjectileTicket(serverLevel, chunkPos)); serverLevel.getChunkSource().addRegionTicket(PROJECTILE_TICKET, chunk, PROJECTILE_TICKET_LEVEL, ticketId);
}
PROJECTILE_TICKETS.put(ticketId, new ProjectileTicket(serverLevel, List.copyOf(chunks)));
this.ticketRegistered = true; 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() { private void releaseProjectileTicket() {
if (!this.ticketRegistered) { if (!this.ticketRegistered) {
return; return;
@@ -328,20 +374,19 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile {
UUID ticketId = this.getUUID(); UUID ticketId = this.getUUID();
ProjectileTicket ticket = PROJECTILE_TICKETS.remove(ticketId); ProjectileTicket ticket = PROJECTILE_TICKETS.remove(ticketId);
if (ticket != null) { if (ticket != null) {
ticket.level.getChunkSource().removeRegionTicket(PROJECTILE_TICKET, ticket.chunkPos, PROJECTILE_TICKET_LEVEL, ticketId); removeTicket(ticketId, ticket);
} }
this.ticketRegistered = false; this.ticketRegistered = false;
} }
public static void releaseAllProjectileTickets() { public static void releaseAllProjectileTickets() {
for (Map.Entry<UUID, ProjectileTicket> entry : PROJECTILE_TICKETS.entrySet()) { for (Map.Entry<UUID, ProjectileTicket> entry : PROJECTILE_TICKETS.entrySet()) {
ProjectileTicket ticket = entry.getValue(); removeTicket(entry.getKey(), entry.getValue());
ticket.level.getChunkSource().removeRegionTicket(PROJECTILE_TICKET, ticket.chunkPos, PROJECTILE_TICKET_LEVEL, entry.getKey());
} }
PROJECTILE_TICKETS.clear(); PROJECTILE_TICKETS.clear();
} }
private record ProjectileTicket(ServerLevel level, ChunkPos chunkPos) { private record ProjectileTicket(ServerLevel level, List<ChunkPos> chunks) {
} }
@Override @Override
@@ -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);
}
}
@@ -147,6 +147,7 @@
], ],
"client": [ "client": [
"client.CameraBasisAccessor", "client.CameraBasisAccessor",
"compat.stellarview.StellarViewLunaDirectionMixin",
"client.LevelRendererPortalViewAreaAccessor", "client.LevelRendererPortalViewAreaAccessor",
"client.LevelRendererPortalViewAreaMixin", "client.LevelRendererPortalViewAreaMixin",
"client.LevelRendererPortalLifecycleMixin", "client.LevelRendererPortalLifecycleMixin",
@@ -74,7 +74,7 @@
"humidity": [0.84, 1.0], "humidity": [0.84, 1.0],
"continentalness": [0.25, 0.72], "continentalness": [0.25, 0.72],
"erosion": [-0.5, 0.55], "erosion": [-0.5, 0.55],
"weirdness": [-0.55, 0.62], "weirdness": [-0.35, 0.62],
"depth": [0.0, 1.0], "depth": [0.0, 1.0],
"offset": 0.0 "offset": 0.0
} }
@@ -94,11 +94,11 @@
{ {
"biome": "antarchy:glimmering_pools", "biome": "antarchy:glimmering_pools",
"parameters": { "parameters": {
"temperature": [0.58, 0.76], "temperature": [0.52, 0.78],
"humidity": [0.88, 1.0], "humidity": [0.84, 1.0],
"continentalness": [0.3, 0.65], "continentalness": [0.3, 0.65],
"erosion": [-0.05, 0.45], "erosion": [-0.3, 0.45],
"weirdness": [-0.7, -0.25], "weirdness": [-0.8, -0.35],
"depth": [0.0, 0.25], "depth": [0.0, 0.25],
"offset": 0.0 "offset": 0.0
} }
@@ -31,10 +31,6 @@
"antarchy:mantis": { "antarchy:mantis": {
"energy_budget": 0.1, "energy_budget": 0.1,
"charge": 15.0 "charge": 15.0
},
"antarchy:glimmer": {
"energy_budget": 0.1,
"charge": 9
} }
}, },
"carvers": { "carvers": {
@@ -37,10 +37,6 @@
"antarchy:basilisk": { "antarchy:basilisk": {
"energy_budget": 0.1, "energy_budget": 0.1,
"charge": 14.0 "charge": 14.0
},
"antarchy:glimmer": {
"energy_budget": 0.1,
"charge": 9
} }
}, },
"carvers": { "carvers": {
@@ -37,10 +37,6 @@
"antarchy:basilisk": { "antarchy:basilisk": {
"energy_budget": 0.1, "energy_budget": 0.1,
"charge": 14.0 "charge": 14.0
},
"antarchy:glimmer": {
"energy_budget": 0.1,
"charge": 9
} }
}, },
"carvers": { "carvers": {
@@ -24,10 +24,6 @@
} }
}, },
"spawn_costs": { "spawn_costs": {
"antarchy:glimmer": {
"energy_budget": 0.1,
"charge": 9
}
}, },
"carvers": { "carvers": {
"air": [], "air": [],
@@ -34,10 +34,6 @@
} }
}, },
"spawn_costs": { "spawn_costs": {
"antarchy:glimmer": {
"energy_budget": 0.1,
"charge": 9
}
}, },
"carvers": { "carvers": {
"air": [], "air": [],
@@ -31,10 +31,6 @@
"antarchy:mantis": { "antarchy:mantis": {
"energy_budget": 0.1, "energy_budget": 0.1,
"charge": 15.0 "charge": 15.0
},
"antarchy:glimmer": {
"energy_budget": 0.1,
"charge": 9
} }
}, },
"carvers": { "carvers": {
+1
View File
@@ -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/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/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/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) // Cloth Config — optional, powers the in-game settings screen (AntarchyClothConfigScreenBuilder)
// via the Mod Menu integration below. compileOnly + modLocalRuntime only: never bundled or // via the Mod Menu integration below. compileOnly + modLocalRuntime only: never bundled or
@@ -79,6 +79,7 @@ public final class AntarchyFabricEvents {
ServerLifecycleEvents.SERVER_STOPPING.register(server -> PortalGunProjectileEntity.releaseAllProjectileTickets()); ServerLifecycleEvents.SERVER_STOPPING.register(server -> PortalGunProjectileEntity.releaseAllProjectileTickets());
ServerLifecycleEvents.SERVER_STOPPING.register(com.craisinlord.antarchy.content.portalgun.PortalGunResetManager::clear); 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.entity.ant.AntArrivalScheduler.clear());
ServerLifecycleEvents.SERVER_STOPPING.register(server -> com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.clear());
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
ChronosphereManager.refresh(handler.player); ChronosphereManager.refresh(handler.player);
TimeDilationManager.resyncPersistentEffects(handler.player); TimeDilationManager.resyncPersistentEffects(handler.player);
@@ -214,6 +215,7 @@ public final class AntarchyFabricEvents {
for (ServerLevel level : server.getAllLevels()) { for (ServerLevel level : server.getAllLevels()) {
CavarynHordeManager.tick(level); CavarynHordeManager.tick(level);
com.craisinlord.antarchy.content.horde.CavarynCreatureSpawner.tick(level); com.craisinlord.antarchy.content.horde.CavarynCreatureSpawner.tick(level);
com.craisinlord.antarchy.content.entity.glimmer.GlimmerNightSpawner.tick(level);
ThoraxisUndersideManager.tick(level); ThoraxisUndersideManager.tick(level);
com.craisinlord.antarchy.content.worldgen.elythia.KingsTreeGridFeature.tickPendingSpawns(level); com.craisinlord.antarchy.content.worldgen.elythia.KingsTreeGridFeature.tickPendingSpawns(level);
tickInvertedPlayers(level, activeThisTick); tickInvertedPlayers(level, activeThisTick);
@@ -46,6 +46,7 @@ public final class PortalGunClientHandler {
boolean attackDown = mc.options.keyAttack.isDown(); boolean attackDown = mc.options.keyAttack.isDown();
if (attackDown && !lastAttackDown && !resetActive) { if (attackDown && !lastAttackDown && !resetActive) {
com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.reportFromClient();
ClientPlayNetworking.send(new PortalGunPrimaryPayload(offhand)); ClientPlayNetworking.send(new PortalGunPrimaryPayload(offhand));
} }
lastAttackDown = attackDown; lastAttackDown = attackDown;
@@ -43,6 +43,8 @@ public final class AntarchyFabricClientNetworking {
context.client().execute(() -> com.craisinlord.antarchy.content.client.AntarchyGameClientState.update(payload))); context.client().execute(() -> com.craisinlord.antarchy.content.client.AntarchyGameClientState.update(payload)));
com.craisinlord.antarchy.content.network.AntarchyGameNetworking.setSender(ClientPlayNetworking::send); com.craisinlord.antarchy.content.network.AntarchyGameNetworking.setSender(ClientPlayNetworking::send);
com.craisinlord.antarchy.content.client.PortalGunIndicatorClientState.setRequestSender(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) -> ClientPlayNetworking.registerGlobalReceiver(PortalGunIndicatorPayload.TYPE, (payload, context) ->
context.client().execute(() -> com.craisinlord.antarchy.content.client.PortalGunIndicatorClientState.update(payload))); context.client().execute(() -> com.craisinlord.antarchy.content.client.PortalGunIndicatorClientState.update(payload)));
ClientPlayNetworking.registerGlobalReceiver(GravityStatePayload.TYPE, (payload, context) -> ClientPlayNetworking.registerGlobalReceiver(GravityStatePayload.TYPE, (payload, context) ->
@@ -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(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(PortalGunIndicatorRequestPayload.TYPE, PortalGunIndicatorRequestPayload.STREAM_CODEC);
PayloadTypeRegistry.playC2S().register(PortalGunResetPayload.TYPE, PortalGunResetPayload.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(EyeOfStormPrimaryPayload.TYPE, EyeOfStormPrimaryPayload.STREAM_CODEC);
PayloadTypeRegistry.playC2S().register(OpenGiantFryingPanPayload.TYPE, OpenGiantFryingPanPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(OpenGiantFryingPanPayload.TYPE, OpenGiantFryingPanPayload.STREAM_CODEC);
PayloadTypeRegistry.playC2S().register(RoyalMountActionPayload.TYPE, RoyalMountActionPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(RoyalMountActionPayload.TYPE, RoyalMountActionPayload.STREAM_CODEC);
@@ -135,6 +136,8 @@ public final class AntarchyFabricNetworking {
}); });
ServerPlayNetworking.registerGlobalReceiver(PortalGunIndicatorRequestPayload.TYPE, (payload, context) -> ServerPlayNetworking.registerGlobalReceiver(PortalGunIndicatorRequestPayload.TYPE, (payload, context) ->
context.server().execute(() -> com.craisinlord.antarchy.content.portalgun.PortalGunIndicatorSync.handleRequest(context.player(), payload))); 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) -> ServerPlayNetworking.registerGlobalReceiver(PortalGunResetPayload.TYPE, (payload, context) ->
context.server().execute(() -> com.craisinlord.antarchy.content.portalgun.PortalGunResetManager.handleInput(context.player(), payload.action()))); context.server().execute(() -> com.craisinlord.antarchy.content.portalgun.PortalGunResetManager.handleInput(context.player(), payload.action())));
ServerPlayNetworking.registerGlobalReceiver(EyeOfStormPrimaryPayload.TYPE, (payload, context) -> ServerPlayNetworking.registerGlobalReceiver(EyeOfStormPrimaryPayload.TYPE, (payload, context) ->
+1 -1
View File
@@ -6,7 +6,7 @@ org.gradle.configureondemand=true
minecraft_version_1_21_1=1.21.1 minecraft_version_1_21_1=1.21.1
modid=antarchy modid=antarchy
mod_id=antarchy mod_id=antarchy
mod_version=2.2.0 mod_version=2.2.1
maven_group=com.craisinlord maven_group=com.craisinlord
mixin_version=0.15.4+mixin.0.8.7 mixin_version=0.15.4+mixin.0.8.7
+1
View File
@@ -60,6 +60,7 @@ dependencies {
runtimeOnly("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_neoforge}") runtimeOnly("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_neoforge}")
implementation "software.bernie.geckolib:geckolib-neoforge-1.21.1:${geckolib_version}" 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/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(files(rootProject.file("infinite_dimensions_jars/infinity-2.7.3+1.21.1-neoforge.jar")))
runtimeOnly("dev.architectury:architectury-neoforge:${architectury_api_version}") runtimeOnly("dev.architectury:architectury-neoforge:${architectury_api_version}")
@@ -25,6 +25,8 @@ public final class PortalGunClientHandler {
com.craisinlord.antarchy.content.client.PortalGunResetClientState.clear(); 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.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 hasPortalGun = mc.player != null && (mc.player.getMainHandItem().getItem() instanceof PortalGunItem || mc.player.getOffhandItem().getItem() instanceof PortalGunItem);
boolean gameplayInput = mc.screen == null; boolean gameplayInput = mc.screen == null;
boolean held = hasPortalGun && gameplayInput; boolean held = hasPortalGun && gameplayInput;
@@ -50,6 +52,7 @@ public final class PortalGunClientHandler {
boolean attackDown = mc.options.keyAttack.isDown(); boolean attackDown = mc.options.keyAttack.isDown();
if (attackDown && !lastAttackDown && !resetActive) { if (attackDown && !lastAttackDown && !resetActive) {
com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.reportFromClient();
PacketDistributor.sendToServer(new PortalGunPrimaryPayload(offhand)); PacketDistributor.sendToServer(new PortalGunPrimaryPayload(offhand));
} }
lastAttackDown = attackDown; lastAttackDown = attackDown;
@@ -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( ).playToServer(
com.craisinlord.antarchy.content.network.PortalGunResetPayload.TYPE, com.craisinlord.antarchy.content.network.PortalGunResetPayload.TYPE,
com.craisinlord.antarchy.content.network.PortalGunResetPayload.STREAM_CODEC, com.craisinlord.antarchy.content.network.PortalGunResetPayload.STREAM_CODEC,
@@ -247,6 +247,7 @@ public final class AntarchyNeoForgeEvents {
for (ServerLevel level : event.getServer().getAllLevels()) { for (ServerLevel level : event.getServer().getAllLevels()) {
CavarynHordeManager.tick(level); CavarynHordeManager.tick(level);
com.craisinlord.antarchy.content.horde.CavarynCreatureSpawner.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); com.craisinlord.antarchy.content.worldgen.elythia.KingsTreeGridFeature.tickPendingSpawns(level);
} }
} }
@@ -15,6 +15,7 @@ public final class PortalGunServerEvents {
public static void onServerStopping(ServerStoppingEvent event) { public static void onServerStopping(ServerStoppingEvent event) {
com.craisinlord.antarchy.content.portalgun.PortalGunResetManager.clear(event.getServer()); com.craisinlord.antarchy.content.portalgun.PortalGunResetManager.clear(event.getServer());
com.craisinlord.antarchy.content.entity.ant.AntArrivalScheduler.clear(); com.craisinlord.antarchy.content.entity.ant.AntArrivalScheduler.clear();
com.craisinlord.antarchy.content.portalgun.PortalGunMoonAimSync.clear();
} }
@SubscribeEvent @SubscribeEvent