From f23cf63f4f386e58ee37e392ca0443fa3e34f1cd Mon Sep 17 00:00:00 2001 From: craisinlord Date: Wed, 8 Jul 2026 13:33:22 -0500 Subject: [PATCH] finish ant portals optional flint and steel functionality dorrie --- .../antarchy/config/AntarchySettings.java | 16 +- .../block/AntDimensionPortalBlock.java | 21 +- .../antarchy/content/entity/DorrieEntity.java | 303 ++++++++++++++++-- .../content/entity/EmperorScorpionEntity.java | 9 + .../portal/PermanentPortalManager.java | 27 +- .../content/portal/PermanentPortalShape.java | 86 +++++ .../portal/PermanentPortalTeleporter.java | 128 +++++++- .../FlintAndSteelPortalIgnitionMixin.java | 53 +++ .../resources/antarchy-common.mixins.json | 1 + .../assets/antarchy/geo/dorrie.geo.json | 2 +- .../antarchy/textures/entity/dorrie.png | Bin 8734 -> 9723 bytes .../textures/entity/dorrie_saddle.png | Bin 11820 -> 11796 bytes .../fabric/AntarchyConfigModuleFabric.java | 1 + .../AntarchyConfigModuleNeoforge.java | 1 + .../antarchy/neoforge/AntarchyMiscConfig.java | 3 + 15 files changed, 598 insertions(+), 53 deletions(-) create mode 100644 common/src/main/java/com/craisinlord/antarchy/mixins/FlintAndSteelPortalIgnitionMixin.java diff --git a/common/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java b/common/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java index a5ab19e5..db23fffd 100644 --- a/common/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java +++ b/common/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java @@ -448,6 +448,7 @@ public final class AntarchySettings { private static int fallenKingCrownArmorValue = 2; private static double fallenKingCrownArmorToughness = 0.0D; private static boolean permanentPortalsEnabled = true; + private static boolean permanentPortalsFlintAndSteelEnabled = false; private static boolean elythiaPortalEnabled = true; private static boolean thoraxisPortalEnabled = true; private static boolean cavarynPortalEnabled = true; @@ -965,6 +966,10 @@ public final class AntarchySettings { permanentPortalsEnabled = value; } + public static void setPermanentPortalsFlintAndSteelEnabled(boolean value) { + permanentPortalsFlintAndSteelEnabled = value; + } + public static void setElythiaPortalEnabled(boolean value) { elythiaPortalEnabled = value; } @@ -977,6 +982,12 @@ public final class AntarchySettings { cavarynPortalEnabled = value; } + public static boolean permanentPortalsEnabled() { return permanentPortalsEnabled; } + public static boolean permanentPortalsFlintAndSteelEnabled() { return permanentPortalsFlintAndSteelEnabled; } + public static boolean elythiaPortalEnabled() { return elythiaPortalEnabled; } + public static boolean thoraxisPortalEnabled() { return thoraxisPortalEnabled; } + public static boolean cavarynPortalEnabled() { return cavarynPortalEnabled; } + public static void setBrownAntRequiresReagent(boolean value) { brownAntRequiresReagent = value; } @@ -2454,11 +2465,6 @@ public final class AntarchySettings { public static double fallenKingCrownArmorToughness() { return fallenKingCrownArmorToughness; } public static void setFallenKingCrownArmorToughness(double value) { fallenKingCrownArmorToughness = value; } - public static boolean permanentPortalsEnabled() { return permanentPortalsEnabled; } - public static boolean elythiaPortalEnabled() { return elythiaPortalEnabled; } - public static boolean thoraxisPortalEnabled() { return thoraxisPortalEnabled; } - public static boolean cavarynPortalEnabled() { return cavarynPortalEnabled; } - public static boolean elythiaFireflyParticlesEnabled() { return elythiaFireflyParticlesEnabled; } public static void setElythiaFireflyParticlesEnabled(boolean value) { elythiaFireflyParticlesEnabled = value; } diff --git a/common/src/main/java/com/craisinlord/antarchy/content/block/AntDimensionPortalBlock.java b/common/src/main/java/com/craisinlord/antarchy/content/block/AntDimensionPortalBlock.java index eca7464d..27eeff06 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/block/AntDimensionPortalBlock.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/block/AntDimensionPortalBlock.java @@ -2,6 +2,7 @@ package com.craisinlord.antarchy.content.block; import com.craisinlord.antarchy.content.portal.PermanentPortalManager; import com.craisinlord.antarchy.content.portal.PermanentPortalType; +import com.craisinlord.antarchy.content.portal.PermanentPortalTeleporter; import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -11,6 +12,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.RandomSource; +import net.minecraft.world.level.portal.DimensionTransition; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; @@ -27,7 +29,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -public final class AntDimensionPortalBlock extends Block { +public final class AntDimensionPortalBlock extends Block implements net.minecraft.world.level.block.Portal { public static final EnumProperty AXIS = BlockStateProperties.HORIZONTAL_AXIS; private static final VoxelShape X_SHAPE = Block.box(0.0D, 0.0D, 6.0D, 16.0D, 16.0D, 10.0D); private static final VoxelShape Z_SHAPE = Block.box(6.0D, 0.0D, 0.0D, 10.0D, 16.0D, 16.0D); @@ -85,10 +87,25 @@ public final class AntDimensionPortalBlock extends Block { @Override public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { if (!level.isClientSide()) { - PermanentPortalManager.handleEntityInsidePortal(entity, this.type); + entity.setAsInsidePortal(this, pos); } } + @Override + public net.minecraft.world.level.block.Portal.Transition getLocalTransition() { + return net.minecraft.world.level.block.Portal.Transition.CONFUSION; + } + + @Override + public int getPortalTransitionTime(ServerLevel level, Entity entity) { + return 20; + } + + @Override + public DimensionTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) { + return PermanentPortalTeleporter.createTransition(level, entity, pos, this.type); + } + @Override protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) { super.onPlace(state, level, pos, oldState, movedByPiston); diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/DorrieEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/DorrieEntity.java index 613e1fd1..09cc8fed 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/entity/DorrieEntity.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/DorrieEntity.java @@ -3,6 +3,7 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; import java.util.EnumSet; import java.util.List; +import net.minecraft.core.BlockPos; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; @@ -12,6 +13,8 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; +import net.minecraft.tags.FluidTags; +import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; @@ -26,8 +29,6 @@ import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.control.MoveControl; import net.minecraft.world.entity.ai.control.SmoothSwimmingLookControl; import net.minecraft.world.entity.ai.control.SmoothSwimmingMoveControl; -import net.minecraft.world.entity.ai.goal.BreathAirGoal; -import net.minecraft.world.entity.ai.goal.FloatGoal; import net.minecraft.world.entity.ai.goal.Goal; import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal; @@ -67,11 +68,11 @@ public class DorrieEntity extends Animal implements GeoEntity { SynchedEntityData.defineId(DorrieEntity.class, EntityDataSerializers.INT); private static final int MAX_CHARGE_TICKS = 40; - private static final float WATER_RIDE_SPEED = 1.26F; - private static final float LAND_BEACH_SPEED = 0.04F; + private static final float WATER_RIDE_SPEED = 1.84F; + private static final float LAND_BEACH_SPEED = 0.10F; private static final int QUIRK_DURATION_TICKS = 65; - private static final int MIN_QUIRK_COOLDOWN_TICKS = 180; - private static final int MAX_QUIRK_COOLDOWN_TICKS = 320; + private static final int MIN_QUIRK_COOLDOWN_TICKS = 140; + private static final int MAX_QUIRK_COOLDOWN_TICKS = 260; private static final double MOVING_ANIM_THRESHOLD_SQ = 0.0025D; private static final RawAnimation IDLE_GROUND_ANIM = RawAnimation.begin().thenLoop("idle_ground"); @@ -127,20 +128,19 @@ public class DorrieEntity extends Animal implements GeoEntity { @Override protected void registerGoals() { - this.goalSelector.addGoal(0, new FloatGoal(this)); - this.goalSelector.addGoal(1, new BreathAirGoal(this)); - this.goalSelector.addGoal(2, new TryFindWaterGoal(this)); - this.goalSelector.addGoal(3, new HuntCheepGoal(this)); - this.goalSelector.addGoal(4, new RandomSwimmingGoal(this, 1.0D, 10)); - this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.45D, 60)); - this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F)); - this.goalSelector.addGoal(7, new RandomLookAroundGoal(this)); + this.goalSelector.addGoal(0, new TryFindWaterGoal(this)); + this.goalSelector.addGoal(1, new HuntCheepGoal(this)); + this.goalSelector.addGoal(2, new DolphinSwimGoal()); + this.goalSelector.addGoal(3, new RandomSwimmingGoal(this, 1.35D, 8)); + this.goalSelector.addGoal(4, new WaterAvoidingRandomStrollGoal(this, 0.72D, 40)); + this.goalSelector.addGoal(5, new LookAtPlayerGoal(this, Player.class, 6.0F)); + this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); } public static AttributeSupplier.Builder createAttributes() { return Mob.createMobAttributes() .add(Attributes.MAX_HEALTH, AntarchySettings.dorrieHealth()) - .add(Attributes.MOVEMENT_SPEED, 1.0D) + .add(Attributes.MOVEMENT_SPEED, 1.15D) .add(Attributes.FOLLOW_RANGE, 16.0D) .add(Attributes.ATTACK_DAMAGE, 4.0D); } @@ -255,13 +255,20 @@ public class DorrieEntity extends Animal implements GeoEntity { protected Vec3 getRiddenInput(Player player, Vec3 travelVector) { float forward = player.zza; float strafe = player.xxa * 0.5F; - return new Vec3(strafe, 0, forward); + float pitch = Mth.clamp(player.getXRot(), -60.0F, 60.0F); + double vertical = 0.0D; + if (player.zza > 0.02F) { + vertical = -pitch / 45.0D; + } else if (Math.abs(pitch) > 10.0F) { + vertical = -pitch / 60.0D; + } + return new Vec3(strafe, Mth.clamp(vertical, -1.0D, 1.0D), forward); } @Override protected float getRiddenSpeed(Player player) { float speed = (this.isInWater() || this.isInLava()) - ? WATER_RIDE_SPEED * (1.0F + Math.min(this.swimForwardTicks, 60) * 0.025F) + ? WATER_RIDE_SPEED * (1.0F + Math.min(this.swimForwardTicks, 60) * 0.03F) : LAND_BEACH_SPEED; return (float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * speed; } @@ -270,6 +277,7 @@ public class DorrieEntity extends Animal implements GeoEntity { public void tick() { super.tick(); this.updateNavigationMode(); + this.setNoGravity(this.isInWater() || this.isInLava()); if (this.getControllingPassenger() instanceof Player player) { this.setYRot(player.getYRot()); @@ -315,13 +323,6 @@ public class DorrieEntity extends Animal implements GeoEntity { this.tickQuirkAnimation(); } - if (this.isInWater() && !isLeaping) { - Vec3 mov = this.getDeltaMovement(); - double push = this.isUnderWater() ? 0.07D : 0.015D; - double cappedY = this.isUnderWater() ? 0.3D : 0.05D; - this.setDeltaMovement(mov.x, Math.min(mov.y + push, cappedY), mov.z); - } - if (landAnimTicks > 0) { landAnimTicks--; } @@ -342,17 +343,57 @@ public class DorrieEntity extends Animal implements GeoEntity { } } + @Override + public void baseTick() { + super.baseTick(); + if (this.isInWater() || this.isInLava()) { + this.setAirSupply(this.getMaxAirSupply()); + } + } + + @Override + public void travel(Vec3 travelVector) { + if (this.getControllingPassenger() instanceof Player rider && this.isVehicle()) { + this.setYRot(rider.getYRot()); + this.yRotO = this.getYRot(); + this.yBodyRot = this.getYRot(); + this.yHeadRot = this.getYRot(); + + Vec3 riddenInput = this.getRiddenInput(rider, travelVector); + this.setSpeed(this.getRiddenSpeed(rider)); + + if (this.isInWater() || this.isInLava()) { + this.moveRelative(this.getSpeed(), new Vec3(riddenInput.x, 0.0D, riddenInput.z)); + Vec3 motion = this.getDeltaMovement(); + double vertical = this.isLeaping ? 0.0D : riddenInput.y * 0.09D; + this.setDeltaMovement( + motion.x * 0.92D, + motion.y * 0.90D + vertical, + motion.z * 0.92D + ); + this.move(net.minecraft.world.entity.MoverType.SELF, this.getDeltaMovement()); + return; + } + + this.moveRelative(this.getSpeed(), new Vec3(riddenInput.x, 0.0D, riddenInput.z)); + this.move(net.minecraft.world.entity.MoverType.SELF, this.getDeltaMovement()); + return; + } + + super.travel(travelVector); + } + public void releaseJump() { if (!this.level().isClientSide && isCharging) { float power = chargeTicks / (float) MAX_CHARGE_TICKS; if (power > 0.05F) { Vec3 look = this.getLookAngle(); Vec3 current = this.getDeltaMovement(); - double forwardAdd = power * 0.5D; - double vertical = 0.55D + power * 0.9D; + double forwardAdd = 0.18D + power * 0.42D; + double vertical = 0.28D + power * 0.62D; this.setDeltaMovement( current.x + look.x * forwardAdd, - vertical, + current.y + vertical, current.z + look.z * forwardAdd ); this.hasImpulse = true; @@ -517,6 +558,7 @@ public class DorrieEntity extends Animal implements GeoEntity { private boolean canUseQuirkAnimation() { return this.isInWater() + && !this.isUnderWater() && this.getControllingPassenger() == null && !this.isLeaping && this.landAnimTicks <= 0 @@ -524,6 +566,72 @@ public class DorrieEntity extends Animal implements GeoEntity { && !this.isMovingForAnimation(null); } + @Nullable + private Vec3 findWaterSurfaceTarget(double radius, int minYDelta, int maxYDelta) { + int baseY = Mth.floor(this.getY()); + for (int attempt = 0; attempt < 12; attempt++) { + double offsetX = (this.random.nextDouble() - 0.5D) * radius * 2.0D; + double offsetZ = (this.random.nextDouble() - 0.5D) * radius * 2.0D; + int x = Mth.floor(this.getX() + offsetX); + int z = Mth.floor(this.getZ() + offsetZ); + Vec3 target = this.findWaterSurfaceTarget(x, z, baseY + minYDelta, baseY + maxYDelta); + if (target != null) { + return target; + } + } + return this.findWaterSurfaceTarget(Mth.floor(this.getX()), Mth.floor(this.getZ()), + baseY + minYDelta, baseY + maxYDelta); + } + + @Nullable + private Vec3 findWaterSurfaceTarget(int x, int z, int minY, int maxY) { + int top = Math.min(maxY, this.level().getMaxBuildHeight() - 2); + int bottom = Math.max(minY, this.level().getMinBuildHeight() + 1); + for (int y = top; y >= bottom; y--) { + BlockPos pos = BlockPos.containing(x, y, z); + if (!this.isWaterAt(pos) || this.isWaterAt(pos.above())) { + continue; + } + return new Vec3(x + 0.5D, y + 0.85D, z + 0.5D); + } + return null; + } + + @Nullable + private Vec3 findSubmergedTarget(double radius, int minYDelta, int maxYDelta) { + int baseY = Mth.floor(this.getY()); + for (int attempt = 0; attempt < 16; attempt++) { + double offsetX = (this.random.nextDouble() - 0.5D) * radius * 2.0D; + double offsetZ = (this.random.nextDouble() - 0.5D) * radius * 2.0D; + int x = Mth.floor(this.getX() + offsetX); + int z = Mth.floor(this.getZ() + offsetZ); + Vec3 target = this.findSubmergedTarget(x, z, baseY + minYDelta, baseY + maxYDelta); + if (target != null) { + return target; + } + } + return this.findSubmergedTarget(Mth.floor(this.getX()), Mth.floor(this.getZ()), + baseY + minYDelta, baseY + maxYDelta); + } + + @Nullable + private Vec3 findSubmergedTarget(int x, int z, int minY, int maxY) { + int top = Math.min(maxY, this.level().getMaxBuildHeight() - 2); + int bottom = Math.max(minY, this.level().getMinBuildHeight() + 1); + for (int y = top; y >= bottom; y--) { + BlockPos pos = BlockPos.containing(x, y, z); + if (!this.isWaterAt(pos) || !this.isWaterAt(pos.below())) { + continue; + } + return new Vec3(x + 0.5D, y + 0.3D, z + 0.5D); + } + return null; + } + + private boolean isWaterAt(BlockPos pos) { + return this.level().getFluidState(pos).is(FluidTags.WATER); + } + private boolean isMovingForAnimation(@Nullable AnimationState state) { if (state != null && state.isMoving()) { return true; @@ -535,6 +643,147 @@ public class DorrieEntity extends Animal implements GeoEntity { || this.getNavigation().isInProgress(); } + private class DolphinSwimGoal extends Goal { + private static final int COOLDOWN_MIN_TICKS = 120; + private static final int COOLDOWN_MAX_TICKS = 240; + private static final int DIVE_MIN_TICKS = 50; + private static final int DIVE_MAX_TICKS = 110; + private static final int ROAM_MIN_TICKS = 70; + private static final int ROAM_MAX_TICKS = 140; + private static final int TARGET_REFRESH_TICKS = 20; + private static final double AQUATIC_SPEED = 1.15D; + private static final double SEARCH_RADIUS = 12.0D; + + @Nullable + private Vec3 targetPos; + private int phaseTicks; + private int targetRefreshTicks; + private int cooldownTicks; + private Phase phase = Phase.ROAM; + + DolphinSwimGoal() { + this.setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK)); + } + + @Override + public boolean canUse() { + if (DorrieEntity.this.level().isClientSide + || DorrieEntity.this.isVehicle() + || DorrieEntity.this.getControllingPassenger() != null + || DorrieEntity.this.isCharging + || DorrieEntity.this.isLeaping + || DorrieEntity.this.landAnimTicks > 0 + || DorrieEntity.this.getTarget() != null) { + return false; + } + if (!DorrieEntity.this.isInWater()) { + return false; + } + if (this.cooldownTicks > 0) { + this.cooldownTicks--; + return false; + } + if (DorrieEntity.this.random.nextInt(6) != 0) { + return false; + } + this.targetPos = DorrieEntity.this.isUnderWater() + ? DorrieEntity.this.findSubmergedTarget(SEARCH_RADIUS, -5, 2) + : DorrieEntity.this.findSubmergedTarget(SEARCH_RADIUS, -5, 1); + return this.targetPos != null; + } + + @Override + public boolean canContinueToUse() { + return this.targetPos != null + && !DorrieEntity.this.isVehicle() + && DorrieEntity.this.getControllingPassenger() == null + && DorrieEntity.this.isAlive() + && DorrieEntity.this.isInWater(); + } + + @Override + public void start() { + this.phase = DorrieEntity.this.isUnderWater() ? Phase.ROAM : Phase.DIVE; + this.phaseTicks = this.phase == Phase.DIVE + ? DorrieEntity.this.random.nextInt(DIVE_MAX_TICKS - DIVE_MIN_TICKS + 1) + DIVE_MIN_TICKS + : DorrieEntity.this.random.nextInt(ROAM_MAX_TICKS - ROAM_MIN_TICKS + 1) + ROAM_MIN_TICKS; + this.targetRefreshTicks = 0; + if (this.targetPos == null) { + this.targetPos = this.pickTargetForPhase(); + } + if (this.targetPos == null) { + this.stop(); + } + } + + @Override + public void stop() { + this.targetPos = null; + this.phaseTicks = 0; + this.targetRefreshTicks = 0; + DorrieEntity.this.getNavigation().stop(); + this.cooldownTicks = DorrieEntity.this.random.nextInt(COOLDOWN_MAX_TICKS - COOLDOWN_MIN_TICKS + 1) + COOLDOWN_MIN_TICKS; + } + + @Override + public void tick() { + if (this.targetPos == null) { + this.stop(); + return; + } + + if (this.phaseTicks > 0) { + this.phaseTicks--; + } + if (this.targetRefreshTicks > 0) { + this.targetRefreshTicks--; + } + + if (this.phase == Phase.DIVE && this.phaseTicks <= 0) { + this.phase = Phase.ROAM; + this.phaseTicks = DorrieEntity.this.random.nextInt(ROAM_MAX_TICKS - ROAM_MIN_TICKS + 1) + ROAM_MIN_TICKS; + this.targetPos = this.pickTargetForPhase(); + } else if (this.phase == Phase.ROAM && this.phaseTicks <= 0) { + this.phase = Phase.SURFACE; + this.phaseTicks = DorrieEntity.this.random.nextInt(DIVE_MAX_TICKS - DIVE_MIN_TICKS + 1) + DIVE_MIN_TICKS; + this.targetPos = DorrieEntity.this.findWaterSurfaceTarget(SEARCH_RADIUS, -1, 4); + } else if (this.phase == Phase.SURFACE && this.phaseTicks <= 0 && this.isCloseToTarget()) { + this.stop(); + return; + } + + if (this.targetPos == null || this.targetRefreshTicks <= 0 || this.isCloseToTarget()) { + this.targetPos = this.pickTargetForPhase(); + this.targetRefreshTicks = TARGET_REFRESH_TICKS; + } + + if (this.targetPos == null) { + this.stop(); + return; + } + + DorrieEntity.this.getLookControl().setLookAt(this.targetPos.x, this.targetPos.y, this.targetPos.z, 25.0F, 20.0F); + DorrieEntity.this.getNavigation().moveTo(this.targetPos.x, this.targetPos.y, this.targetPos.z, AQUATIC_SPEED); + } + + @Nullable + private Vec3 pickTargetForPhase() { + return this.phase == Phase.SURFACE + ? DorrieEntity.this.findWaterSurfaceTarget(SEARCH_RADIUS, -1, 4) + : DorrieEntity.this.findSubmergedTarget(SEARCH_RADIUS, -5, 2); + } + + private boolean isCloseToTarget() { + return this.targetPos != null && DorrieEntity.this.distanceToSqr(this.targetPos) < 4.0D; + } + + private enum Phase { + DIVE, + ROAM, + SURFACE + } + } + private static class HuntCheepGoal extends Goal { private static final int COOLDOWN_TICKS = 600; private static final double HUNT_RANGE = 16.0D; diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/EmperorScorpionEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/EmperorScorpionEntity.java index 7f815a30..421c14de 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/entity/EmperorScorpionEntity.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/EmperorScorpionEntity.java @@ -108,6 +108,15 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity { .add(Attributes.FOLLOW_RANGE, AntarchySettings.emperorScorpionFollowRange()); } + @Override + public boolean fireImmune() { + return true; + } + + @Override + public void lavaHurt() { + } + public static boolean canSpawn(EntityType entityType, ServerLevelAccessor level, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { if (spawnReason == MobSpawnType.SPAWN_EGG diff --git a/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalManager.java b/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalManager.java index 04cf7aab..9fc76074 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalManager.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalManager.java @@ -11,6 +11,7 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; @@ -34,10 +35,19 @@ public final class PermanentPortalManager { return; } - shape.fill(serverLevel); - Vec3 center = shape.center(); - serverLevel.playSound(null, center.x, center.y, center.z, SoundEvents.END_PORTAL_SPAWN, SoundSource.BLOCKS, 0.9F, 0.9F); - spawnActivationParticles(serverLevel, type, center); + activatePortal(serverLevel, type, shape, SoundEvents.END_PORTAL_SPAWN, 0.9F, 0.9F); + } + + public static boolean tryIgnitePortal(Level level, BlockPos triggerPos, PermanentPortalType type) { + PermanentPortalShape shape = PermanentPortalShape.findInactiveNear(level, triggerPos, type); + if (shape == null) { + return false; + } + + if (level instanceof ServerLevel serverLevel) { + activatePortal(serverLevel, type, shape, SoundEvents.FLINTANDSTEEL_USE, 0.9F, 1.0F); + } + return true; } public static void handleEntityInsidePortal(Entity entity, PermanentPortalType type) { @@ -67,7 +77,7 @@ public final class PermanentPortalManager { WARMUPS.remove(entity.getUUID()); PermanentPortalTeleporter.teleport(entity, type); if (entity.level() instanceof ServerLevel currentLevel) { - currentLevel.playSound(null, entity.getX(), entity.getY(), entity.getZ(), SoundEvents.ENDERMAN_TELEPORT, SoundSource.PLAYERS, 0.8F, 1.0F); + currentLevel.playSound(null, entity.getX(), entity.getY(), entity.getZ(), SoundEvents.PORTAL_TRAVEL, SoundSource.PLAYERS, 0.8F, 1.0F); } } @@ -121,6 +131,13 @@ public final class PermanentPortalManager { } } + private static void activatePortal(ServerLevel level, PermanentPortalType type, PermanentPortalShape shape, net.minecraft.sounds.SoundEvent sound, float volume, float pitch) { + shape.fill(level); + Vec3 center = shape.center(); + level.playSound(null, center.x, center.y, center.z, sound, SoundSource.BLOCKS, volume, pitch); + spawnActivationParticles(level, type, center); + } + private static final class PortalWarmup { private PermanentPortalType type; private long lastSeenTick; diff --git a/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalShape.java b/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalShape.java index 879dc473..9d84f0fa 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalShape.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalShape.java @@ -8,6 +8,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.TagKey; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.phys.AABB; @@ -18,6 +19,7 @@ public final class PermanentPortalShape { public static final int MIN_WIDTH = 2; public static final int MIN_HEIGHT = 3; public static final int MAX_SIZE = 21; + public static final int ACTIVE_SEARCH_RADIUS = 8; private final PermanentPortalType type; private final Direction.Axis axis; @@ -38,12 +40,52 @@ public final class PermanentPortalShape { return find(level, interiorPos, type, axis, state -> state.isAir()); } + @Nullable + public static PermanentPortalShape findInactiveNear(BlockGetter level, BlockPos center, PermanentPortalType type) { + for (int x = center.getX() - 2; x <= center.getX() + 2; x++) { + for (int y = center.getY() - 2; y <= center.getY() + 2; y++) { + for (int z = center.getZ() - 2; z <= center.getZ() + 2; z++) { + BlockPos candidate = new BlockPos(x, y, z); + PermanentPortalShape xShape = findInactive(level, candidate, type, Direction.Axis.X); + if (xShape != null) { + return xShape; + } + PermanentPortalShape zShape = findInactive(level, candidate, type, Direction.Axis.Z); + if (zShape != null) { + return zShape; + } + } + } + } + return null; + } + @Nullable public static PermanentPortalShape findActive(BlockGetter level, BlockPos interiorPos, PermanentPortalType type, Direction.Axis axis) { Block portalBlock = type.portalBlock(); return find(level, interiorPos, type, axis, state -> state.is(portalBlock)); } + @Nullable + public static PermanentPortalShape findActiveNear(BlockGetter level, BlockPos center, PermanentPortalType type) { + for (int x = center.getX() - ACTIVE_SEARCH_RADIUS; x <= center.getX() + ACTIVE_SEARCH_RADIUS; x++) { + for (int y = center.getY() - ACTIVE_SEARCH_RADIUS; y <= center.getY() + ACTIVE_SEARCH_RADIUS; y++) { + for (int z = center.getZ() - ACTIVE_SEARCH_RADIUS; z <= center.getZ() + ACTIVE_SEARCH_RADIUS; z++) { + BlockPos candidate = new BlockPos(x, y, z); + PermanentPortalShape xShape = findActive(level, candidate, type, Direction.Axis.X); + if (xShape != null) { + return xShape; + } + PermanentPortalShape zShape = findActive(level, candidate, type, Direction.Axis.Z); + if (zShape != null) { + return zShape; + } + } + } + } + return null; + } + @Nullable private static PermanentPortalShape find( BlockGetter level, @@ -159,6 +201,50 @@ public final class PermanentPortalShape { this.forEachInterior(pos -> level.setBlock(pos, portalState, Block.UPDATE_ALL)); } + @Nullable + public static PermanentPortalShape create(ServerLevel level, BlockPos bottomLeft, PermanentPortalType type, Direction.Axis axis) { + if (axis == Direction.Axis.Y || !canCreate(level, bottomLeft, type, axis)) { + return null; + } + + BlockState frameState = type.platformBlock().defaultBlockState(); + BlockState portalState = type.portalBlock().defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_AXIS, axis); + Direction widthDirection = axis == Direction.Axis.X ? Direction.EAST : Direction.SOUTH; + + for (int y = -1; y <= 3; y++) { + for (int x = -1; x <= 2; x++) { + BlockPos pos = bottomLeft.relative(widthDirection, x).above(y); + if (x == -1 || x == 2 || y == -1 || y == 3) { + level.setBlock(pos, frameState, Block.UPDATE_ALL); + } else { + level.setBlock(pos, portalState, Block.UPDATE_ALL); + } + } + } + + return new PermanentPortalShape(type, axis, bottomLeft.immutable(), 2, 3); + } + + private static boolean canCreate(BlockGetter level, BlockPos bottomLeft, PermanentPortalType type, Direction.Axis axis) { + Direction widthDirection = axis == Direction.Axis.X ? Direction.EAST : Direction.SOUTH; + Block frameBlock = type.platformBlock(); + for (int y = -1; y <= 3; y++) { + for (int x = -1; x <= 2; x++) { + BlockPos pos = bottomLeft.relative(widthDirection, x).above(y); + BlockState state = level.getBlockState(pos); + boolean frameSpot = x == -1 || x == 2 || y == -1 || y == 3; + if (frameSpot) { + if (!state.isAir() && !state.is(frameBlock) && !state.canBeReplaced()) { + return false; + } + } else if (!state.isAir() && !state.canBeReplaced() && !state.is(Blocks.AIR)) { + return false; + } + } + } + return true; + } + public boolean contains(BlockPos pos) { if (pos.getY() < this.bottomLeft.getY() || pos.getY() >= this.bottomLeft.getY() + this.height) { return false; diff --git a/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java b/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java index 0eabe59c..bfd18721 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java @@ -1,14 +1,17 @@ package com.craisinlord.antarchy.content.portal; +import com.craisinlord.antarchy.config.AntarchySettings; import java.util.LinkedHashSet; import java.util.Set; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.vehicle.DismountHelper; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.Heightmap; @@ -28,18 +31,23 @@ public final class PermanentPortalTeleporter { return; } - ServerLevel destination = resolveDestination(sourceLevel, type); - if (destination == null) { - return; - } - - Vec3 arrival = findArrivalPosition(entity, destination, entity.blockPosition(), type.platformBlock().defaultBlockState()); - Entity movedEntity = moveEntity(entity, destination, arrival); + DimensionTransition transition = createTransition(sourceLevel, entity, entity.blockPosition(), type); + Entity movedEntity = moveEntity(entity, transition); if (movedEntity != null) { movedEntity.setPortalCooldown(); } } + public static DimensionTransition createTransition(ServerLevel sourceLevel, Entity entity, BlockPos portalPos, PermanentPortalType type) { + ServerLevel destination = resolveDestination(sourceLevel, type); + if (destination == null) { + return new DimensionTransition(sourceLevel, entity, DimensionTransition.DO_NOTHING); + } + + Vec3 arrival = findArrivalPosition(entity, destination, portalPos, type); + return new DimensionTransition(destination, arrival, Vec3.ZERO, entity.getYRot(), entity.getXRot(), DimensionTransition.PLAY_PORTAL_SOUND); + } + @Nullable private static ServerLevel resolveDestination(ServerLevel sourceLevel, PermanentPortalType type) { if (sourceLevel.dimension() == type.primaryDimension()) { @@ -48,13 +56,31 @@ public final class PermanentPortalTeleporter { return sourceLevel.getServer().getLevel(type.primaryDimension()); } - private static Vec3 findArrivalPosition(Entity entity, ServerLevel destination, BlockPos preferredPos, BlockState platformState) { + private static Vec3 findArrivalPosition(Entity entity, ServerLevel destination, BlockPos preferredPos, PermanentPortalType type) { + PermanentPortalShape active = PermanentPortalShape.findActiveNear(destination, preferredPos, type); + if (active != null) { + return active.center(); + } + Vec3 safe = findSafeArrivalPosition(entity, destination, preferredPos); - return safe != null ? safe : createFallbackPlatform(destination, preferredPos, platformState); + if (safe != null) { + PermanentPortalShape created = createReturnPortal(destination, safe, type); + if (created != null) { + return created.center(); + } + return safe; + } + + return createFallbackPlatform(destination, preferredPos, type.platformBlock().defaultBlockState()); } @Nullable private static Vec3 findSafeArrivalPosition(Entity entity, ServerLevel destination, BlockPos preferredPos) { + int[] yRange = getDimensionYRange(destination); + if (yRange != null) { + return findSafeArrivalPositionInYRange(entity, destination, preferredPos, yRange[0], yRange[1]); + } + Set candidates = new LinkedHashSet<>(); addCandidate(candidates, preferredPos); @@ -88,6 +114,29 @@ public final class PermanentPortalTeleporter { return null; } + @Nullable + private static Vec3 findSafeArrivalPositionInYRange(Entity entity, ServerLevel destination, BlockPos preferredPos, int minY, int maxY) { + for (int radius = 0; radius <= SEARCH_RADIUS; radius++) { + for (int xOff = -radius; xOff <= radius; xOff++) { + for (int zOff = -radius; zOff <= radius; zOff++) { + if (radius > 0 && Math.abs(xOff) != radius && Math.abs(zOff) != radius) { + continue; + } + + int x = preferredPos.getX() + xOff; + int z = preferredPos.getZ() + zOff; + for (int y = maxY; y >= minY + 1; y--) { + Vec3 safePos = tryFindSafePosition(entity, destination, new BlockPos(x, y, z)); + if (safePos != null && safePos.y >= minY && safePos.y <= maxY) { + return safePos; + } + } + } + } + } + return null; + } + private static void addCandidate(Set candidates, @Nullable BlockPos pos) { if (pos == null) { return; @@ -103,13 +152,13 @@ public final class PermanentPortalTeleporter { @Nullable private static Vec3 tryFindSafePosition(Entity entity, ServerLevel destination, BlockPos candidate) { Vec3 safe = DismountHelper.findSafeDismountLocation(entity.getType(), destination, candidate, true); - if (safe != null) { + if (safe != null && isValidArrivalPosition(destination, safe)) { return safe; } for (Direction direction : Direction.Plane.HORIZONTAL) { safe = DismountHelper.findSafeDismountLocation(entity.getType(), destination, candidate.relative(direction), true); - if (safe != null) { + if (safe != null && isValidArrivalPosition(destination, safe)) { return safe; } } @@ -134,7 +183,60 @@ public final class PermanentPortalTeleporter { } @Nullable - private static Entity moveEntity(Entity entity, ServerLevel destination, Vec3 destinationPos) { + private static PermanentPortalShape createReturnPortal(ServerLevel destination, Vec3 safePos, PermanentPortalType type) { + BlockPos preferred = BlockPos.containing(safePos); + int minY = destination.getMinBuildHeight() + 2; + int maxY = destination.getMaxBuildHeight() - 4; + int clampedY = Mth.clamp(preferred.getY(), minY, maxY); + + for (int radius = 0; radius <= 4; radius++) { + for (int xOff = -radius; xOff <= radius; xOff++) { + for (int zOff = -radius; zOff <= radius; zOff++) { + if (radius > 0 && Math.abs(xOff) != radius && Math.abs(zOff) != radius) { + continue; + } + + BlockPos anchor = new BlockPos(preferred.getX() + xOff, clampedY, preferred.getZ() + zOff); + PermanentPortalShape xShape = PermanentPortalShape.create(destination, anchor, type, Direction.Axis.X); + if (xShape != null) { + return xShape; + } + PermanentPortalShape zShape = PermanentPortalShape.create(destination, anchor, type, Direction.Axis.Z); + if (zShape != null) { + return zShape; + } + } + } + } + + return null; + } + + @Nullable + private static int[] getDimensionYRange(ServerLevel destination) { + ResourceKey dim = destination.dimension(); + if (dim == AntarchySettings.termiteDestinationDimension()) { + return new int[]{100, 200}; + } + if (dim == AntarchySettings.brownAntDestinationDimension()) { + return new int[]{75, 120}; + } + return null; + } + + private static boolean isValidArrivalPosition(ServerLevel destination, Vec3 safePos) { + BlockPos standPos = BlockPos.containing(safePos); + if (destination.dimension() == AntarchySettings.termiteDestinationDimension() + || destination.dimension() == AntarchySettings.redAntDestinationDimension()) { + return !destination.getBlockState(standPos.below()).is(net.minecraft.world.level.block.Blocks.BEDROCK); + } + return true; + } + + @Nullable + private static Entity moveEntity(Entity entity, DimensionTransition transition) { + ServerLevel destination = transition.newLevel(); + Vec3 destinationPos = transition.pos(); if (entity instanceof ServerPlayer player) { player.teleportTo(destination, destinationPos.x, destinationPos.y, destinationPos.z, player.getYRot(), player.getXRot()); return player; @@ -145,6 +247,6 @@ public final class PermanentPortalTeleporter { return entity; } - return entity.changeDimension(new DimensionTransition(destination, destinationPos, Vec3.ZERO, entity.getYRot(), entity.getXRot(), DimensionTransition.DO_NOTHING)); + return entity.changeDimension(transition); } } diff --git a/common/src/main/java/com/craisinlord/antarchy/mixins/FlintAndSteelPortalIgnitionMixin.java b/common/src/main/java/com/craisinlord/antarchy/mixins/FlintAndSteelPortalIgnitionMixin.java new file mode 100644 index 00000000..58bb411b --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/mixins/FlintAndSteelPortalIgnitionMixin.java @@ -0,0 +1,53 @@ +package com.craisinlord.antarchy.mixins; + +import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.portal.PermanentPortalManager; +import com.craisinlord.antarchy.content.portal.PermanentPortalType; +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.FlintAndSteelItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(FlintAndSteelItem.class) +public abstract class FlintAndSteelPortalIgnitionMixin { + @Inject(method = "useOn", at = @At("HEAD"), cancellable = true) + private void antarchy$ignitePermanentPortal(UseOnContext context, CallbackInfoReturnable cir) { + if (!AntarchySettings.permanentPortalsEnabled() || !AntarchySettings.permanentPortalsFlintAndSteelEnabled()) { + return; + } + + Level level = context.getLevel(); + BlockPos clickedPos = context.getClickedPos(); + BlockState clickedState = level.getBlockState(clickedPos); + + for (PermanentPortalType type : PermanentPortalType.values()) { + if (!type.isEnabled() || !clickedState.is(type.frameTag())) { + continue; + } + if (!PermanentPortalManager.tryIgnitePortal(level, clickedPos, type)) { + continue; + } + + if (!level.isClientSide() && context.getPlayer() != null) { + ItemStack stack = context.getItemInHand(); + stack.hurtAndBreak(1, context.getPlayer(), handToSlot(context.getHand())); + } + + cir.setReturnValue(InteractionResult.sidedSuccess(level.isClientSide())); + return; + } + } + + private static EquipmentSlot handToSlot(InteractionHand hand) { + return hand == InteractionHand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND; + } +} diff --git a/common/src/main/resources/antarchy-common.mixins.json b/common/src/main/resources/antarchy-common.mixins.json index f9a8a757..2a281ed4 100644 --- a/common/src/main/resources/antarchy-common.mixins.json +++ b/common/src/main/resources/antarchy-common.mixins.json @@ -13,6 +13,7 @@ "DreamSandLowGravityMixin", "FireVisualBaseFireBlockMixin", "FireVisualEntityMixin", + "FlintAndSteelPortalIgnitionMixin", "GlowVinesUnderLeavesMixin", "NightmareSwordDamageMixin", "ServerPlayerGameModeMixin", diff --git a/common/src/main/resources/assets/antarchy/geo/dorrie.geo.json b/common/src/main/resources/assets/antarchy/geo/dorrie.geo.json index 8e16dbbb..074a5581 100644 --- a/common/src/main/resources/assets/antarchy/geo/dorrie.geo.json +++ b/common/src/main/resources/assets/antarchy/geo/dorrie.geo.json @@ -5,7 +5,7 @@ "description": { "identifier": "geometry.unknown", "texture_width": 128, - "texture_height": 128, + "texture_height": 256, "visible_bounds_width": 7, "visible_bounds_height": 4.5, "visible_bounds_offset": [0, 1.75, 0] diff --git a/common/src/main/resources/assets/antarchy/textures/entity/dorrie.png b/common/src/main/resources/assets/antarchy/textures/entity/dorrie.png index e47505920fe3b23dd606d8749bbd2072c97e8d53..98b9b53cd012d77bff2a126a7a95532d4070831c 100644 GIT binary patch literal 9723 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 literal 8734 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 diff --git a/common/src/main/resources/assets/antarchy/textures/entity/dorrie_saddle.png b/common/src/main/resources/assets/antarchy/textures/entity/dorrie_saddle.png index b9f008158eb729c55c83cbd6d1bf92ab290e29f3..8df880c91e9eb944bd0d2a499c63d843da54164f 100644 GIT binary patch delta 11252 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 delta 11283 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 diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyConfigModuleFabric.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyConfigModuleFabric.java index 07550736..be11f333 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyConfigModuleFabric.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyConfigModuleFabric.java @@ -170,6 +170,7 @@ public final class AntarchyConfigModuleFabric { return name.equals("disableInfinityBookPortalCreation") || name.equals("rainbowAntsLeadToInfinityDimensions") || name.equals("permanentPortalsEnabled") + || name.equals("permanentPortalsFlintAndSteelEnabled") || name.equals("elythiaPortalEnabled") || name.equals("thoraxisPortalEnabled") || name.equals("cavarynPortalEnabled") diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyConfigModuleNeoforge.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyConfigModuleNeoforge.java index f13309c6..c2e356a0 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyConfigModuleNeoforge.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyConfigModuleNeoforge.java @@ -334,6 +334,7 @@ public final class AntarchyConfigModuleNeoforge { AntarchySettings.setDiamondMinecartMobDamageEnabled(AntarchyMiscConfig.diamondMinecartMobDamageEnabled()); AntarchySettings.setDiamondMinecartMaxMobDamage(AntarchyMiscConfig.diamondMinecartMaxMobDamage()); AntarchySettings.setPermanentPortalsEnabled(AntarchyMiscConfig.permanentPortalsEnabled()); + AntarchySettings.setPermanentPortalsFlintAndSteelEnabled(AntarchyMiscConfig.permanentPortalsFlintAndSteelEnabled()); AntarchySettings.setElythiaPortalEnabled(AntarchyMiscConfig.elythiaPortalEnabled()); AntarchySettings.setThoraxisPortalEnabled(AntarchyMiscConfig.thoraxisPortalEnabled()); AntarchySettings.setCavarynPortalEnabled(AntarchyMiscConfig.cavarynPortalEnabled()); diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMiscConfig.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMiscConfig.java index ad704183..04369feb 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMiscConfig.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMiscConfig.java @@ -27,6 +27,7 @@ public final class AntarchyMiscConfig { // Permanent portals private static final ModConfigSpec.BooleanValue PERMANENT_PORTALS_ENABLED; + private static final ModConfigSpec.BooleanValue PERMANENT_PORTALS_FLINT_AND_STEEL_ENABLED; private static final ModConfigSpec.BooleanValue ELYTHIA_PORTAL_ENABLED; private static final ModConfigSpec.BooleanValue THORAXIS_PORTAL_ENABLED; private static final ModConfigSpec.BooleanValue CAVARYN_PORTAL_ENABLED; @@ -110,6 +111,7 @@ public final class AntarchyMiscConfig { b.push("permanentPortals"); PERMANENT_PORTALS_ENABLED = b.comment("Master toggle for sacrifice-activated permanent portals.").define("permanentPortalsEnabled", true); + PERMANENT_PORTALS_FLINT_AND_STEEL_ENABLED = b.comment("Whether flint and steel can ignite permanent portal frames.").define("permanentPortalsFlintAndSteelEnabled", false); ELYTHIA_PORTAL_ENABLED = b.comment("Whether mossy ouranwood wood portals to Elythia can activate and function.").define("elythiaPortalEnabled", true); THORAXIS_PORTAL_ENABLED = b.comment("Whether Nyxite portals to Thoraxis can activate and function.").define("thoraxisPortalEnabled", true); CAVARYN_PORTAL_ENABLED = b.comment("Whether Myrmite portals to Cavaryn can activate and function.").define("cavarynPortalEnabled", true); @@ -167,6 +169,7 @@ public final class AntarchyMiscConfig { static boolean disableInfinityBookPortalCreation() { return DISABLE_INFINITY_BOOK_PORTAL_CREATION.get(); } static boolean rainbowAntsLeadToInfinityDimensions() { return RAINBOW_ANTS_LEAD_TO_INFINITY_DIMENSIONS.get(); } public static boolean permanentPortalsEnabled() { return PERMANENT_PORTALS_ENABLED.get(); } + public static boolean permanentPortalsFlintAndSteelEnabled() { return PERMANENT_PORTALS_FLINT_AND_STEEL_ENABLED.get(); } public static boolean elythiaPortalEnabled() { return ELYTHIA_PORTAL_ENABLED.get(); } public static boolean thoraxisPortalEnabled() { return THORAXIS_PORTAL_ENABLED.get(); } public static boolean cavarynPortalEnabled() { return CAVARYN_PORTAL_ENABLED.get(); }