diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java index df9e172e..664bafbc 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java @@ -1368,6 +1368,8 @@ public final class AntarchySettings { public static void setKrakensGraspAttackSpeed(double value) { krakensGraspAttackSpeed = value; } public static void setKrakensGraspThrownDamage(double value) { krakensGraspThrownDamage = value; } public static void setKrakensGraspLightningDamage(double value) { krakensGraspLightningDamage = value; } + + public static double krakensGraspLightningDamage() { return krakensGraspLightningDamage; } public static void setKrakensGraspInnateLoyalty(boolean value) { krakensGraspInnateLoyalty = value; } public static void setKrakensGraspInnateLoyaltyLevel(int value) { krakensGraspInnateLoyaltyLevel = value; } public static void setKrakensGraspTentacleDurationTicks(int value) { krakensGraspTentacleDurationTicks = value; } diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ReverieEntity.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ReverieEntity.java index ae691805..0c7c4abb 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ReverieEntity.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ReverieEntity.java @@ -73,6 +73,7 @@ import software.bernie.geckolib.core.animation.RawAnimation; import software.bernie.geckolib.util.GeckoLibUtil; public class ReverieEntity extends PathfinderMob implements FlyingAnimal, GeoEntity { + private static final int DAMAGE_REACTION_DURATION_TICKS = 40; private static final EntityDataAccessor MOOD = SynchedEntityData.defineId(ReverieEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor ANIMATION_STATE = @@ -309,7 +310,7 @@ public class ReverieEntity extends PathfinderMob implements FlyingAnimal, GeoEnt this.releaseFocus(); this.clearNoticePlayer(); this.ambientTarget = null; - this.damageReactionTicks = 0; + this.damageReactionTicks = DAMAGE_REACTION_DURATION_TICKS; this.inversionReactionTicks = 0; this.transitionToMood(Mood.WHITE); } diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java index 33db0795..468a74a3 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java @@ -15,6 +15,8 @@ import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.goal.FloatGoal; +import net.minecraft.world.entity.ai.goal.BreedGoal; +import net.minecraft.world.entity.ai.goal.TemptGoal; import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; import net.minecraft.world.entity.ai.goal.PanicGoal; import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal; @@ -23,6 +25,8 @@ import net.minecraft.world.entity.animal.Animal; import net.minecraft.world.entity.player.Player; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerLevelAccessor; import org.jetbrains.annotations.Nullable; @@ -76,9 +80,11 @@ public class StinkBugEntity extends Animal implements GeoEntity { protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); this.goalSelector.addGoal(1, new PanicGoal(this, 1.4D)); - this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 0.9D)); - this.goalSelector.addGoal(3, new LookAtPlayerGoal(this, Player.class, 6.0F)); - this.goalSelector.addGoal(4, new RandomLookAroundGoal(this)); + this.goalSelector.addGoal(2, new TemptGoal(this, 1.0D, Ingredient.of(Items.ROTTEN_FLESH), false)); + this.goalSelector.addGoal(3, new BreedGoal(this, 0.9D)); + this.goalSelector.addGoal(4, new WaterAvoidingRandomStrollGoal(this, 0.9D)); + this.goalSelector.addGoal(5, new LookAtPlayerGoal(this, Player.class, 6.0F)); + this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); } @Override @@ -108,7 +114,7 @@ public class StinkBugEntity extends Animal implements GeoEntity { @Override public boolean isFood(ItemStack stack) { - return false; + return stack.is(Items.ROTTEN_FLESH); } @Override diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakenEntity.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakenEntity.java index 79e63795..b91ce43c 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakenEntity.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakenEntity.java @@ -1026,7 +1026,8 @@ public class KrakenEntity extends Monster implements GeoEntity, MultipartEntityO for (int i = 0; i < strikeBolts; i++) { this.spawnVisualLightning(serverLevel, this.getTargetStormStrikePos(target)); } - target.hurt(AntarchyDamageSources.krakenLightning(serverLevel, this), this.isPhaseTwo() ? 12.0F : 8.0F); + target.hurt(AntarchyDamageSources.krakenLightning(serverLevel, this), + this.isPhaseTwo() ? 12.0F : AntarchySettings.krakenLightningDamagePhaseOne()); } } else { this.lightningStrikeCooldown = this.isPhaseTwo() ? 30 : 60; diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java index afaaaff4..ee0f6b2e 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java @@ -91,12 +91,14 @@ public class KrakensGraspItem extends TridentItem { public static void strikeLightning(LivingEntity target, ServerLevel level) { strikeLightningAt(level, target.getX(), target.getY(), target.getZ()); + target.hurt(level.damageSources().lightningBolt(), (float) AntarchySettings.krakensGraspLightningDamage()); level.sendParticles(ParticleTypes.ELECTRIC_SPARK, target.getX(), target.getY(0.7D), target.getZ(), 10, 0.25D, 0.25D, 0.25D, 0.02D); } public static void strikeLightningAt(ServerLevel level, double x, double y, double z) { LightningBolt lightningBolt = new LightningBolt(net.minecraft.world.entity.EntityType.LIGHTNING_BOLT, level); lightningBolt.moveTo(x, y, z); + lightningBolt.setVisualOnly(true); level.addFreshEntity(lightningBolt); level.sendParticles(ParticleTypes.ELECTRIC_SPARK, x, y + 0.2D, z, 10, 0.25D, 0.25D, 0.25D, 0.02D); } diff --git a/common-1.20.1/src/main/resources/assets/antarchy/blockstates/dimensional_tear_marker.json b/common-1.20.1/src/main/resources/assets/antarchy/blockstates/dimensional_tear_marker.json new file mode 100644 index 00000000..f17f93e2 --- /dev/null +++ b/common-1.20.1/src/main/resources/assets/antarchy/blockstates/dimensional_tear_marker.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} diff --git a/common-1.20.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_base.json b/common-1.20.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_base.json new file mode 100644 index 00000000..f17f93e2 --- /dev/null +++ b/common-1.20.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_base.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} diff --git a/common-1.20.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_master.json b/common-1.20.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_master.json new file mode 100644 index 00000000..f17f93e2 --- /dev/null +++ b/common-1.20.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_master.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} diff --git a/common-1.20.1/src/main/resources/assets/antarchy/geo/fallen_king_crown.geo.json b/common-1.20.1/src/main/resources/assets/antarchy/geo/fallen_king_crown.geo.json index c8f22646..afa9b466 100644 --- a/common-1.20.1/src/main/resources/assets/antarchy/geo/fallen_king_crown.geo.json +++ b/common-1.20.1/src/main/resources/assets/antarchy/geo/fallen_king_crown.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -80,4 +80,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.20.1/src/main/resources/assets/antarchy/geo/krakens_grasp.geo.json b/common-1.20.1/src/main/resources/assets/antarchy/geo/krakens_grasp.geo.json index a8e4f668..b3df7394 100644 --- a/common-1.20.1/src/main/resources/assets/antarchy/geo/krakens_grasp.geo.json +++ b/common-1.20.1/src/main/resources/assets/antarchy/geo/krakens_grasp.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -199,4 +199,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.20.1/src/main/resources/assets/antarchy/geo/rpo_launcher.geo.json b/common-1.20.1/src/main/resources/assets/antarchy/geo/rpo_launcher.geo.json index 07451faf..794ca38d 100644 --- a/common-1.20.1/src/main/resources/assets/antarchy/geo/rpo_launcher.geo.json +++ b/common-1.20.1/src/main/resources/assets/antarchy/geo/rpo_launcher.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -284,4 +284,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.20.1/src/main/resources/assets/antarchy/geo/water_cannon.geo.json b/common-1.20.1/src/main/resources/assets/antarchy/geo/water_cannon.geo.json index 4240f801..6b844883 100644 --- a/common-1.20.1/src/main/resources/assets/antarchy/geo/water_cannon.geo.json +++ b/common-1.20.1/src/main/resources/assets/antarchy/geo/water_cannon.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -92,4 +92,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.20.1/src/main/resources/assets/antarchy/models/block/nadir_hanging_sign.json b/common-1.20.1/src/main/resources/assets/antarchy/models/block/nadir_hanging_sign.json index c101c4af..cc1d471b 100644 --- a/common-1.20.1/src/main/resources/assets/antarchy/models/block/nadir_hanging_sign.json +++ b/common-1.20.1/src/main/resources/assets/antarchy/models/block/nadir_hanging_sign.json @@ -1,5 +1,5 @@ { "textures": { - "particle": "antarchy:block/nadir/nadir_hanging" + "particle": "antarchy:block/nadir/nadir_planks" } } diff --git a/common-1.20.1/src/main/resources/assets/antarchy/models/block/nadir_wall_hanging_sign.json b/common-1.20.1/src/main/resources/assets/antarchy/models/block/nadir_wall_hanging_sign.json index c101c4af..cc1d471b 100644 --- a/common-1.20.1/src/main/resources/assets/antarchy/models/block/nadir_wall_hanging_sign.json +++ b/common-1.20.1/src/main/resources/assets/antarchy/models/block/nadir_wall_hanging_sign.json @@ -1,5 +1,5 @@ { "textures": { - "particle": "antarchy:block/nadir/nadir_hanging" + "particle": "antarchy:block/nadir/nadir_planks" } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java index 7bfe5623..d475667c 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java @@ -91,11 +91,11 @@ public final class AntarchySettings { private static double bigBerthaNoneModeDamageBonusPercent = 15.0D; private static double bigBerthaNightmareDamageBonusPercent = 30.0D; private static double potentNyxiteInvertedDurationSeconds = 60.0D; - private static boolean dimensionalTearsSpawnNaturally = false; + private static boolean dimensionalTearsSpawnNaturally = true; private static int dimensionalTearLifetimeTicks = 24000; private static int dimensionalTearInvertedDurationTicks = 2400; - private static int dimensionalTearEmergenceMinIntervalTicks = 2400; - private static int dimensionalTearEmergenceMaxIntervalTicks = 7200; + private static int dimensionalTearEmergenceMinIntervalTicks = 400; + private static int dimensionalTearEmergenceMaxIntervalTicks = 1200; private static float dimensionalTearLucidEventChance = 0.65F; private static int ultimateToolEnchantability = 25; private static int ultimateArmorEnchantability = 10; @@ -250,6 +250,23 @@ public final class AntarchySettings { private static double queenHealth = 6000.0D; private static double kingAttackDamage = 50.0D; private static double queenAttackDamage = 45.0D; + private static double royalBossSoundVolume = 4.5D; + private static double queenBlackHoleRadius = 14.0D; + private static int queenBlackHoleActiveTicks = 120; + private static double queenBlackHolePullStrength = 0.16D; + private static double queenFinalTimeFieldRadius = 20.0D; + private static double queenFinalTimeFieldRate = 0.05D; + private static int queenFinalTimeFieldDurationTicks = 45; + private static int queenFinalTimeFieldCooldownTicks = 80; + private static double kingFireballDamage = 32.0D; + private static double kingFireballRadius = 4.5D; + private static int kingFireballCooldownTicks = 150; + private static double kingIceballDamage = 18.0D; + private static double kingIceballRadius = 5.0D; + private static int kingIceballCooldownTicks = 190; + private static double kingIceSpikeDamage = 24.0D; + private static int kingIceSpikeCooldownTicks = 240; + private static int kingElementalTerrainCap = 256; private static double royalBossArmor = 20.0D; private static double royalBossFollowRange = 128.0D; private static double royalBossMovementSpeed = 0.22D; @@ -391,7 +408,7 @@ public final class AntarchySettings { private static double toreterrorDamageRange = 25.0D; private static double brutalflyDamageRange = 25.0D; private static double alphaMantisDamageRange = 25.0D; - private static float krakenLightningDamagePhaseOne = 12.0F; + private static float krakenLightningDamagePhaseOne = 6.0F; private static double lucidHealth = 70.0D; private static double lucidAttackDamage = 4.0D; private static double lucidMovementSpeed = 0.22D; @@ -402,7 +419,7 @@ public final class AntarchySettings { private static double vortexMovementSpeed = 0.22D; private static double vortexFlyingSpeed = 0.35D; private static int vortexMaxActiveVortexes = 3; - private static int windVortexDurationTicks = 140; + private static int windVortexDurationTicks = 240; private static double windVortexPullStrength = 0.32D; private static double windVortexLaunchStrength = 1.0D; private static boolean eyeOfTheStormEnabled = true; @@ -534,6 +551,8 @@ public final class AntarchySettings { private static double queenBeamDamage = 45.0D; private static double queenBeamRange = 100.0D; private static int queenBeamDurationTicks = 30; + private static int queenBeamWindupTicks = 20; + private static int queenBeamTravelTicks = 12; private static int queenBeamCooldownTicks = 90; private static double queenBeamTracking = 0.1D; private static double queenBeamTerrainRadius = 5.0D; @@ -541,6 +560,8 @@ public final class AntarchySettings { private static double kingBeamDamage = 50.0D; private static double kingBeamRange = 100.0D; private static int kingBeamDurationTicks = 30; + private static int kingBeamWindupTicks = 20; + private static int kingBeamTravelTicks = 12; private static int kingBeamCooldownTicks = 90; private static double kingBeamTracking = 0.1D; private static double kingBeamTerrainRadius = 5.0D; @@ -803,6 +824,8 @@ public final class AntarchySettings { return bigBerthaNightmareDamageBonusPercent; } + public static double krakensGraspLightningDamage() { return krakensGraspLightningDamage; } + public static double potentNyxiteInvertedDurationSeconds() { return potentNyxiteInvertedDurationSeconds; } @@ -2013,6 +2036,40 @@ public final class AntarchySettings { public static double queenAttackDamage() { return queenAttackDamage; } public static void setQueenAttackDamage(double v) { queenAttackDamage = v; } + public static double royalBossSoundVolume() { return royalBossSoundVolume; } + public static void setRoyalBossSoundVolume(double v) { royalBossSoundVolume = v; } + public static double queenBlackHoleRadius() { return queenBlackHoleRadius; } + public static void setQueenBlackHoleRadius(double v) { queenBlackHoleRadius = v; } + public static int queenBlackHoleActiveTicks() { return queenBlackHoleActiveTicks; } + public static void setQueenBlackHoleActiveTicks(int v) { queenBlackHoleActiveTicks = v; } + public static double queenBlackHolePullStrength() { return queenBlackHolePullStrength; } + public static void setQueenBlackHolePullStrength(double v) { queenBlackHolePullStrength = v; } + public static double queenFinalTimeFieldRadius() { return queenFinalTimeFieldRadius; } + public static void setQueenFinalTimeFieldRadius(double v) { queenFinalTimeFieldRadius = v; } + public static double queenFinalTimeFieldRate() { return queenFinalTimeFieldRate; } + public static void setQueenFinalTimeFieldRate(double v) { queenFinalTimeFieldRate = v; } + public static int queenFinalTimeFieldDurationTicks() { return queenFinalTimeFieldDurationTicks; } + public static void setQueenFinalTimeFieldDurationTicks(int v) { queenFinalTimeFieldDurationTicks = v; } + public static int queenFinalTimeFieldCooldownTicks() { return queenFinalTimeFieldCooldownTicks; } + public static void setQueenFinalTimeFieldCooldownTicks(int v) { queenFinalTimeFieldCooldownTicks = v; } + public static double kingFireballDamage() { return kingFireballDamage; } + public static void setKingFireballDamage(double v) { kingFireballDamage = v; } + public static double kingFireballRadius() { return kingFireballRadius; } + public static void setKingFireballRadius(double v) { kingFireballRadius = v; } + public static int kingFireballCooldownTicks() { return kingFireballCooldownTicks; } + public static void setKingFireballCooldownTicks(int v) { kingFireballCooldownTicks = v; } + public static double kingIceballDamage() { return kingIceballDamage; } + public static void setKingIceballDamage(double v) { kingIceballDamage = v; } + public static double kingIceballRadius() { return kingIceballRadius; } + public static void setKingIceballRadius(double v) { kingIceballRadius = v; } + public static int kingIceballCooldownTicks() { return kingIceballCooldownTicks; } + public static void setKingIceballCooldownTicks(int v) { kingIceballCooldownTicks = v; } + public static double kingIceSpikeDamage() { return kingIceSpikeDamage; } + public static void setKingIceSpikeDamage(double v) { kingIceSpikeDamage = v; } + public static int kingIceSpikeCooldownTicks() { return kingIceSpikeCooldownTicks; } + public static void setKingIceSpikeCooldownTicks(int v) { kingIceSpikeCooldownTicks = v; } + public static int kingElementalTerrainCap() { return kingElementalTerrainCap; } + public static void setKingElementalTerrainCap(int v) { kingElementalTerrainCap = v; } public static double royalBossArmor() { return royalBossArmor; } public static void setRoyalBossArmor(double v) { royalBossArmor = v; } @@ -2832,6 +2889,10 @@ public final class AntarchySettings { public static void setQueenBeamRange(double v) { queenBeamRange = v; } public static int queenBeamDurationTicks() { return queenBeamDurationTicks; } public static void setQueenBeamDurationTicks(int v) { queenBeamDurationTicks = v; } + public static int queenBeamWindupTicks() { return queenBeamWindupTicks; } + public static void setQueenBeamWindupTicks(int v) { queenBeamWindupTicks = v; } + public static int queenBeamTravelTicks() { return queenBeamTravelTicks; } + public static void setQueenBeamTravelTicks(int v) { queenBeamTravelTicks = v; } public static int queenBeamCooldownTicks() { return queenBeamCooldownTicks; } public static void setQueenBeamCooldownTicks(int v) { queenBeamCooldownTicks = v; } public static double queenBeamTracking() { return queenBeamTracking; } @@ -2846,6 +2907,10 @@ public final class AntarchySettings { public static void setKingBeamRange(double v) { kingBeamRange = v; } public static int kingBeamDurationTicks() { return kingBeamDurationTicks; } public static void setKingBeamDurationTicks(int v) { kingBeamDurationTicks = v; } + public static int kingBeamWindupTicks() { return kingBeamWindupTicks; } + public static void setKingBeamWindupTicks(int v) { kingBeamWindupTicks = v; } + public static int kingBeamTravelTicks() { return kingBeamTravelTicks; } + public static void setKingBeamTravelTicks(int v) { kingBeamTravelTicks = v; } public static int kingBeamCooldownTicks() { return kingBeamCooldownTicks; } public static void setKingBeamCooldownTicks(int v) { kingBeamCooldownTicks = v; } public static double kingBeamTracking() { return kingBeamTracking; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java index e0cf683b..d1d87ac1 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java @@ -157,6 +157,10 @@ public final class AntarchyObjects { @SuppressWarnings("unchecked") public static Supplier> ROYAL_BOLT = (Supplier>) UNBOUND; @SuppressWarnings("unchecked") + public static Supplier> ROYAL_ELEMENTAL_PROJECTILE = (Supplier>) UNBOUND; + @SuppressWarnings("unchecked") + public static Supplier> ROYAL_ICE_SPIKE = (Supplier>) UNBOUND; + @SuppressWarnings("unchecked") public static Supplier> KING = (Supplier>) UNBOUND; @SuppressWarnings("unchecked") public static Supplier> QUEEN = (Supplier>) UNBOUND; @@ -725,6 +729,14 @@ public final class AntarchyObjects { ROYAL_BOLT = supplier; } + public static void setRoyalElementalProjectile(Supplier> supplier) { + ROYAL_ELEMENTAL_PROJECTILE = supplier; + } + + public static void setRoyalIceSpike(Supplier> supplier) { + ROYAL_ICE_SPIKE = supplier; + } + public static void setKing(Supplier> supplier) { KING = supplier; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchySoundEvents.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchySoundEvents.java index 095567d2..4849b8e9 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchySoundEvents.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchySoundEvents.java @@ -202,6 +202,7 @@ public final class AntarchySoundEvents { public static Supplier KING_ROAR = (Supplier) UNBOUND; public static Supplier KING_WING_FLAP = (Supplier) UNBOUND; public static Supplier KING_FLY_LOOP = (Supplier) UNBOUND; + public static Supplier QUEEN_FLY_LOOP = (Supplier) UNBOUND; public static Supplier PRINCE_IDLE = (Supplier) UNBOUND; public static Supplier PRINCE_BITE = (Supplier) UNBOUND; public static Supplier PRINCE_SHOOT = (Supplier) UNBOUND; @@ -406,6 +407,7 @@ public final class AntarchySoundEvents { Supplier kingRoar, Supplier kingWingFlap, Supplier kingFlyLoop, + Supplier queenFlyLoop, Supplier princeIdle, Supplier princeBite, Supplier princeShoot, @@ -606,6 +608,7 @@ public final class AntarchySoundEvents { KING_ROAR = kingRoar; KING_WING_FLAP = kingWingFlap; KING_FLY_LOOP = kingFlyLoop; + QUEEN_FLY_LOOP = queenFlyLoop; PRINCE_IDLE = princeIdle; PRINCE_BITE = princeBite; PRINCE_SHOOT = princeShoot; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchyTags.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchyTags.java index 865c33a4..d8f19501 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchyTags.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/AntarchyTags.java @@ -85,6 +85,8 @@ public final class AntarchyTags { public static final TagKey> DIMENSIONAL_TEAR_COMMON_SPAWNS = TagKey.create(Registries.ENTITY_TYPE, id("dimensional_tear_common_spawns")); public static final TagKey> DIMENSIONAL_TEAR_RARE_SPAWNS = TagKey.create(Registries.ENTITY_TYPE, id("dimensional_tear_rare_spawns")); public static final TagKey> TIME_DILATION_IMMUNE = TagKey.create(Registries.ENTITY_TYPE, id("time_dilation_immune")); + public static final TagKey> COMMANDED_BLACKLIST = TagKey.create(Registries.ENTITY_TYPE, id("commanded_blacklist")); + public static final TagKey> DILATED_BLACKLIST = TagKey.create(Registries.ENTITY_TYPE, id("dilated_blacklist")); private Entities() { } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/DimensionalTearMarkerBlockEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/DimensionalTearMarkerBlockEntity.java index 7cd8f318..546569ed 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/DimensionalTearMarkerBlockEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/DimensionalTearMarkerBlockEntity.java @@ -12,17 +12,23 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; public class DimensionalTearMarkerBlockEntity extends BlockEntity { - private static final int MAX_ATTEMPT_TICKS = 100; + private static final int MAX_ATTEMPT_TICKS = 80; private static final int MIN_LINK_RANGE = 50; private static final int MAX_LINK_RANGE = 500; - private static final int PARTNER_ORIGIN_ATTEMPTS = 12; - private static final int PARTNER_SEARCH_ATTEMPTS = 48; - private static final int LOCAL_SEARCH_ATTEMPTS = 18; - private static final int SEARCH_ATTEMPTS_PER_TICK = 2; + private static final int PARTNER_ORIGIN_ATTEMPTS = 8; + private static final int PARTNER_SEARCH_ATTEMPTS = 32; + private static final int LOCAL_SEARCH_ATTEMPTS = 12; + private static final int SEARCH_ATTEMPTS_PER_TICK = 1; + private static final int MIN_VERTICAL_SEPARATION = 24; + private static final int MIN_PARTNER_VERTICAL_OFFSET = 48; + private static final int MAX_PARTNER_VERTICAL_OFFSET = 96; + private static final int NATURAL_TEAR_LOCAL_RADIUS = 512; + private static final int NATURAL_TEAR_LOCAL_CAP = 6; private int attemptTicks; private int localAttempts; @@ -64,6 +70,11 @@ public class DimensionalTearMarkerBlockEntity extends BlockEntity { continue; } + if (partnerOrigin == null && partnerOriginAttempts == 0 + && countNearbyTears(level, origin) >= NATURAL_TEAR_LOCAL_CAP) { + return false; + } + if (partnerOrigin == null || partnerSearchAttempts >= PARTNER_SEARCH_ATTEMPTS) { if (partnerOriginAttempts >= PARTNER_ORIGIN_ATTEMPTS) { return false; @@ -75,7 +86,8 @@ public class DimensionalTearMarkerBlockEntity extends BlockEntity { partnerSearchAttempts++; BlockPos candidate = randomCandidate(partnerOrigin, random); - if (!isUsablePocket(level, candidate)) { + if (Math.abs(candidate.getY() - firstPocket.getY()) < MIN_VERTICAL_SEPARATION + || !isUsablePocket(level, candidate)) { continue; } return spawnPair(level, random, firstPocket, candidate); @@ -111,10 +123,16 @@ public class DimensionalTearMarkerBlockEntity extends BlockEntity { int distance = Mth.nextInt(random, MIN_LINK_RANGE, MAX_LINK_RANGE); int dx = Mth.floor(Math.cos(angle) * distance); int dz = Mth.floor(Math.sin(angle) * distance); - int dy = Mth.nextInt(random, -36, 36); + int verticalOffset = Mth.nextInt(random, MIN_PARTNER_VERTICAL_OFFSET, MAX_PARTNER_VERTICAL_OFFSET); + int dy = random.nextBoolean() ? verticalOffset : -verticalOffset; return first.offset(dx, dy, dz); } + private static int countNearbyTears(ServerLevel level, BlockPos origin) { + AABB area = new AABB(origin).inflate(NATURAL_TEAR_LOCAL_RADIUS); + return level.getEntitiesOfClass(DimensionalTearEntity.class, area).size(); + } + private static boolean isUsablePocket(ServerLevel level, BlockPos pos) { int minY = level.getMinBuildHeight() + 8; int maxY = level.getMaxBuildHeight() - 8; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ClientTimeDilationTicker.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ClientTimeDilationTicker.java index 97886a73..0a042ba3 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ClientTimeDilationTicker.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ClientTimeDilationTicker.java @@ -10,6 +10,7 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; import net.minecraft.util.Mth; public final class ClientTimeDilationTicker { @@ -32,6 +33,11 @@ public final class ClientTimeDilationTicker { com.craisinlord.antarchy.content.time.TimeDilationApi.clearSyncedClientRates(); } // Entity rates come from the server. Field snapshots are used only for local effects. + for (Player player : level.players()) { + if (player.isDeadOrDying() || rateAt(player.getX(), player.getY(), player.getZ()) >= TimeDilationMath.NORMAL_RATE) { + com.craisinlord.antarchy.content.time.TimeDilationApi.clearRate(player); + } + } } public static float dilateAnimationTime(Entity entity, float vanillaTime) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalBlackHoleModel.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalBlackHoleModel.java new file mode 100644 index 00000000..a0d8d665 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalBlackHoleModel.java @@ -0,0 +1,23 @@ +package com.craisinlord.antarchy.content.client.model; + +import com.craisinlord.antarchy.Antarchy; +import com.craisinlord.antarchy.content.entity.royal.RoyalBlackHoleEntity; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class RoyalBlackHoleModel extends GeoModel { + @Override + public ResourceLocation getModelResource(RoyalBlackHoleEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "geo/black_hole.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(RoyalBlackHoleEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/queen/black_hole.png"); + } + + @Override + public ResourceLocation getAnimationResource(RoyalBlackHoleEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "animations/black_hole.animation.json"); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalElementalProjectileModel.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalElementalProjectileModel.java new file mode 100644 index 00000000..04785e5d --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalElementalProjectileModel.java @@ -0,0 +1,26 @@ +package com.craisinlord.antarchy.content.client.model; + +import com.craisinlord.antarchy.Antarchy; +import com.craisinlord.antarchy.content.entity.royal.RoyalElementalProjectileEntity; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class RoyalElementalProjectileModel extends GeoModel { + @Override + public ResourceLocation getModelResource(RoyalElementalProjectileEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, + "geo/" + (animatable.isIceball() ? "ice_ball" : "fire_ball") + ".geo.json"); + } + + @Override + public ResourceLocation getTextureResource(RoyalElementalProjectileEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, + "textures/entity/king/" + (animatable.isIceball() ? "ice_ball" : "fire_ball") + ".png"); + } + + @Override + public ResourceLocation getAnimationResource(RoyalElementalProjectileEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, + "animations/" + (animatable.isIceball() ? "ice_ball" : "fire_ball") + ".animation.json"); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalIceSpikeModel.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalIceSpikeModel.java new file mode 100644 index 00000000..27ffa87e --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalIceSpikeModel.java @@ -0,0 +1,23 @@ +package com.craisinlord.antarchy.content.client.model; + +import com.craisinlord.antarchy.Antarchy; +import com.craisinlord.antarchy.content.entity.royal.RoyalIceSpikeEntity; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class RoyalIceSpikeModel extends GeoModel { + @Override + public ResourceLocation getModelResource(RoyalIceSpikeEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "geo/ice_spike.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(RoyalIceSpikeEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/king/ice_spike.png"); + } + + @Override + public ResourceLocation getAnimationResource(RoyalIceSpikeEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "animations/ice_spike.animation.json"); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalBlackHoleRenderer.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalBlackHoleRenderer.java new file mode 100644 index 00000000..bd25a3ed --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalBlackHoleRenderer.java @@ -0,0 +1,30 @@ +package com.craisinlord.antarchy.content.client.renderer; + +import com.craisinlord.antarchy.content.client.model.RoyalBlackHoleModel; +import com.craisinlord.antarchy.content.entity.royal.RoyalBlackHoleEntity; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.Nullable; +import software.bernie.geckolib.renderer.GeoEntityRenderer; + +public class RoyalBlackHoleRenderer extends GeoEntityRenderer { + public RoyalBlackHoleRenderer(EntityRendererProvider.Context context) { + super(context, new RoyalBlackHoleModel()); + this.shadowRadius = 0.0F; + } + + @Override + public void render(RoyalBlackHoleEntity entity, float entityYaw, float partialTick, PoseStack poseStack, + MultiBufferSource bufferSource, int packedLight) { + super.render(entity, entityYaw, partialTick, poseStack, bufferSource, 0xF000F0); + } + + @Override + public @Nullable RenderType getRenderType(RoyalBlackHoleEntity animatable, ResourceLocation texture, + @Nullable MultiBufferSource bufferSource, float partialTick) { + return RenderType.entityTranslucent(this.getTextureLocation(animatable)); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalBossRenderer.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalBossRenderer.java index 7717bb46..f9b76e33 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalBossRenderer.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalBossRenderer.java @@ -58,8 +58,8 @@ public class RoyalBossRenderer extends GeoEntityRenderer { this.shadowRadius = 8.0F * RoyalBossEntity.MODEL_RENDER_SCALE; } - private static final float BEAM_OUTER_RADIUS = 0.55F; - private static final float BEAM_INNER_RADIUS = 0.26F; + private static final float BEAM_OUTER_RADIUS = 1.10F; + private static final float BEAM_INNER_RADIUS = 0.52F; private static final float BEAM_TILE_BLOCKS = 3.0F; private static final float BEAM_SCROLL_SPEED = 0.32F; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalElementalProjectileRenderer.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalElementalProjectileRenderer.java new file mode 100644 index 00000000..52056457 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalElementalProjectileRenderer.java @@ -0,0 +1,38 @@ +package com.craisinlord.antarchy.content.client.renderer; + +import com.craisinlord.antarchy.content.client.model.RoyalElementalProjectileModel; +import com.craisinlord.antarchy.content.entity.royal.RoyalElementalProjectileEntity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.util.Mth; +import software.bernie.geckolib.cache.object.BakedGeoModel; +import software.bernie.geckolib.renderer.GeoEntityRenderer; + +public class RoyalElementalProjectileRenderer extends GeoEntityRenderer { + public RoyalElementalProjectileRenderer(EntityRendererProvider.Context context) { + super(context, new RoyalElementalProjectileModel()); + this.shadowRadius = 0.0F; + } + + @Override + public void preRender(PoseStack poseStack, RoyalElementalProjectileEntity animatable, BakedGeoModel model, + MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, + float partialTick, int packedLight, int packedOverlay, int colour) { + super.preRender(poseStack, animatable, model, bufferSource, buffer, isReRender, partialTick, + packedLight, packedOverlay, colour); + float scale = animatable.isIceball() ? 0.75F : 0.36F; + poseStack.scale(scale, scale, scale); + } + + @Override + protected void applyRotations(RoyalElementalProjectileEntity entity, PoseStack poseStack, float ageInTicks, + float rotationYaw, float partialTick, float nativeScale) { + float yaw = Mth.rotLerp(partialTick, entity.yRotO, entity.getYRot()); + float pitch = Mth.lerp(partialTick, entity.xRotO, entity.getXRot()); + poseStack.mulPose(Axis.YP.rotationDegrees(180.0F - yaw)); + poseStack.mulPose(Axis.XP.rotationDegrees(-pitch)); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalIceSpikeRenderer.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalIceSpikeRenderer.java new file mode 100644 index 00000000..49033216 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalIceSpikeRenderer.java @@ -0,0 +1,14 @@ +package com.craisinlord.antarchy.content.client.renderer; + +import com.craisinlord.antarchy.content.client.model.RoyalIceSpikeModel; +import com.craisinlord.antarchy.content.entity.royal.RoyalIceSpikeEntity; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import software.bernie.geckolib.renderer.GeoEntityRenderer; + +public class RoyalIceSpikeRenderer extends GeoEntityRenderer { + public RoyalIceSpikeRenderer(EntityRendererProvider.Context context) { + super(context, new RoyalIceSpikeModel()); + this.shadowRadius = 0.0F; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/WindVortexRenderer.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/WindVortexRenderer.java index 6cf50ec3..a88cf9ce 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/WindVortexRenderer.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/WindVortexRenderer.java @@ -12,9 +12,8 @@ import net.minecraft.util.Mth; import org.joml.Matrix4f; public class WindVortexRenderer extends EntityRenderer { - private static final int RINGS = 10; - private static final int SEGMENTS_PER_RING = 12; - private static final int ARC_STEPS = 6; + private static final int RINGS = 11; + private static final int SQUARES_PER_SIDE = 3; private static final float BASE_RADIUS = 0.35F; public WindVortexRenderer(EntityRendererProvider.Context context) { @@ -44,48 +43,72 @@ public class WindVortexRenderer extends EntityRenderer { float radius = Mth.lerp(shapeProgress, BASE_RADIUS, topRadius); float ringSpin = spinDirection * age * (0.13F + progress * 0.045F) + ring * 0.47F; float alpha = alphaMultiplier; - float thickness = 0.025F + radius * 0.012F; - float arcLength = 0.34F + progress * 0.08F; + float halfSide = radius * 0.92F; + float tileSize = Math.max(0.035F, radius * 0.12F); int red = push ? 70 : 64; int green = push ? 220 : 255; int blue = push ? 255 : 56; - - for (int segment = 0; segment < SEGMENTS_PER_RING; segment++) { - float baseAngle = ringSpin + segment * Mth.TWO_PI / SEGMENTS_PER_RING; - float start = baseAngle - arcLength * 0.5F; - float end = baseAngle + arcLength * 0.5F; - drawArc(consumer, pose, basis, radius, axisDistance, thickness, start, end, alpha, red, green, blue); - } + drawSquareRing(consumer, pose, basis, halfSide, axisDistance, tileSize, ringSpin, + alpha, red, green, blue); } super.render(entity, entityYaw, partialTick, poseStack, bufferSource, packedLight); } - private static void drawArc(VertexConsumer consumer, Matrix4f pose, WindVortexEntity.Basis basis, float radius, - float axisDistance, float thickness, float start, float end, float alpha, int red, int green, int blue) { - float previousAngle = start; - for (int step = 1; step <= ARC_STEPS; step++) { - float angle = Mth.lerp(step / (float) ARC_STEPS, start, end); - addLineQuad(consumer, pose, basis, radius, axisDistance, thickness, previousAngle, angle, alpha, red, green, blue); - previousAngle = angle; + private static void drawSquareRing(VertexConsumer consumer, Matrix4f pose, WindVortexEntity.Basis basis, + float halfSide, float axisDistance, float tileSize, float rotation, float alpha, + int red, int green, int blue) { + for (int side = 0; side < 4; side++) { + for (int tile = 0; tile < SQUARES_PER_SIDE; tile++) { + float start = -halfSide + (tile + 0.18F) * (2.0F * halfSide / SQUARES_PER_SIDE); + float end = -halfSide + (tile + 0.82F) * (2.0F * halfSide / SQUARES_PER_SIDE); + float sideAngle = rotation + side * (Mth.TWO_PI / 4.0F); + addSquareTile(consumer, pose, basis, halfSide, axisDistance, tileSize, + sideAngle, start, end, alpha, red, green, blue); + } } } - private static void addLineQuad(VertexConsumer consumer, Matrix4f pose, WindVortexEntity.Basis basis, float radius, - float axisDistance, float thickness, float startAngle, float endAngle, float alpha, int red, int green, int blue) { - org.joml.Vector3f start = point(basis, radius, axisDistance, startAngle); - org.joml.Vector3f end = point(basis, radius, axisDistance, endAngle); - org.joml.Vector3f axisOffset = new org.joml.Vector3f((float) basis.axis.x, (float) basis.axis.y, (float) basis.axis.z).mul(thickness); - float middleAngle = (startAngle + endAngle) * 0.5F; - org.joml.Vector3f radialOffset = new org.joml.Vector3f( - (float) (basis.sideA.x * Mth.cos(middleAngle) + basis.sideB.x * Mth.sin(middleAngle)), - (float) (basis.sideA.y * Mth.cos(middleAngle) + basis.sideB.y * Mth.sin(middleAngle)), - (float) (basis.sideA.z * Mth.cos(middleAngle) + basis.sideB.z * Mth.sin(middleAngle)) - ).mul(thickness); + private static void addSquareTile(VertexConsumer consumer, Matrix4f pose, WindVortexEntity.Basis basis, + float halfSide, float axisDistance, float tileSize, float sideAngle, float start, float end, + float alpha, int red, int green, int blue) { + org.joml.Vector3f center = squarePoint(basis, halfSide, axisDistance, sideAngle, (start + end) * 0.5F); + org.joml.Vector3f tangent = new org.joml.Vector3f( + (float) (-basis.sideA.x * Mth.sin(sideAngle) + basis.sideB.x * Mth.cos(sideAngle)), + (float) (-basis.sideA.y * Mth.sin(sideAngle) + basis.sideB.y * Mth.cos(sideAngle)), + (float) (-basis.sideA.z * Mth.sin(sideAngle) + basis.sideB.z * Mth.cos(sideAngle))); + org.joml.Vector3f axisOffset = new org.joml.Vector3f( + (float) basis.axis.x, (float) basis.axis.y, (float) basis.axis.z).mul(tileSize * 0.5F); + tangent.mul(tileSize * 0.5F); int a = Mth.clamp((int) (alpha * 255.0F), 0, 255); + addVertex(consumer, pose, center.x - tangent.x - axisOffset.x, center.y - tangent.y - axisOffset.y, + center.z - tangent.z - axisOffset.z, red, green, blue, a); + addVertex(consumer, pose, center.x + tangent.x - axisOffset.x, center.y + tangent.y - axisOffset.y, + center.z + tangent.z - axisOffset.z, red, green, blue, a); + addVertex(consumer, pose, center.x + tangent.x + axisOffset.x, center.y + tangent.y + axisOffset.y, + center.z + tangent.z + axisOffset.z, red, green, blue, a); + addVertex(consumer, pose, center.x - tangent.x + axisOffset.x, center.y - tangent.y + axisOffset.y, + center.z - tangent.z + axisOffset.z, red, green, blue, a); + addVertex(consumer, pose, center.x - tangent.x + axisOffset.x, center.y - tangent.y + axisOffset.y, + center.z - tangent.z + axisOffset.z, red, green, blue, a); + addVertex(consumer, pose, center.x + tangent.x + axisOffset.x, center.y + tangent.y + axisOffset.y, + center.z + tangent.z + axisOffset.z, red, green, blue, a); + addVertex(consumer, pose, center.x + tangent.x - axisOffset.x, center.y + tangent.y - axisOffset.y, + center.z + tangent.z - axisOffset.z, red, green, blue, a); + addVertex(consumer, pose, center.x - tangent.x - axisOffset.x, center.y - tangent.y - axisOffset.y, + center.z - tangent.z - axisOffset.z, red, green, blue, a); + } - addQuad(consumer, pose, start, end, axisOffset, red, green, blue, a); - addQuad(consumer, pose, start, end, radialOffset, red, green, blue, a); + private static org.joml.Vector3f squarePoint(WindVortexEntity.Basis basis, float halfSide, + float axisDistance, float sideAngle, float along) { + float x = Mth.cos(sideAngle) * halfSide; + float z = Mth.sin(sideAngle) * halfSide; + float tangentX = -Mth.sin(sideAngle) * along; + float tangentZ = Mth.cos(sideAngle) * along; + return new org.joml.Vector3f( + (float) (basis.axis.x * axisDistance + basis.sideA.x * (x + tangentX) + basis.sideB.x * (z + tangentZ)), + (float) (basis.axis.y * axisDistance + basis.sideA.y * (x + tangentX) + basis.sideB.y * (z + tangentZ)), + (float) (basis.axis.z * axisDistance + basis.sideA.z * (x + tangentX) + basis.sideB.z * (z + tangentZ))); } private static void addQuad(VertexConsumer consumer, Matrix4f pose, org.joml.Vector3f start, @@ -94,15 +117,14 @@ public class WindVortexRenderer extends EntityRenderer { addVertex(consumer, pose, end.x - offset.x, end.y - offset.y, end.z - offset.z, red, green, blue, alpha); addVertex(consumer, pose, end.x + offset.x, end.y + offset.y, end.z + offset.z, red, green, blue, alpha); addVertex(consumer, pose, start.x + offset.x, start.y + offset.y, start.z + offset.z, red, green, blue, alpha); - } - private static org.joml.Vector3f point(WindVortexEntity.Basis basis, float radius, float axisDistance, float angle) { - double radialA = Mth.cos(angle) * radius; - double radialB = Mth.sin(angle) * radius; - double x = basis.axis.x * axisDistance + basis.sideA.x * radialA + basis.sideB.x * radialB; - double y = basis.axis.y * axisDistance + basis.sideA.y * radialA + basis.sideB.y * radialB; - double z = basis.axis.z * axisDistance + basis.sideA.z * radialA + basis.sideB.z * radialB; - return new org.joml.Vector3f((float) x, (float) y, (float) z); + // The lightning render type can cull one winding from some camera + // angles. Emit the opposite winding as well so every ribbon is + // visible from both sides. + addVertex(consumer, pose, start.x + offset.x, start.y + offset.y, start.z + offset.z, red, green, blue, alpha); + addVertex(consumer, pose, end.x + offset.x, end.y + offset.y, end.z + offset.z, red, green, blue, alpha); + addVertex(consumer, pose, end.x - offset.x, end.y - offset.y, end.z - offset.z, red, green, blue, alpha); + addVertex(consumer, pose, start.x - offset.x, start.y - offset.y, start.z - offset.z, red, green, blue, alpha); } private static void addVertex(VertexConsumer consumer, Matrix4f pose, float x, float y, float z, diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/creative/CreativeTabContents.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/creative/CreativeTabContents.java index 820f422e..e126f967 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/creative/CreativeTabContents.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/creative/CreativeTabContents.java @@ -594,7 +594,8 @@ public final class CreativeTabContents { private static final List ANTARCHY_POTION_FAMILIES = List.of( "dread", "long_dread", "inversion", "long_inversion", "stinky", "long_stinky", "paralysis", "long_paralysis", "haste", "strong_haste", "shrinking", - "strong_shrinking", "extreme_shrinking", "growing", "strong_growing", "extreme_growing" + "strong_shrinking", "extreme_shrinking", "growing", "strong_growing", "extreme_growing", + "command", "long_command", "time_dilation", "long_time_dilation" ); private static final Map ORDER_INDEX = createOrderIndex(); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/CommandedBehavior.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/CommandedBehavior.java new file mode 100644 index 00000000..cc6365ef --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/CommandedBehavior.java @@ -0,0 +1,99 @@ +package com.craisinlord.antarchy.content.effect; + +import java.util.UUID; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.player.Player; + +public final class CommandedBehavior { + private CommandedBehavior() { + } + + public static void tick(Mob mob) { + if (!(mob instanceof CommandedEntityAccess access)) { + return; + } + UUID commanderUuid = access.antarchy$getCommanderUuid(); + if (commanderUuid == null || mob.level().getServer() == null) { + clear(mob); + return; + } + ServerPlayer commander = mob.level().getServer().getPlayerList().getPlayer(commanderUuid); + if (commander == null || commander.level() != mob.level() || !RoyalEffectEligibility.canApplyCommanded(mob)) { + mob.removeEffect(RoyalEffectHooks.commandedHolder()); + clear(mob); + return; + } + LivingEntity target = mob.getTarget(); + if (target != null && isProtectedAlly(mob, target)) { + mob.setTarget(null); + target = null; + } + if (mob.tickCount % 10 != 0 || target != null) { + return; + } + LivingEntity candidate = commander.getLastHurtByMob(); + if (!isValidTarget(mob, commander, candidate)) { + candidate = commander.getLastHurtMob(); + } + if (!isValidTarget(mob, commander, candidate)) { + candidate = mob.getLastHurtByMob(); + } + if (!isValidTarget(mob, commander, candidate)) { + candidate = mob.level().getEntitiesOfClass(LivingEntity.class, mob.getBoundingBox().inflate(16.0D), + entity -> isValidTarget(mob, commander, entity)).stream() + .min((a, b) -> { + int distance = Double.compare(mob.distanceToSqr(a), mob.distanceToSqr(b)); + return distance != 0 ? distance : Integer.compare(a.getId(), b.getId()); + }).orElse(null); + } + if (candidate != null) { + mob.setTarget(candidate); + access.antarchy$setCommandedTargetOwned(true); + } + } + + public static boolean isProtectedAlly(Mob mob, Entity entity) { + if (!(mob instanceof CommandedEntityAccess access) || entity == null) { + return false; + } + UUID commanderUuid = access.antarchy$getCommanderUuid(); + if (commanderUuid == null) { + return false; + } + if (entity.getUUID().equals(commanderUuid)) { + return true; + } + if (entity instanceof Mob other && other instanceof CommandedEntityAccess otherAccess) { + return commanderUuid.equals(otherAccess.antarchy$getCommanderUuid()); + } + if (entity instanceof LivingEntity living && living.isAlliedTo(mob)) { + return true; + } + if (mob.level().getServer() != null + && mob.level().getServer().getPlayerList().getPlayer(commanderUuid) instanceof Player commander + && entity instanceof LivingEntity living) { + return living.isAlliedTo(commander); + } + return false; + } + + private static boolean isValidTarget(Mob mob, ServerPlayer commander, LivingEntity target) { + return target != null && target.isAlive() && target != mob && target != commander + && !isProtectedAlly(mob, target) && !target.isAlliedTo(commander) + && mob.canAttack(target); + } + + public static void clear(Mob mob) { + if (!(mob instanceof CommandedEntityAccess access)) { + return; + } + if (access.antarchy$isCommandedTargetOwned()) { + mob.setTarget(null); + } + access.antarchy$setCommandedTargetOwned(false); + access.antarchy$setCommanderUuid(null); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/CommandedEntityAccess.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/CommandedEntityAccess.java new file mode 100644 index 00000000..6907148d --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/CommandedEntityAccess.java @@ -0,0 +1,10 @@ +package com.craisinlord.antarchy.content.effect; + +import java.util.UUID; + +public interface CommandedEntityAccess { + UUID antarchy$getCommanderUuid(); + void antarchy$setCommanderUuid(UUID uuid); + boolean antarchy$isCommandedTargetOwned(); + void antarchy$setCommandedTargetOwned(boolean owned); +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/CommandedMobEffect.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/CommandedMobEffect.java new file mode 100644 index 00000000..3138c6f9 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/CommandedMobEffect.java @@ -0,0 +1,25 @@ +package com.craisinlord.antarchy.content.effect; + +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; + +public final class CommandedMobEffect extends MobEffect { + public CommandedMobEffect() { + super(MobEffectCategory.HARMFUL, 0xD4AF37); + } + + @Override + public boolean applyEffectTick(LivingEntity entity, int amplifier) { + if (!entity.level().isClientSide() && entity instanceof Mob mob) { + CommandedBehavior.tick(mob); + } + return true; + } + + @Override + public boolean shouldApplyEffectTickThisTick(int duration, int amplifier) { + return true; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/DilatedMobEffect.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/DilatedMobEffect.java new file mode 100644 index 00000000..908d92ee --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/DilatedMobEffect.java @@ -0,0 +1,23 @@ +package com.craisinlord.antarchy.content.effect; + +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +import net.minecraft.world.entity.LivingEntity; + +public final class DilatedMobEffect extends MobEffect { + public static final double RATE = 0.35D; + + public DilatedMobEffect() { + super(MobEffectCategory.HARMFUL, 0x6C4AB6); + } + + @Override + public boolean applyEffectTick(LivingEntity entity, int amplifier) { + return true; + } + + @Override + public boolean shouldApplyEffectTickThisTick(int duration, int amplifier) { + return true; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/InvertedMobEffect.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/InvertedMobEffect.java index b3bb5f15..b0e5da9f 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/InvertedMobEffect.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/InvertedMobEffect.java @@ -1,11 +1,14 @@ package com.craisinlord.antarchy.content.effect; +import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; import com.craisinlord.antarchy.content.gravity.AntarchyGravityTransition; +import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; public final class InvertedMobEffect extends MobEffect { private static final AntarchyGravityTransition EFFECT_TRANSITION = new AntarchyGravityTransition(12); @@ -19,6 +22,19 @@ public final class InvertedMobEffect extends MobEffect { public boolean applyEffectTick(LivingEntity entity, int amplifier) { if (!entity.level().isClientSide()) { if (AntarchyGravityApi.getGravityDirection(entity) != AntarchyGravityDirection.UP || !AntarchyGravityApi.isGravityForced(entity)) { + MobEffectInstance effect = entity.getEffect(com.craisinlord.antarchy.content.AntarchyObjects.INVERTED_EFFECT.get()); + if (entity instanceof Player || com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisUndersideManager.isThoraxis(entity.level())) { + Antarchy.LOGGER.info( + "[antarchy-gravity] applying inverted gravity from effect targetType={} uuid={} pos=({}, {}, {}) dim={} duration={} ambient={} visible={} forcedBefore={} gameTime={}", + entity.getType(), entity.getUUID(), entity.getX(), entity.getY(), entity.getZ(), + entity.level().dimension().location(), + effect != null ? effect.getDuration() : -1, + effect != null && effect.isAmbient(), + effect != null && effect.isVisible(), + AntarchyGravityApi.isGravityForced(entity), + entity.level().getGameTime() + ); + } AntarchyGravityApi.setForcedGravityDirection(entity, AntarchyGravityDirection.UP, EFFECT_TRANSITION); } } else { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/RoyalEffectEligibility.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/RoyalEffectEligibility.java new file mode 100644 index 00000000..2f3dcf54 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/RoyalEffectEligibility.java @@ -0,0 +1,57 @@ +package com.craisinlord.antarchy.content.effect; + +import com.craisinlord.antarchy.content.AntarchyTags; +import com.craisinlord.antarchy.content.item.RoyalAssailantArmorItem; +import com.craisinlord.antarchy.content.item.RoyalGuardianArmorItem; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.player.Player; + +public final class RoyalEffectEligibility { + private RoyalEffectEligibility() { + } + + public static boolean isCommanded(MobEffectInstance instance) { + return RoyalEffectHooks.commandedHolder() != null && instance.is(RoyalEffectHooks.commandedHolder()); + } + + public static boolean isDilated(MobEffectInstance instance) { + return RoyalEffectHooks.dilatedHolder() != null && instance.is(RoyalEffectHooks.dilatedHolder()); + } + + public static boolean canApplyCommanded(LivingEntity entity) { + return entity instanceof Mob mob + && !(entity instanceof Player) + && !entity.getType().is(AntarchyTags.Entities.COMMANDED_BLACKLIST) + && !(mob.isNoAi()) + && !(entity.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.HEAD).getItem() instanceof RoyalGuardianArmorItem) + && !(entity.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.CHEST).getItem() instanceof RoyalGuardianArmorItem) + && !(entity.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.LEGS).getItem() instanceof RoyalGuardianArmorItem) + && !(entity.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.FEET).getItem() instanceof RoyalGuardianArmorItem); + } + + public static boolean canApplyDilated(LivingEntity entity) { + return !entity.getType().is(AntarchyTags.Entities.DILATED_BLACKLIST) + && !entity.getType().is(AntarchyTags.Entities.TIME_DILATION_IMMUNE) + && !(entity.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.HEAD).getItem() instanceof RoyalAssailantArmorItem) + && !(entity.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.CHEST).getItem() instanceof RoyalAssailantArmorItem) + && !(entity.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.LEGS).getItem() instanceof RoyalAssailantArmorItem) + && !(entity.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.FEET).getItem() instanceof RoyalAssailantArmorItem); + } + + public static boolean canApply(LivingEntity entity, MobEffectInstance instance) { + if (isCommanded(instance)) { + return canApplyCommanded(entity); + } + if (isDilated(instance)) { + return canApplyDilated(entity); + } + return true; + } + + public static boolean canUseCommandSource(Entity source) { + return source instanceof Player; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/RoyalEffectHooks.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/RoyalEffectHooks.java new file mode 100644 index 00000000..70068b36 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/effect/RoyalEffectHooks.java @@ -0,0 +1,27 @@ +package com.craisinlord.antarchy.content.effect; + +import com.craisinlord.antarchy.Antarchy; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.effect.MobEffect; + +public final class RoyalEffectHooks { + private static final ResourceKey COMMANDED_KEY = ResourceKey.create(Registries.MOB_EFFECT, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "commanded")); + private static final ResourceKey DILATED_KEY = ResourceKey.create(Registries.MOB_EFFECT, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "dilated")); + + private RoyalEffectHooks() { + } + + public static Holder commandedHolder() { + return BuiltInRegistries.MOB_EFFECT.getHolder(COMMANDED_KEY).orElse(null); + } + + public static Holder dilatedHolder() { + return BuiltInRegistries.MOB_EFFECT.getHolder(DILATED_KEY).orElse(null); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BedBugEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BedBugEntity.java index 192216ad..bdb2c3ff 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BedBugEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BedBugEntity.java @@ -98,6 +98,8 @@ public class BedBugEntity extends Animal implements GeoEntity { @Nullable private ItemEntity cachedRottenFlesh; private int nextFoodSearchTick; + private int ignoredRottenFleshId = -1; + private int ignoredRottenFleshUntilTick; private int guardNestCooldown; public BedBugEntity(EntityType entityType, Level level) { @@ -450,6 +452,24 @@ public class BedBugEntity extends Animal implements GeoEntity { this.nextFoodSearchTick = 0; } + private void temporarilyIgnoreRottenFlesh(ItemEntity itemEntity) { + this.ignoredRottenFleshId = itemEntity.getId(); + this.ignoredRottenFleshUntilTick = this.tickCount + 100; + this.invalidateFoodCache(); + } + + private boolean isTemporarilyIgnoredFood(ItemEntity itemEntity) { + if (itemEntity.getId() != this.ignoredRottenFleshId) { + return false; + } + if (this.tickCount >= this.ignoredRottenFleshUntilTick) { + this.ignoredRottenFleshId = -1; + this.ignoredRottenFleshUntilTick = 0; + return false; + } + return true; + } + @Nullable private ItemEntity findNearestRottenFlesh() { return this.level().getEntitiesOfClass( @@ -457,7 +477,8 @@ public class BedBugEntity extends Animal implements GeoEntity { this.getBoundingBox().inflate(FOOD_SEARCH_RADIUS, 2.0D, FOOD_SEARCH_RADIUS), itemEntity -> itemEntity.isAlive() && !itemEntity.getItem().isEmpty() - && itemEntity.getItem().is(Items.ROTTEN_FLESH)) + && itemEntity.getItem().is(Items.ROTTEN_FLESH) + && !this.isTemporarilyIgnoredFood(itemEntity)) .stream() .min(Comparator.comparingDouble(this::distanceToSqr)) .orElse(null); @@ -581,6 +602,7 @@ public class BedBugEntity extends Animal implements GeoEntity { private ItemEntity targetFood; private double lastDistanceSqr; private int stuckTicks; + private int pathRefreshCooldown; private SeekRottenFleshGoal() { this.setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK)); @@ -614,6 +636,7 @@ public class BedBugEntity extends Animal implements GeoEntity { BedBugEntity.this.setTarget(null); this.lastDistanceSqr = Double.MAX_VALUE; this.stuckTicks = 0; + this.pathRefreshCooldown = 0; } @Override @@ -622,6 +645,7 @@ public class BedBugEntity extends Animal implements GeoEntity { this.targetFood = null; this.lastDistanceSqr = Double.MAX_VALUE; this.stuckTicks = 0; + this.pathRefreshCooldown = 0; } @Override @@ -631,7 +655,14 @@ public class BedBugEntity extends Animal implements GeoEntity { } BedBugEntity.this.getLookControl().setLookAt(this.targetFood, 30.0F, 30.0F); - BedBugEntity.this.getNavigation().moveTo(this.targetFood, 1.0D); + if (this.pathRefreshCooldown-- <= 0) { + if (!BedBugEntity.this.getNavigation().moveTo(this.targetFood, 1.0D)) { + BedBugEntity.this.temporarilyIgnoreRottenFlesh(this.targetFood); + this.targetFood = null; + return; + } + this.pathRefreshCooldown = 10; + } double distanceSqr = BedBugEntity.this.distanceToSqr(this.targetFood); if (distanceSqr < this.lastDistanceSqr - 0.2D) { @@ -639,7 +670,7 @@ public class BedBugEntity extends Animal implements GeoEntity { this.stuckTicks = 0; } else if (BedBugEntity.this.getNavigation().isDone() && distanceSqr > 4.0D) { if (++this.stuckTicks >= 20) { - BedBugEntity.this.invalidateFoodCache(); + BedBugEntity.this.temporarilyIgnoreRottenFlesh(this.targetFood); this.targetFood = null; return; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/DiamondMinecartEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/DiamondMinecartEntity.java index c9655da6..07c22ea4 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/DiamondMinecartEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/DiamondMinecartEntity.java @@ -29,12 +29,14 @@ import org.jetbrains.annotations.Nullable; import java.util.List; public class DiamondMinecartEntity extends Minecart { + private static final long INPUT_TIMEOUT_TICKS = 5L; private static final EntityDataAccessor SYNCED_SPEED = SynchedEntityData.defineId(DiamondMinecartEntity.class, EntityDataSerializers.FLOAT); private static final EntityDataAccessor SYNCED_FACING = SynchedEntityData.defineId(DiamondMinecartEntity.class, EntityDataSerializers.INT); private byte inputFlags = 0; + private long lastInputGameTime = Long.MIN_VALUE; private float currentSpeed = 0.0F; private Direction facingDir = Direction.SOUTH; private BlockPos lastBlockPos = null; @@ -109,19 +111,38 @@ public class DiamondMinecartEntity extends Minecart { @Override protected double getMaxSpeed() { - return 0.4D; + return AntarchySettings.diamondMinecartEnabled() + ? AntarchySettings.diamondMinecartMaxSpeed() + : 0.4D; } public void onInputReceived(byte flags) { this.inputFlags = flags; + this.lastInputGameTime = this.level().getGameTime(); } @Override public void tick() { super.tick(); + if (!this.level().isClientSide) { + this.serverTick(); + } } private void serverTick() { + if (!AntarchySettings.diamondMinecartEnabled()) { + this.inputFlags = 0; + this.lastInputGameTime = Long.MIN_VALUE; + this.currentSpeed = 0.0F; + this.entityData.set(SYNCED_SPEED, 0.0F); + this.setDeltaMovement(0.0D, this.getDeltaMovement().y, 0.0D); + return; + } + + if (this.level().getGameTime() - this.lastInputGameTime > INPUT_TIMEOUT_TICKS) { + this.inputFlags = 0; + } + Player rider = this.getRidingPlayer(); boolean hasRider = rider != null; @@ -176,6 +197,17 @@ public class DiamondMinecartEntity extends Minecart { if (AntarchySettings.diamondMinecartMobDamageEnabled() && this.currentSpeed > 0.15F && hasRider) { this.applyMobCollisionDamage(); } + + this.applyControlledVelocity(); + } + + private void applyControlledVelocity() { + double speed = this.currentSpeed; + this.setDeltaMovement( + this.facingDir.getStepX() * speed, + this.getDeltaMovement().y, + this.facingDir.getStepZ() * speed + ); } private void onEnteredNewBlock(BlockPos currentPos, @Nullable Player rider) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ManticoreEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ManticoreEntity.java index 13bd6e33..0fcdb4a4 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ManticoreEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ManticoreEntity.java @@ -1,8 +1,11 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.entity.royal.QueenEntity; import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisUndersideManager; import java.util.List; import java.util.UUID; import net.minecraft.core.BlockPos; @@ -89,6 +92,11 @@ public class ManticoreEntity extends Monster implements GeoEntity { this.xpReward = 12; } + @Override + public boolean fireImmune() { + return true; + } + public static AttributeSupplier.Builder createAttributes() { return Mob.createMobAttributes() .add(Attributes.MAX_HEALTH, AntarchySettings.manticoreHealth()) @@ -206,6 +214,8 @@ public class ManticoreEntity extends Monster implements GeoEntity { return; } + this.tickQueenSummonInversionRule(); + boolean flying = !this.onGround(); if (flying != this.wasFlyingLastTick) { this.triggerAnim("controller", flying ? "fly_start" : "fly_land"); @@ -367,6 +377,24 @@ public class ManticoreEntity extends Monster implements GeoEntity { return AntarchyGravityApi.isGravityInverted(entity) ? new Vec3(0.0D, -1.0D, 0.0D) : new Vec3(0.0D, 1.0D, 0.0D); } + private void tickQueenSummonInversionRule() { + if (!this.isQueenSummoned() || this.canUseQueenSummonInversion()) { + return; + } + if (this.hasEffect(AntarchyObjects.INVERTED_EFFECT.get())) { + this.removeEffect(AntarchyObjects.INVERTED_EFFECT.get()); + } + if (AntarchyGravityApi.isGravityInverted(this) && AntarchyGravityApi.isGravityForced(this)) { + AntarchyGravityApi.setGravityDirection(this, AntarchyGravityDirection.DOWN, false); + } + this.setNoGravity(false); + } + + private boolean canUseQueenSummonInversion() { + return ThoraxisUndersideManager.isThoraxis(this.level()) + && this.getY() < ThoraxisUndersideManager.GRAVITY_FLIP_Y + 4; + } + void performSting(LivingEntity enemy) { this.swing(InteractionHand.MAIN_HAND); if (enemy.hurt(this.damageSources().mobAttack(this), (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE))) { @@ -394,6 +422,14 @@ public class ManticoreEntity extends Monster implements GeoEntity { return false; } + @Override + public boolean canBeAffected(MobEffectInstance effectInstance) { + if (this.isQueenSummoned() && effectInstance.is(AntarchyObjects.INVERTED_EFFECT.get())) { + return this.canUseQueenSummonInversion(); + } + return super.canBeAffected(effectInstance); + } + @Override public boolean isInWall() { return false; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ReverieEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ReverieEntity.java index 6ce154af..27cf6706 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ReverieEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ReverieEntity.java @@ -75,6 +75,7 @@ import software.bernie.geckolib.animation.RawAnimation; import software.bernie.geckolib.util.GeckoLibUtil; public class ReverieEntity extends PathfinderMob implements FlyingAnimal, GeoEntity { + private static final int DAMAGE_REACTION_DURATION_TICKS = 40; private static final EntityDataAccessor MOOD = SynchedEntityData.defineId(ReverieEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor ANIMATION_STATE = @@ -318,7 +319,7 @@ public class ReverieEntity extends PathfinderMob implements FlyingAnimal, GeoEnt this.releaseFocus(); this.clearNoticePlayer(); this.ambientTarget = null; - this.damageReactionTicks = 0; + this.damageReactionTicks = DAMAGE_REACTION_DURATION_TICKS; this.inversionReactionTicks = 0; this.transitionToMood(Mood.WHITE); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ScorpionEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ScorpionEntity.java index b2a6b35c..4d42ccc7 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ScorpionEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ScorpionEntity.java @@ -38,6 +38,9 @@ import net.minecraft.world.entity.monster.Monster; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import software.bernie.geckolib.animatable.GeoEntity; import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.animation.AnimatableManager; @@ -51,6 +54,10 @@ import org.jetbrains.annotations.Nullable; import java.util.UUID; public class ScorpionEntity extends Monster implements GeoEntity { + private static final ResourceKey DREAM_DUNES = ResourceKey.create( + Registries.BIOME, + ResourceLocation.fromNamespaceAndPath("antarchy", "dream_dunes") + ); private static final byte ATTACK_ANIM_EVENT = 4; private static final EntityDataAccessor TEXTURE_VARIANT = SynchedEntityData.defineId(ScorpionEntity.class, EntityDataSerializers.INT); @@ -81,6 +88,11 @@ public class ScorpionEntity extends Monster implements GeoEntity { this.xpReward = 5; } + @Override + public boolean fireImmune() { + return true; + } + public static AttributeSupplier.Builder createAttributes() { return Mob.createMobAttributes() .add(Attributes.MAX_HEALTH, AntarchySettings.scorpionHealth()) @@ -98,6 +110,12 @@ public class ScorpionEntity extends Monster implements GeoEntity { || spawnReason == MobSpawnType.COMMAND) { return true; } + // The Dream Dunes biome is the entire underside below Y=0. Its higher + // spawn weight is therefore targeted there without doubling the small + // surface-side Dream Dunes band as well. + if (pos.getY() >= 0 && level.getBiome(pos).is(DREAM_DUNES) && random.nextBoolean()) { + return false; + } if (ThoraxisUndersideManager.shouldSpawnInvertedOnDreamSand(level, pos)) { return level.getDifficulty() != Difficulty.PEACEFUL; } @@ -182,7 +200,8 @@ public class ScorpionEntity extends Monster implements GeoEntity { this.getLookControl().setLookAt(this.attackTarget, 30.0F, 30.0F); if (!this.attackDamageApplied - && this.attackAnimTicks == ATTACK_HIT_TICK + && this.attackAnimTicks > 0 + && this.attackAnimTicks <= ATTACK_HIT_TICK && this.distanceToSqr(this.attackTarget) <= this.getAttackReachSqr(this.attackTarget)) { this.attackDamageApplied = true; this.doHurtTarget(this.attackTarget); @@ -328,6 +347,10 @@ public class ScorpionEntity extends Monster implements GeoEntity { if (ScorpionEntity.this.attackTarget != null) { ScorpionEntity.this.getLookControl().setLookAt(ScorpionEntity.this.attackTarget, 30.0F, 30.0F); } + if (ScorpionEntity.this.isAttackLocked()) { + ScorpionEntity.this.getNavigation().stop(); + return; + } super.tick(); } @@ -341,8 +364,10 @@ public class ScorpionEntity extends Monster implements GeoEntity { if (ScorpionEntity.this.isAttackLocked()) { return; } - if (this.canPerformAttack(enemy) && this.isTimeToAttack() && ScorpionEntity.this.attackCooldownTicks <= 0) { - this.resetAttackCooldown(); + // Inverted melee tick handling replaces vanilla MeleeAttackGoal.tick, + // so vanilla's internal attack timer is not advanced. The Scorpion's + // own cooldown already covers its wind-up and hit timing. + if (this.canPerformAttack(enemy) && ScorpionEntity.this.attackCooldownTicks <= 0) { ScorpionEntity.this.beginAttack(enemy); return; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java index 322b3571..c671999a 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java @@ -15,6 +15,8 @@ import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.goal.FloatGoal; +import net.minecraft.world.entity.ai.goal.BreedGoal; +import net.minecraft.world.entity.ai.goal.TemptGoal; import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; import net.minecraft.world.entity.ai.goal.PanicGoal; import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal; @@ -23,6 +25,8 @@ import net.minecraft.world.entity.animal.Animal; import net.minecraft.world.entity.player.Player; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.Difficulty; @@ -86,9 +90,11 @@ public class StinkBugEntity extends Animal implements GeoEntity { protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); this.goalSelector.addGoal(1, new PanicGoal(this, 1.4D)); - this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 0.9D)); - this.goalSelector.addGoal(3, new LookAtPlayerGoal(this, Player.class, 6.0F)); - this.goalSelector.addGoal(4, new RandomLookAroundGoal(this)); + this.goalSelector.addGoal(2, new TemptGoal(this, 1.0D, Ingredient.of(Items.ROTTEN_FLESH), false)); + this.goalSelector.addGoal(3, new BreedGoal(this, 0.9D)); + this.goalSelector.addGoal(4, new WaterAvoidingRandomStrollGoal(this, 0.9D)); + this.goalSelector.addGoal(5, new LookAtPlayerGoal(this, Player.class, 6.0F)); + this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); } @Override @@ -118,7 +124,7 @@ public class StinkBugEntity extends Animal implements GeoEntity { @Override public boolean isFood(ItemStack stack) { - return false; + return stack.is(Items.ROTTEN_FLESH); } @Override diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java index 3e713c36..8d132000 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java @@ -313,7 +313,10 @@ public final class AntTeleportHelper { return new int[]{100, 200}; } if (dim == AntarchySettings.brownAntDestinationDimension()) { - return new int[]{75, 120}; + return new int[]{60, 240}; + } + if (dim == AntarchySettings.redAntDestinationDimension()) { + return new int[]{0, 220}; } return null; } @@ -328,7 +331,7 @@ public final class AntTeleportHelper { } int x = preferredPos.getX() + xOff; int z = preferredPos.getZ() + zOff; - for (int y = maxY; y >= minY + 1; y--) { + for (int y = minY + 1; y <= maxY; y++) { Vec3 safePos = tryFindSafeDismount(player, destination, new BlockPos(x, y, z)); if (safePos != null && safePos.y >= minY && safePos.y <= maxY) { return safePos; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakenEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakenEntity.java index 7e848017..22f3a19e 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakenEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/kraken/KrakenEntity.java @@ -1035,7 +1035,8 @@ public class KrakenEntity extends Monster implements GeoEntity, MultipartEntityO for (int i = 0; i < strikeBolts; i++) { this.spawnVisualLightning(serverLevel, this.getTargetStormStrikePos(target)); } - target.hurt(AntarchyDamageSources.krakenLightning(serverLevel, this), this.isPhaseTwo() ? 12.0F : 8.0F); + target.hurt(AntarchyDamageSources.krakenLightning(serverLevel, this), + this.isPhaseTwo() ? 12.0F : AntarchySettings.krakenLightningDamagePhaseOne()); } } else { this.lightningStrikeCooldown = this.isPhaseTwo() ? 30 : 60; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/portal/DimensionalTearEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/portal/DimensionalTearEntity.java index cae62d95..2e06f84e 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/portal/DimensionalTearEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/portal/DimensionalTearEntity.java @@ -1,5 +1,6 @@ package com.craisinlord.antarchy.content.entity.portal; +import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.AntarchySoundEvents; @@ -176,6 +177,13 @@ public class DimensionalTearEntity extends Entity implements GeoEntity { DimensionalTearEntity linked = this.findLinkedTear(); if (linked == null || !linked.isAlive()) { + Antarchy.LOGGER.warn( + "[antarchy-dimensional-tear] discarding unlinked tear uuid={} pos=({}, {}, {}) dim={} linkedTearId={} fallback=({}, {}, {}) ageTicks={} lifetimeTicks={}", + this.getUUID(), this.getX(), this.getY(), this.getZ(), this.level().dimension().location(), + this.linkedTearId, + this.linkedFallbackPos.x, this.linkedFallbackPos.y, this.linkedFallbackPos.z, + this.ageTicks, this.lifetimeTicks + ); this.discard(); return; } @@ -264,7 +272,7 @@ public class DimensionalTearEntity extends Entity implements GeoEntity { manticore.setTarget(target); } manticore.setDeltaMovement(this.getViewVector(1.0F).scale(0.2D).add(0.0D, 0.08D, 0.0D)); - manticore.setNoGravity(true); + manticore.setNoGravity(false); level.addFreshEntity(manticore); } } @@ -348,6 +356,7 @@ public class DimensionalTearEntity extends Entity implements GeoEntity { private void teleportEntity(Entity entity, DimensionalTearEntity destination) { Vec3 motion = entity.getDeltaMovement(); + Vec3 startPos = entity.position(); Vec3 exitPos = destination.exitPosition(); TELEPORT_COOLDOWNS.put(entity.getUUID(), this.level().getGameTime() + TELEPORT_COOLDOWN_TICKS); @@ -360,7 +369,15 @@ public class DimensionalTearEntity extends Entity implements GeoEntity { entity.setDeltaMovement(motion); entity.hasImpulse = true; if (entity instanceof LivingEntity living) { - living.addEffect(new MobEffectInstance(AntarchyObjects.INVERTED_EFFECT.get(), AntarchySettings.dimensionalTearInvertedDurationTicks(), 0)); + int invertedDuration = AntarchySettings.dimensionalTearInvertedDurationTicks(); + Antarchy.LOGGER.info( + "[antarchy-dimensional-tear] applying inverted effect targetType={} uuid={} fromTear={} toTear={} startPos=({}, {}, {}) exitPos=({}, {}, {}) dim={} durationTicks={}", + living.getType(), living.getUUID(), this.getUUID(), destination.getUUID(), + startPos.x, startPos.y, startPos.z, + exitPos.x, exitPos.y, exitPos.z, + this.level().dimension().location(), invertedDuration + ); + living.addEffect(new MobEffectInstance(AntarchyObjects.INVERTED_EFFECT.get(), invertedDuration, 0)); } this.level().playSound(null, this.blockPosition(), SoundEvents.ENDERMAN_TELEPORT, SoundSource.NEUTRAL, 0.7F, 0.65F + this.random.nextFloat() * 0.2F); } @@ -516,6 +533,16 @@ public class DimensionalTearEntity extends Entity implements GeoEntity { this.queenManticoreCount = tag.getInt("QueenManticoreCount"); this.queenManticoreSpawned = tag.getBoolean("QueenManticoreSpawned"); } + if (!this.level().isClientSide) { + Antarchy.LOGGER.info( + "[antarchy-dimensional-tear] loaded tear uuid={} pos=({}, {}, {}) dim={} linkedTearId={} fallback=({}, {}, {}) ageTicks={} lifetimeTicks={} eventTicks={} nextEventTicks={} pendingEvent={} queenOwner={} queenManticoreCount={} queenManticoreSpawned={}", + this.getUUID(), this.getX(), this.getY(), this.getZ(), this.level().dimension().location(), + this.linkedTearId, + this.linkedFallbackPos.x, this.linkedFallbackPos.y, this.linkedFallbackPos.z, + this.ageTicks, this.lifetimeTicks, this.eventTicks, this.nextEventTicks, this.pendingEvent, + this.queenOwnerId, this.queenManticoreCount, this.queenManticoreSpawned + ); + } } @Override diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java index 1da0efc6..26771fbe 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java @@ -1,6 +1,7 @@ package com.craisinlord.antarchy.content.entity.royal; import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.AntarchySoundEvents; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; @@ -35,7 +36,6 @@ import org.jetbrains.annotations.Nullable; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamSettings; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamTerrainMode; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamElement; -import com.craisinlord.antarchy.content.entity.royal.decree.AdvanceDecree; import com.craisinlord.antarchy.content.entity.royal.decree.CloseQuartersDecree; import com.craisinlord.antarchy.content.entity.royal.decree.ComeNoCloserDecree; import com.craisinlord.antarchy.content.entity.royal.decree.DoNotRunDecree; @@ -50,6 +50,7 @@ import com.craisinlord.antarchy.content.entity.royal.decree.ShowNoMercyDecree; import com.craisinlord.antarchy.content.entity.royal.decree.SkyIsMineDecree; import com.craisinlord.antarchy.content.entity.royal.decree.StandTallDecree; import com.craisinlord.antarchy.content.entity.royal.decree.StandYourGroundDecree; +import com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackLane; import java.util.EnumMap; import java.util.List; import java.util.HashMap; @@ -79,9 +80,10 @@ public class KingEntity extends RoyalBossEntity { private int decreeCooldownTicks; private int activeDecreeTicks; private int stompCooldownTicks; - private int stompWindupTicks; private int wingGustCooldownTicks; - private int wingGustWindupTicks; + private int fireballCooldownTicks = 80; + private int iceballCooldownTicks = 120; + private int iceSpikeCooldownTicks = 160; private boolean decreeRetreatPressure; private final Map judgmentCooldowns = new HashMap<>(); private final Map lastPlayerDamageTime = new HashMap<>(); @@ -91,9 +93,9 @@ public class KingEntity extends RoyalBossEntity { private RoyalDecree activeDecree; private static final List DECREES = List.of( new SkyIsMineDecree(), new DoNotRunDecree(), new KneelDecree(), new CloseQuartersDecree(), - new ComeNoCloserDecree(), new FightMeCowardDecree(), new NoRespiteDecree(), new NoRetreatDecree(), - new KeepYourDistanceDecree(), new StandTallDecree(), new StandYourGroundDecree(), - new HandsOffTheCrownDecree(), new AdvanceDecree(), new ShowNoMercyDecree()); + new ComeNoCloserDecree(), new FightMeCowardDecree(), new NoRespiteDecree(), + new StandTallDecree(), new StandYourGroundDecree(), + new HandsOffTheCrownDecree(), new ShowNoMercyDecree()); public KingEntity(EntityType entityType, Level level) { super(entityType, level); @@ -133,6 +135,11 @@ public class KingEntity extends RoyalBossEntity { return AntarchySoundEvents.KING_DEATH.get(); } + @Override + protected SoundEvent royalFlyLoopSound() { + return AntarchySoundEvents.KING_FLY_LOOP.get(); + } + @Override protected SoundEvent royalBiteSound() { return AntarchySoundEvents.KING_BITE.get(); @@ -160,7 +167,7 @@ public class KingEntity extends RoyalBossEntity { @Override protected RoyalBeamSettings royalBeamSettings() { return new RoyalBeamSettings(AntarchySettings.kingBeamRange(), AntarchySettings.kingBeamTracking(), 7.5D, - AntarchySettings.kingBeamDurationTicks(), AntarchySettings.kingBeamCooldownTicks(), 6.0F, 6.0F, + AntarchySettings.kingBeamDurationTicks(), AntarchySettings.kingBeamTravelTicks(), AntarchySettings.kingBeamCooldownTicks(), 6.0F, 6.0F, (float) AntarchySettings.kingBeamDamage(), 1.0F, 3, 100.0D, (float) AntarchySettings.kingBeamTerrainRadius(), 4.0F, AntarchySettings.kingBeamTerrainCap(), 1.0F, 0.08F, 15.0F, true, true); @@ -194,13 +201,13 @@ public class KingEntity extends RoyalBossEntity { return; } var particle = switch (head.slot()) { - case LEFT -> ParticleTypes.FLAME; + case LEFT -> null; case CENTER -> ParticleTypes.ELECTRIC_SPARK; case RIGHT -> ParticleTypes.SNOWFLAKE; }; Vec3 direction = end.subtract(start); double distance = direction.length(); - if (distance > 0.001D) { + if (particle != null && distance > 0.001D) { direction = direction.scale(1.0D / distance); for (double walked = 0.0D; walked <= distance; walked += 2.5D) { Vec3 point = start.add(direction.scale(walked)); @@ -311,7 +318,7 @@ public class KingEntity extends RoyalBossEntity { } if (this.patrolCooldownTicks-- <= 0) { this.patrolCooldownTicks = 100 + this.random.nextInt(100); - this.playSound(AntarchySoundEvents.KING_WING_FLAP.get(), 2.0F, 0.9F + this.random.nextFloat() * 0.15F); + this.playRoyalSound(AntarchySoundEvents.KING_WING_FLAP.get(), 0.9F + this.random.nextFloat() * 0.15F); double angle = this.random.nextDouble() * Math.PI * 2.0D; double radius = 12.0D + this.random.nextDouble() * 18.0D; double px = this.patrolCenter.x + Math.cos(angle) * radius; @@ -347,37 +354,41 @@ public class KingEntity extends RoyalBossEntity { } private void tickKingWholeBody(ServerLevel level, LivingEntity target) { - if (this.stompCooldownTicks > 0) this.stompCooldownTicks--; - if (this.wingGustCooldownTicks > 0) this.wingGustCooldownTicks--; - boolean skyIsMine = this.activeDecree instanceof SkyIsMineDecree; boolean forceFar = this.decreeRetreatPressure || this.activeDecree instanceof ComeNoCloserDecree || this.activeDecree instanceof KeepYourDistanceDecree; - if (this.stompWindupTicks > 0) { - if (--this.stompWindupTicks == 0) { - this.performStomp(level, target); - } - } else if (this.wingGustWindupTicks > 0) { - if (--this.wingGustWindupTicks == 0) { - this.performWingGust(level, target); - } - } else { + { double distance = target.distanceTo(this); - if (this.stompCooldownTicks <= 0 && (distance <= STOMP_RADIUS || skyIsMine)) { - this.stompCooldownTicks = skyIsMine ? STOMP_COOLDOWN_TICKS / 2 : STOMP_COOLDOWN_TICKS; - this.stompWindupTicks = STOMP_WINDUP_TICKS; - this.triggerAnim("body_action", "stomp"); - this.playSound(AntarchySoundEvents.KING_ROAR.get(), 3.0F, 0.7F); + if (this.attackScheduler.ready("stomp", RoyalAttackLane.BODY) + && (distance <= STOMP_RADIUS || skyIsMine) + && this.beginRoyalAttack("stomp", RoyalAttackLane.BODY, + skyIsMine ? STOMP_COOLDOWN_TICKS / 2 : STOMP_COOLDOWN_TICKS, + STOMP_WINDUP_TICKS, 1, 18, new com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackScheduler.Action() { + @Override public void onStart() { + KingEntity.this.triggerAnim("body_action", "stomp"); + KingEntity.this.playRoyalSound(AntarchySoundEvents.KING_ROAR.get(), 0.7F); + } + @Override public void onActive(int elapsedTicks) { + KingEntity.this.performStomp(level, target); + } + })) { if (skyIsMine) { this.getMoveControl().setWantedPosition(this.getX(), target.getY(), this.getZ(), 1.2D); } - } else if (this.wingGustCooldownTicks <= 0 && distance <= WING_GUST_RADIUS && (forceFar || this.random.nextInt(3) == 0)) { - this.wingGustCooldownTicks = WING_GUST_COOLDOWN_TICKS; - this.wingGustWindupTicks = WING_GUST_WINDUP_TICKS; - this.triggerAnim("body_action", "wing_gust"); - this.playSound(AntarchySoundEvents.KING_WING_FLAP.get(), 3.0F, 0.85F); + } else if (this.attackScheduler.ready("wing_gust", RoyalAttackLane.BODY) + && distance <= WING_GUST_RADIUS && (forceFar || this.random.nextInt(3) == 0) + && this.beginRoyalAttack("wing_gust", RoyalAttackLane.BODY, WING_GUST_COOLDOWN_TICKS, + WING_GUST_WINDUP_TICKS, 1, 16, new com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackScheduler.Action() { + @Override public void onStart() { + KingEntity.this.triggerAnim("body_action", "wing_gust"); + KingEntity.this.playRoyalSound(AntarchySoundEvents.KING_WING_FLAP.get(), 0.85F); + } + @Override public void onActive(int elapsedTicks) { + KingEntity.this.performWingGust(level, target); + } + })) { } } @@ -388,6 +399,101 @@ public class KingEntity extends RoyalBossEntity { double ay = this.groundYBelow(ax, az) + FLYING_PREFERRED_HOVER + 6.0D; this.getMoveControl().setWantedPosition(ax, ay, az, 1.3D); } + + this.tickKingElementalProjectiles(level, target); + } + + private void tickKingElementalProjectiles(ServerLevel level, LivingEntity target) { + if (this.fireballCooldownTicks > 0) this.fireballCooldownTicks--; + if (this.iceballCooldownTicks > 0) this.iceballCooldownTicks--; + if (this.iceSpikeCooldownTicks > 0) this.iceSpikeCooldownTicks--; + + double distance = this.distanceTo(target); + String[] candidates = {"fireball", "iceball", "ice_spikes"}; + String selected = this.attackScheduler.chooseWeighted(candidates, id -> { + boolean ready = switch (id) { + case "fireball" -> distance >= 14.0D && distance <= 48.0D && this.fireballCooldownTicks <= 0 + && this.royalHead(RoyalHead.Slot.LEFT).readyToAttack(); + case "iceball" -> distance >= 10.0D && distance <= 42.0D && this.iceballCooldownTicks <= 0 + && this.royalHead(RoyalHead.Slot.RIGHT).readyToAttack(); + default -> distance <= 36.0D && this.iceSpikeCooldownTicks <= 0 + && this.royalHead(RoyalHead.Slot.RIGHT).readyToAttack(); + }; + if (!ready) return 0; + return switch (id) { + case "fireball" -> this.behaviorScore(Behavior.KEEPING_FAR) + 4; + case "iceball" -> this.behaviorScore(Behavior.RETREATING) + 4; + default -> this.behaviorScore(Behavior.HUGGING) + 3; + }; + }, this.random); + if (selected == null) return; + if ("fireball".equals(selected)) { + if (!this.beginRoyalAttack("fireball", RoyalAttackLane.LEFT_HEAD, + AntarchySettings.kingFireballCooldownTicks(), 14, 1, 5, + new com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackScheduler.Action() { + @Override public void onStart() { + KingEntity.this.triggerAnim(RoyalHead.Slot.LEFT.controllerName(), "shoot"); + } + @Override public void onActive(int elapsedTicks) { + Vec3 origin = KingEntity.this.headAnchor(KingEntity.this.royalHead(RoyalHead.Slot.LEFT)); + Vec3 predicted = target.position().add(target.getDeltaMovement().scale(10.0D)); + Vec3 direction = predicted.add(0.0D, target.getBbHeight() * 0.5D, 0.0D).subtract(origin).normalize(); + RoyalElementalProjectileEntity fireball = RoyalElementalProjectileEntity.create(level, KingEntity.this, + RoyalBeamElement.FIRE, origin, direction); + level.addFreshEntity(fireball); + KingEntity.this.playRoyalSound(AntarchySoundEvents.KING_FIREBALL_SHOOT.get(), 0.9F); + } + })) return; + this.fireballCooldownTicks = AntarchySettings.kingFireballCooldownTicks(); + } else if ("iceball".equals(selected)) { + if (!this.beginRoyalAttack("iceball", RoyalAttackLane.RIGHT_HEAD, + AntarchySettings.kingIceballCooldownTicks(), 16, 1, 5, + new com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackScheduler.Action() { + @Override public void onStart() { + KingEntity.this.triggerAnim(RoyalHead.Slot.RIGHT.controllerName(), "shoot"); + } + @Override public void onActive(int elapsedTicks) { + Vec3 origin = KingEntity.this.headAnchor(KingEntity.this.royalHead(RoyalHead.Slot.RIGHT)); + Vec3 direction = target.getEyePosition().subtract(origin).normalize(); + RoyalElementalProjectileEntity iceball = RoyalElementalProjectileEntity.create(level, KingEntity.this, + RoyalBeamElement.ICE, origin, direction); + level.addFreshEntity(iceball); + KingEntity.this.playRoyalSound(AntarchySoundEvents.KING_BEAM_SHOOT.get(), 1.2F); + } + })) return; + this.iceballCooldownTicks = AntarchySettings.kingIceballCooldownTicks(); + } else { + if (!this.beginRoyalAttack("ice_spikes", RoyalAttackLane.RIGHT_HEAD, + AntarchySettings.kingIceSpikeCooldownTicks(), 20, 1, 5, + new com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackScheduler.Action() { + @Override public void onStart() { + KingEntity.this.triggerAnim(RoyalHead.Slot.RIGHT.controllerName(), "shoot"); + } + @Override public void onActive(int elapsedTicks) { + KingEntity.this.raiseIceSpikes(level, target); + KingEntity.this.playRoyalSound(AntarchySoundEvents.KING_BEAM_SHOOT.get(), 0.8F); + } + })) return; + this.iceSpikeCooldownTicks = AntarchySettings.kingIceSpikeCooldownTicks(); + } + } + + private void raiseIceSpikes(ServerLevel level, LivingEntity target) { + Vec3 start = this.position(); + Vec3 end = target.position(); + Vec3 line = end.subtract(start).multiply(1.0D, 0.0D, 1.0D); + if (line.lengthSqr() < 1.0E-4D) return; + line = line.normalize(); + Vec3 side = new Vec3(-line.z, 0.0D, line.x); + for (int i = 1; i <= 5; i++) { + double distance = i * 4.0D; + for (int lane = -1; lane <= 1; lane++) { + Vec3 point = start.add(line.scale(distance)).add(side.scale(lane * (i % 2 == 0 ? 2.0D : 0.0D))); + double y = this.groundYBelow(point.x, point.z) + 0.1D; + RoyalIceSpikeEntity spike = RoyalIceSpikeEntity.create(level, new Vec3(point.x, y, point.z)); + level.addFreshEntity(spike); + } + } } private void performStomp(ServerLevel level, LivingEntity target) { @@ -406,7 +512,7 @@ public class KingEntity extends RoyalBossEntity { RoyalBlockDestruction.destroySphere(level, this, new Vec3(this.getX(), this.getY(), this.getZ()), STOMP_RADIUS * 0.5D, 96, 80.0D, 0.15F); level.sendParticles(ParticleTypes.EXPLOSION_EMITTER, this.getX(), this.getY(), this.getZ(), 6, 4.0D, 0.5D, 4.0D, 0.0D); - this.playSound(AntarchySoundEvents.KING_STOMP.get(), 3.5F, 0.8F); + this.playRoyalSound(AntarchySoundEvents.KING_STOMP.get(), 0.8F); } private void performWingGust(ServerLevel level, LivingEntity target) { @@ -434,11 +540,15 @@ public class KingEntity extends RoyalBossEntity { if (this.decreeCooldownTicks-- > 0) { return; } + if (!this.beginRoyalAttack("decree", RoyalAttackLane.DECREE, + AntarchySettings.royalDecreeCooldownTicks(), 300)) { + return; + } this.activeDecreeTicks = 300; this.activeDecree = this.pickDecree(target); this.decreeRetreatPressure = false; - this.playSound(AntarchySoundEvents.KING_DECREE_CAST.get(), 3.0F, 0.9F + this.random.nextFloat() * 0.15F); - this.playSound(AntarchySoundEvents.KING_ROAR.get(), 3.0F, 0.8F + this.random.nextFloat() * 0.12F); + this.playRoyalSound(AntarchySoundEvents.KING_DECREE_CAST.get(), 0.9F + this.random.nextFloat() * 0.15F); + this.playRoyalSound(AntarchySoundEvents.KING_ROAR.get(), 0.8F + this.random.nextFloat() * 0.12F); if (target instanceof ServerPlayer player) { player.connection.send(new ClientboundSetTitlesAnimationPacket(5, 300, 10)); player.connection.send(new ClientboundSetTitleTextPacket(Component.translatable(this.activeDecree.translationKey()) @@ -452,6 +562,11 @@ public class KingEntity extends RoyalBossEntity { level.playSound(null, target.blockPosition(), SoundEvents.BELL_BLOCK, SoundSource.HOSTILE, 0.8F, 1.0F + countdown / 500.0F); } this.activeDecree.apply(level, this, target); + if (this.activeDecree != null + && this.activeDecree.evaluate(level, this, target) == RoyalDecree.Evaluation.VIOLATED) { + this.failActiveDecree(target); + return; + } if (this.activeDecree != null && --this.activeDecreeTicks <= 0) { this.endDecree(target); } @@ -495,6 +610,15 @@ public class KingEntity extends RoyalBossEntity { this.endDecree(target); } + /** Resolves a decree violation once, using the existing bounded judgment while the new judgment system is pending. */ + public void failActiveDecree(@Nullable LivingEntity target) { + if (this.activeDecree == null || target == null || !target.isAlive()) { + return; + } + this.invokeJudgment(target); + this.endDecree(target); + } + public boolean blocksHealing() { return this.activeDecree instanceof NoRespiteDecree; } @@ -520,11 +644,11 @@ public class KingEntity extends RoyalBossEntity { boolean projectile = source.getDirectEntity() instanceof Projectile; this.bumpBehavior(projectile ? Behavior.RANGED : Behavior.HUGGING, 2); if (this.activeDecree instanceof CloseQuartersDecree && projectile) { - this.invokeJudgment(attacker); + this.failActiveDecree(attacker); } else if (this.activeDecree instanceof ComeNoCloserDecree && !projectile) { - this.invokeJudgment(attacker); + this.failActiveDecree(attacker); } else if (this.activeDecree instanceof HandsOffTheCrownDecree) { - this.invokeJudgment(attacker); + this.failActiveDecree(attacker); } } return super.hurt(source, amount); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java index c1fc60d1..c10e2da1 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java @@ -30,6 +30,8 @@ import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamSettings; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamTerrainMode; +import com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackLane; +import com.craisinlord.antarchy.content.entity.royal.attack.RoyalEffectController; import com.craisinlord.antarchy.content.entity.portal.DimensionalTearEntity; import com.craisinlord.antarchy.content.time.TimeDilationApi; import net.minecraft.world.damagesource.DamageSource; @@ -61,13 +63,12 @@ public class QueenEntity extends RoyalBossEntity { private int gravityStompCooldownTicks; private int timeFieldCooldownTicks; private int momentumLockCooldownTicks; - private int momentumLockTicks; private int crushingGravityCooldownTicks; - private int crushingGravityTicks; private int accelerationCooldownTicks; - private int accelerationTicks; private int blackHoleCooldownTicks; private int idleWanderCooldownTicks; + private int finalTimeControlTicks; + private final RoyalEffectController royalEffects = new RoyalEffectController(); private final Map frozenVelocities = new HashMap<>(); public QueenEntity(EntityType entityType, Level level) { @@ -85,7 +86,12 @@ public class QueenEntity extends RoyalBossEntity { @Override protected boolean isFlyingBoss() { - return false; + return true; + } + + @Override + protected SoundEvent royalFlyLoopSound() { + return AntarchySoundEvents.QUEEN_FLY_LOOP.get(); } @Override @@ -128,7 +134,7 @@ public class QueenEntity extends RoyalBossEntity { @Override protected RoyalBeamSettings royalBeamSettings() { return new RoyalBeamSettings(AntarchySettings.queenBeamRange(), AntarchySettings.queenBeamTracking(), 7.5D, - AntarchySettings.queenBeamDurationTicks(), AntarchySettings.queenBeamCooldownTicks(), 6.0F, 6.0F, + AntarchySettings.queenBeamDurationTicks(), AntarchySettings.queenBeamTravelTicks(), AntarchySettings.queenBeamCooldownTicks(), 6.0F, 6.0F, (float) AntarchySettings.queenBeamDamage(), 1.0F, 3, 100.0D, (float) AntarchySettings.queenBeamTerrainRadius(), 4.0F, AntarchySettings.queenBeamTerrainCap(), 1.0F, 0.08F, 15.0F, true, true); @@ -156,9 +162,8 @@ public class QueenEntity extends RoyalBossEntity { } this.tickManticoreSummon(); this.tickQueenAbilities(); - this.tickRoyalAcceleration(); - this.tickMomentumLock(); - this.tickCrushingGravity(); + this.tickFinalTimeControl(); + this.royalEffects.tick(); } private void tickIdleWander() { @@ -174,7 +179,7 @@ public class QueenEntity extends RoyalBossEntity { } private int cooldown(int base) { - return this.accelerationTicks > 0 ? Math.max(20, base / 2) : base; + return this.royalEffects.active("acceleration") ? Math.max(20, base / 2) : base; } private void tickManticoreSummon() { @@ -205,7 +210,7 @@ public class QueenEntity extends RoyalBossEntity { : FAILED_SUMMON_RETRY_TICKS; if (spawned > 0) { this.triggerAnim("body_action", "minion_spawn"); - this.playSound(AntarchySoundEvents.QUEEN_ROAR.get(), 3.0F, 0.8F + this.random.nextFloat() * 0.12F); + this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 0.8F + this.random.nextFloat() * 0.12F); serverLevel.sendParticles(ParticleTypes.PORTAL, this.getX(), this.getY() + 2.0D, this.getZ(), 36, 3.0D, 2.0D, 3.0D, 0.15D); } @@ -249,40 +254,97 @@ public class QueenEntity extends RoyalBossEntity { } Phase phase = this.phase(); - boolean majorBusy = this.momentumLockTicks > 0 || this.crushingGravityTicks > 0; + boolean majorBusy = this.royalEffects.active("momentum_lock") || this.royalEffects.active("crushing_gravity"); boolean allowOverlap = phase != Phase.ONE; + String[] candidates = phase == Phase.ONE + ? new String[] {"gravity_stomp", "time_field", "black_hole"} + : new String[] {"gravity_stomp", "time_field", "black_hole", "momentum_lock", "crushing_gravity", "acceleration"}; + String selected = this.attackScheduler.chooseWeighted(candidates, id -> { + if (!this.queenAttackReady(id, phase, majorBusy, allowOverlap)) return 0; + return switch (id) { + case "black_hole", "crushing_gravity" -> phase == Phase.THREE ? 5 : 3; + case "momentum_lock", "acceleration" -> phase == Phase.THREE ? 4 : 2; + default -> 4; + }; + }, this.random); + if (selected == null) return; + int cooldown = switch (selected) { + case "gravity_stomp" -> GRAVITY_STOMP_COOLDOWN; + case "time_field" -> TIME_FIELD_COOLDOWN; + case "black_hole" -> BLACK_HOLE_COOLDOWN; + case "momentum_lock" -> MOMENTUM_LOCK_COOLDOWN; + case "crushing_gravity" -> CRUSHING_GRAVITY_COOLDOWN; + default -> ACCELERATION_COOLDOWN; + }; + if (!this.beginRoyalAttack(selected, RoyalAttackLane.HAZARD, this.cooldown(cooldown), + 10, 1, 14, new com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackScheduler.Action() { + @Override public void onStart() { + if ("gravity_stomp".equals(selected)) { + QueenEntity.this.triggerAnim("body_action", "stomp"); + } else { + QueenEntity.this.triggerAnim("body_action", "wing_gust"); + } + } + @Override public void onActive(int elapsedTicks) { + QueenEntity.this.performSelectedQueenAttack(selected, phase, cooldown, level, target); + } + })) return; + } - if (this.gravityStompCooldownTicks <= 0 && (allowOverlap || !majorBusy)) { - this.gravityStompCooldownTicks = this.cooldown(GRAVITY_STOMP_COOLDOWN); - this.performGravityStomp(level, target); + private void performSelectedQueenAttack(String selected, Phase phase, int cooldown, + ServerLevel level, LivingEntity target) { + switch (selected) { + case "gravity_stomp" -> { this.gravityStompCooldownTicks = cooldown; this.performGravityStomp(level, target); } + case "time_field" -> { + this.timeFieldCooldownTicks = cooldown; + double fieldRate = phase == Phase.THREE ? 0.1D : 0.4D; + TimeDilationApi.createField(level, target.position(), 12.0D, fieldRate, 140 + phase.ordinal() * 40); + } + case "black_hole" -> { this.blackHoleCooldownTicks = cooldown; this.castBlackHole(level, target); } + case "momentum_lock" -> { this.momentumLockCooldownTicks = cooldown; this.startMomentumLock(level); } + case "crushing_gravity" -> { + this.crushingGravityCooldownTicks = cooldown; + this.royalEffects.start("crushing_gravity", CRUSHING_GRAVITY_DURATION, + () -> {}, this::tickCrushingGravity, () -> {}); + this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 0.6F); + } + case "acceleration" -> { this.accelerationCooldownTicks = cooldown; this.startRoyalAcceleration(); } } - if (this.timeFieldCooldownTicks <= 0 && (allowOverlap || !majorBusy)) { - this.timeFieldCooldownTicks = this.cooldown(TIME_FIELD_COOLDOWN); - double fieldRate = phase == Phase.THREE ? 0.1D : 0.4D; - TimeDilationApi.createField(level, target.position(), 12.0D, fieldRate, 140 + phase.ordinal() * 40); - this.triggerAnim("body_action", "wing_gust"); + } + + private boolean queenAttackReady(String id, Phase phase, boolean majorBusy, boolean allowOverlap) { + if (!allowOverlap && majorBusy) return false; + return switch (id) { + case "gravity_stomp" -> this.gravityStompCooldownTicks <= 0; + case "time_field" -> this.timeFieldCooldownTicks <= 0; + case "black_hole" -> this.blackHoleCooldownTicks <= 0; + case "momentum_lock" -> !this.royalEffects.active("momentum_lock") && this.momentumLockCooldownTicks <= 0; + case "crushing_gravity" -> phase != Phase.ONE && !this.royalEffects.active("crushing_gravity") && this.crushingGravityCooldownTicks <= 0; + case "acceleration" -> phase == Phase.THREE && !this.royalEffects.active("acceleration") && this.accelerationCooldownTicks <= 0; + default -> false; + }; + } + + private void tickFinalTimeControl() { + if (this.phase() != Phase.THREE || !(this.level() instanceof ServerLevel level)) { + return; } - if (this.blackHoleCooldownTicks <= 0 && (allowOverlap || !majorBusy)) { - this.blackHoleCooldownTicks = this.cooldown(BLACK_HOLE_COOLDOWN); - this.castBlackHole(level, target); - } - if (this.momentumLockTicks <= 0 && this.momentumLockCooldownTicks <= 0 && (allowOverlap || !majorBusy)) { - this.startMomentumLock(level); - } - if (this.crushingGravityTicks <= 0 && this.crushingGravityCooldownTicks <= 0 && phase != Phase.ONE) { - this.crushingGravityCooldownTicks = CRUSHING_GRAVITY_COOLDOWN; - this.crushingGravityTicks = CRUSHING_GRAVITY_DURATION; - this.playSound(AntarchySoundEvents.QUEEN_ROAR.get(), 3.0F, 0.6F); - } - if (this.accelerationTicks <= 0 && this.accelerationCooldownTicks <= 0 - && (phase == Phase.THREE || (phase == Phase.TWO && this.random.nextInt(3) == 0))) { + if (!this.royalEffects.active("acceleration") && this.accelerationCooldownTicks <= 0) { this.startRoyalAcceleration(); } + if (this.finalTimeControlTicks-- <= 0) { + this.finalTimeControlTicks = AntarchySettings.queenFinalTimeFieldCooldownTicks(); + LivingEntity target = this.getTarget(); + if (target != null && target.isAlive()) { + TimeDilationApi.createField(level, target.position(), AntarchySettings.queenFinalTimeFieldRadius(), + AntarchySettings.queenFinalTimeFieldRate(), AntarchySettings.queenFinalTimeFieldDurationTicks()); + } + } } private void performGravityStomp(ServerLevel level, LivingEntity target) { this.triggerAnim("body_action", "stomp"); - this.playSound(AntarchySoundEvents.QUEEN_ROAR.get(), 3.0F, 0.7F); + this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 0.7F); DamageSource source = this.damageSources().mobAttack(this); for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class, this.getBoundingBox().inflate(18.0D), entity -> entity instanceof Player && entity.isAlive())) { @@ -303,30 +365,36 @@ public class QueenEntity extends RoyalBossEntity { RoyalBlackHoleEntity hole = RoyalBlackHoleEntity.create(level, anchor, this.getUUID()); level.addFreshEntity(hole); this.triggerAnim("body_action", "wing_gust"); - this.playSound(AntarchySoundEvents.QUEEN_ROAR.get(), 3.0F, 1.15F); + this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 1.0F); level.sendParticles(ParticleTypes.REVERSE_PORTAL, anchor.x, anchor.y, anchor.z, 60, 1.0D, 1.0D, 1.0D, 0.4D); } private void startMomentumLock(ServerLevel level) { this.momentumLockCooldownTicks = MOMENTUM_LOCK_COOLDOWN; - this.momentumLockTicks = MOMENTUM_LOCK_DURATION; - this.frozenVelocities.clear(); - this.triggerAnim("body_action", "wing_gust"); - this.playSound(AntarchySoundEvents.QUEEN_ROAR.get(), 3.0F, 0.5F); - for (Entity entity : level.getEntitiesOfClass(Entity.class, - this.getBoundingBox().inflate(MOMENTUM_LOCK_RADIUS))) { - if (entity == this || isFieldImmune(entity) || entity instanceof Player player && player.isCreative()) { - continue; + this.royalEffects.start("momentum_lock", MOMENTUM_LOCK_DURATION, () -> { + this.frozenVelocities.clear(); + for (Entity entity : level.getEntitiesOfClass(Entity.class, + this.getBoundingBox().inflate(MOMENTUM_LOCK_RADIUS))) { + if (entity == this || isFieldImmune(entity) || entity instanceof Player player && player.isCreative()) { + continue; + } + this.frozenVelocities.put(entity.getUUID(), entity.getDeltaMovement()); } - this.frozenVelocities.put(entity.getUUID(), entity.getDeltaMovement()); - } + }, this::tickMomentumLockEffect, () -> { + for (Map.Entry entry : this.frozenVelocities.entrySet()) { + Entity entity = level.getEntity(entry.getKey()); + if (entity != null && entity.isAlive()) { + entity.setDeltaMovement(entry.getValue()); + entity.hasImpulse = true; + } + } + this.frozenVelocities.clear(); + }); + this.triggerAnim("body_action", "wing_gust"); + this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 0.5F); } - private void tickMomentumLock() { - if (this.momentumLockTicks <= 0) { - return; - } - this.momentumLockTicks--; + private void tickMomentumLockEffect() { if (!(this.level() instanceof ServerLevel level)) { return; } @@ -335,29 +403,20 @@ public class QueenEntity extends RoyalBossEntity { if (entity == null || !entity.isAlive()) { continue; } - if (this.momentumLockTicks <= 0) { - entity.setDeltaMovement(entry.getValue()); - entity.hasImpulse = true; - } else { - entity.setDeltaMovement(Vec3.ZERO); - entity.fallDistance = 0.0F; - entity.hasImpulse = true; - if (this.tickCount % 6 == 0 && level instanceof ServerLevel serverLevel) { - serverLevel.sendParticles(ParticleTypes.END_ROD, entity.getX(), entity.getY() + entity.getBbHeight() * 0.5D, entity.getZ(), - 2, 0.2D, 0.2D, 0.2D, 0.0D); - } + entity.setDeltaMovement(Vec3.ZERO); + entity.fallDistance = 0.0F; + entity.hasImpulse = true; + if (this.tickCount % 6 == 0) { + level.sendParticles(ParticleTypes.END_ROD, entity.getX(), entity.getY() + entity.getBbHeight() * 0.5D, entity.getZ(), + 2, 0.2D, 0.2D, 0.2D, 0.0D); } } - if (this.momentumLockTicks <= 0) { - this.frozenVelocities.clear(); - } } private void tickCrushingGravity() { - if (this.crushingGravityTicks <= 0) { + if (!this.royalEffects.active("crushing_gravity")) { return; } - this.crushingGravityTicks--; if (!(this.level() instanceof ServerLevel level)) { return; } @@ -378,11 +437,16 @@ public class QueenEntity extends RoyalBossEntity { private void startRoyalAcceleration() { this.accelerationCooldownTicks = ACCELERATION_COOLDOWN; - this.accelerationTicks = ACCELERATION_DURATION; - this.setRoyalAccelerated(true); - this.playSound(AntarchySoundEvents.QUEEN_ROAR.get(), 3.5F, 1.4F); - applyAccelModifier(this.getAttribute(Attributes.MOVEMENT_SPEED), ACCEL_SPEED_ID); - applyAccelModifier(this.getAttribute(Attributes.FLYING_SPEED), ACCEL_FLY_ID); + this.royalEffects.start("acceleration", ACCELERATION_DURATION, () -> { + this.setRoyalAccelerated(true); + this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 1.4F); + applyAccelModifier(this.getAttribute(Attributes.MOVEMENT_SPEED), ACCEL_SPEED_ID); + applyAccelModifier(this.getAttribute(Attributes.FLYING_SPEED), ACCEL_FLY_ID); + }, this::tickRoyalAccelerationEffect, () -> { + this.setRoyalAccelerated(false); + removeAccelModifier(this.getAttribute(Attributes.MOVEMENT_SPEED), ACCEL_SPEED_ID); + removeAccelModifier(this.getAttribute(Attributes.FLYING_SPEED), ACCEL_FLY_ID); + }); } private static void applyAccelModifier(AttributeInstance attribute, ResourceLocation id) { @@ -398,16 +462,10 @@ public class QueenEntity extends RoyalBossEntity { } } - private void tickRoyalAcceleration() { - if (this.accelerationTicks <= 0) { - if (this.isRoyalAccelerated()) { - this.setRoyalAccelerated(false); - removeAccelModifier(this.getAttribute(Attributes.MOVEMENT_SPEED), ACCEL_SPEED_ID); - removeAccelModifier(this.getAttribute(Attributes.FLYING_SPEED), ACCEL_FLY_ID); - } + private void tickRoyalAccelerationEffect() { + if (!this.isRoyalAccelerated()) { return; } - this.accelerationTicks--; if (this.level() instanceof ServerLevel level && this.tickCount % 2 == 0) { level.sendParticles(ACCEL_DUST, this.getX() + (this.random.nextDouble() - 0.5D) * this.getBbWidth(), @@ -415,11 +473,6 @@ public class QueenEntity extends RoyalBossEntity { this.getZ() + (this.random.nextDouble() - 0.5D) * this.getBbWidth(), 6, 0.4D, 0.6D, 0.4D, 0.02D); } - if (this.accelerationTicks <= 0) { - this.setRoyalAccelerated(false); - removeAccelModifier(this.getAttribute(Attributes.MOVEMENT_SPEED), ACCEL_SPEED_ID); - removeAccelModifier(this.getAttribute(Attributes.FLYING_SPEED), ACCEL_FLY_ID); - } } @Override @@ -427,6 +480,8 @@ public class QueenEntity extends RoyalBossEntity { if (!this.level().isClientSide && this.level() instanceof ServerLevel level) { DimensionalTearEntity.discardQueenOwnedTears(level, this.getUUID()); } + this.royalEffects.clear(); + this.frozenVelocities.clear(); removeAccelModifier(this.getAttribute(Attributes.MOVEMENT_SPEED), ACCEL_SPEED_ID); removeAccelModifier(this.getAttribute(Attributes.FLYING_SPEED), ACCEL_FLY_ID); super.die(damageSource); @@ -468,8 +523,6 @@ public class QueenEntity extends RoyalBossEntity { tag.putInt(SUMMON_COOLDOWN_KEY, this.manticoreSummonCooldownTicks); tag.putInt("GravityStompCooldownTicks", this.gravityStompCooldownTicks); tag.putInt("TimeFieldCooldownTicks", this.timeFieldCooldownTicks); - tag.putInt("MomentumLockCooldownTicks", this.momentumLockCooldownTicks); - tag.putInt("CrushingGravityCooldownTicks", this.crushingGravityCooldownTicks); tag.putInt("AccelerationCooldownTicks", this.accelerationCooldownTicks); tag.putInt("BlackHoleCooldownTicks", this.blackHoleCooldownTicks); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBlackHoleEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBlackHoleEntity.java index 3d69918d..d30b2ed4 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBlackHoleEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBlackHoleEntity.java @@ -1,6 +1,8 @@ package com.craisinlord.antarchy.content.entity.royal; import com.craisinlord.antarchy.content.AntarchyObjects; +import com.craisinlord.antarchy.content.time.TimeDilationApi; +import com.craisinlord.antarchy.config.AntarchySettings; import java.util.UUID; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; @@ -17,8 +19,16 @@ import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; +import software.bernie.geckolib.animatable.GeoEntity; +import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.animation.AnimatableManager; +import software.bernie.geckolib.animation.AnimationController; +import software.bernie.geckolib.animation.AnimationState; +import software.bernie.geckolib.animation.PlayState; +import software.bernie.geckolib.animation.RawAnimation; +import software.bernie.geckolib.util.GeckoLibUtil; -public class RoyalBlackHoleEntity extends Entity { +public class RoyalBlackHoleEntity extends Entity implements GeoEntity { private static final EntityDataAccessor RADIUS = SynchedEntityData.defineId(RoyalBlackHoleEntity.class, EntityDataSerializers.FLOAT); private static final EntityDataAccessor COLLAPSING = @@ -36,6 +46,7 @@ public class RoyalBlackHoleEntity extends Entity { private UUID ownerId; private int age; private int activeTicks = DEFAULT_ACTIVE_TICKS; + private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); public RoyalBlackHoleEntity(EntityType entityType, Level level) { super(entityType, level); @@ -46,14 +57,14 @@ public class RoyalBlackHoleEntity extends Entity { public static RoyalBlackHoleEntity create(ServerLevel level, Vec3 center, double radius, int activeTicks, @Nullable UUID ownerId) { RoyalBlackHoleEntity hole = new RoyalBlackHoleEntity(AntarchyObjects.ROYAL_BLACK_HOLE.get(), level); hole.setPos(center.x, center.y, center.z); - hole.setRadius(radius); - hole.activeTicks = Math.max(20, activeTicks); + hole.setRadius(radius > 0.0D ? radius : AntarchySettings.queenBlackHoleRadius()); + hole.activeTicks = activeTicks > 0 ? Math.max(20, activeTicks) : AntarchySettings.queenBlackHoleActiveTicks(); hole.ownerId = ownerId; return hole; } public static RoyalBlackHoleEntity create(ServerLevel level, Vec3 center, @Nullable UUID ownerId) { - return create(level, center, DEFAULT_RADIUS, DEFAULT_ACTIVE_TICKS, ownerId); + return create(level, center, AntarchySettings.queenBlackHoleRadius(), AntarchySettings.queenBlackHoleActiveTicks(), ownerId); } @Override @@ -84,6 +95,12 @@ public class RoyalBlackHoleEntity extends Entity { this.age++; if (!this.isCollapsing()) { this.applyPull(); + if (this.age % 10 == 0 && this.level() instanceof ServerLevel level) { + TimeDilationApi.createField(level, this.position(), Math.max(2.0D, this.radius() * 0.55D), 0.18D, 14); + if (this.age % 20 == 0 && level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { + RoyalBlockDestruction.destroySphere(level, this, this.position(), Math.min(2.0D, this.radius() * 0.2D), 8, 30.0D, 0.0F); + } + } if (this.age >= this.activeTicks) { this.entityData.set(COLLAPSING, true); this.age = 0; @@ -108,7 +125,7 @@ public class RoyalBlackHoleEntity extends Entity { if (distance < 0.5D || distance > radius) { continue; } - double strength = 0.16D * (1.0D - distance / radius); + double strength = AntarchySettings.queenBlackHolePullStrength() * (1.0D - distance / radius); Vec3 pull = toCenter.scale(strength / distance); entity.setDeltaMovement(entity.getDeltaMovement().scale(0.86D).add(pull)); entity.hasImpulse = true; @@ -201,4 +218,18 @@ public class RoyalBlackHoleEntity extends Entity { tag.putUUID(OWNER_KEY, this.ownerId); } } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { + controllers.add(new AnimationController<>(this, "black_hole_controller", 0, this::blackHoleController)); + } + + private PlayState blackHoleController(AnimationState state) { + return state.setAndContinue(RawAnimation.begin().thenLoop("animation")); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.geoCache; + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java index 78f9d030..dafad45f 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java @@ -8,6 +8,10 @@ import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamController; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamSettings; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamTerrainMode; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamElement; +import com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackLane; +import com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackScheduler; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisUndersideManager; import java.util.List; import net.minecraft.network.chat.Component; import net.minecraft.network.syncher.EntityDataAccessor; @@ -89,6 +93,11 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private static final int CRUSH_MAX_BLOCKS = 24; private static final double CRUSH_MAX_RESISTANCE = 60.0D; private static final float CRUSH_DROP_CHANCE = 0.1F; + private static final int OBSTRUCTION_CLEAR_INTERVAL_TICKS = 5; + private static final double OBSTRUCTION_CLEAR_RADIUS = 3.5D; + private static final int OBSTRUCTION_CLEAR_MAX_BLOCKS = 24; + private static final double OBSTRUCTION_CLEAR_MAX_RESISTANCE = 60.0D; + private static final float OBSTRUCTION_CLEAR_DROP_CHANCE = 0.1F; protected static final double FLYING_MIN_HOVER = 2.5D; protected static final double FLYING_PREFERRED_HOVER = 6.0D; @@ -116,6 +125,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); protected final RoyalBeamController beamController = new RoyalBeamController(this); + protected final RoyalAttackScheduler attackScheduler = new RoyalAttackScheduler(); private final ServerBossEvent bossEvent; private final RoyalHead[] heads = { new RoyalHead(RoyalHead.Slot.LEFT), @@ -127,6 +137,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private RoyalHead activeBeamHead; private int beamLoopSoundTicks; private int beamHeadCursor; + private boolean beamStarted; @Nullable private Entity[] multipartParts; @@ -152,6 +163,11 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult protected abstract SoundEvent royalDeathSound(); + @Nullable + protected SoundEvent royalFlyLoopSound() { + return null; + } + protected abstract SoundEvent royalBiteSound(); protected abstract SoundEvent royalBeamShootSound(); @@ -275,7 +291,11 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult @Override protected float getSoundVolume() { - return 2.5F; + return (float) AntarchySettings.royalBossSoundVolume(); + } + + protected void playRoyalSound(SoundEvent sound, float pitch) { + this.playSound(sound, (float) AntarchySettings.royalBossSoundVolume(), pitch); } @Override @@ -292,8 +312,21 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult @Override public void tick() { super.tick(); + if (!this.level().isClientSide + && !this.isDeadOrDying() + && this.tickCount % OBSTRUCTION_CLEAR_INTERVAL_TICKS == 0 + && this.isInWall()) { + RoyalBlockDestruction.destroySphere( + (ServerLevel) this.level(), + this, + this.position().add(0.0D, this.getBbHeight() * 0.5D, 0.0D), + OBSTRUCTION_CLEAR_RADIUS, + OBSTRUCTION_CLEAR_MAX_BLOCKS, + OBSTRUCTION_CLEAR_MAX_RESISTANCE, + OBSTRUCTION_CLEAR_DROP_CHANCE); + } if (this.isFlyingBoss()) { - this.setNoGravity(true); + this.setNoGravity(!AntarchyGravityApi.isGravityInverted(this)); } if (this.level().isClientSide) { return; @@ -303,9 +336,10 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth()); + this.attackScheduler.tick(); - for (RoyalHead head : this.heads) { - head.tick(); + if (this.isFlyingBoss() && this.tickCount % 40 == 0 && this.royalFlyLoopSound() != null) { + this.playRoyalSound(this.royalFlyLoopSound(), 0.92F + this.random.nextFloat() * 0.12F); } if (this.isDeadOrDying()) { @@ -326,16 +360,10 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult this.steerTowardTarget(primaryTarget); this.tickBodyCrush(); - for (RoyalHead head : this.heads) { - if (head.tickBiteHit()) { - this.applyBiteHit(head); - } - } - Phase phase = this.phase(); int activeHeadAttacks = 0; for (RoyalHead head : this.heads) { - if (head.busy()) { + if (this.attackScheduler.laneBusy(this.headLane(head))) { activeHeadAttacks++; } } @@ -344,7 +372,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult if (activeHeadAttacks >= phase.maxConcurrentHeadAttacks()) { break; } - if (!head.readyToAttack()) { + if (!head.readyToAttack() || this.attackScheduler.laneBusy(this.headLane(head))) { continue; } LivingEntity headTarget = head.target(this.level()); @@ -355,8 +383,14 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } } + @Override + public boolean isInvulnerableTo(DamageSource source) { + return source.is(net.minecraft.world.damagesource.DamageTypes.IN_WALL) + || super.isInvulnerableTo(source); + } + private void tickRoyalBeam(LivingEntity primaryTarget) { - if (this.beamCooldownTicks > 0) { + if (this.beamCooldownTicks > 0 || this.attackScheduler.laneBusy(this.beamLane())) { this.beamCooldownTicks--; } @@ -364,10 +398,12 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult LivingEntity beamTarget = this.activeBeamHead.target(this.level()); if (!this.activeBeamHead.shooting() || beamTarget == null || !beamTarget.isAlive()) { this.stopRoyalBeam(); + } else if (!this.beamStarted) { + return; } else { if (this.beamLoopSoundTicks-- <= 0) { this.beamLoopSoundTicks = 20; - this.playSound(this.royalBeamLoopSound(), 2.5F, 1.0F); + this.playRoyalSound(this.royalBeamLoopSound(), 1.0F); } this.beamController.tick( this.headAnchor(this.activeBeamHead), @@ -393,24 +429,56 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult for (int offset = 0; offset < this.heads.length; offset++) { RoyalHead head = this.heads[(this.beamHeadCursor + offset) % this.heads.length]; LivingEntity target = head.target(this.level()); - if (!head.readyToAttack() || target == null || !this.canAttack(target) + if (!head.readyToAttack() || this.attackScheduler.laneBusy(this.headLane(head)) + || target == null || !this.canAttack(target) || this.headWithinBiteReach(head, target)) { continue; } - int duration = Math.max(1, this.royalBeamSettings().durationTicks()); - int cooldown = Math.max(1, Mth.floor(this.royalBeamSettings().cooldownTicks() * phase.cooldownScale())); - head.startShoot(duration, cooldown); + RoyalBeamSettings beamSettings = this.royalBeamSettings(); + int duration = Math.max(1, beamSettings.durationTicks()); + int cooldown = Math.max(1, Mth.floor(beamSettings.cooldownTicks() * phase.cooldownScale())); + int windup = Math.max(0, AntarchySettings.queenBeamWindupTicks()); + if (this instanceof KingEntity) { + windup = Math.max(0, AntarchySettings.kingBeamWindupTicks()); + } + LivingEntity committedTarget = target; + if (!this.attackScheduler.start("beam_" + head.slot().name(), this.beamLane(), cooldown, + windup, duration, 8, new RoyalAttackScheduler.Action() { + @Override + public void onStart() { + head.startShoot(); + } + + @Override + public void onActive(int elapsedTicks) { + if (elapsedTicks != 0 || RoyalBossEntity.this.beamStarted) { + return; + } + RoyalBossEntity.this.beamStarted = true; + RoyalBossEntity.this.beamController.start( + RoyalBossEntity.this.headAnchor(head), committedTarget.getEyePosition(), duration); + RoyalBossEntity.this.entityData.set(BEAM_ELEMENT, RoyalBossEntity.this.royalBeamElement(head).ordinal()); + RoyalBossEntity.this.setFiringRoyalBeam(true); + RoyalBossEntity.this.triggerAnim(head.slot().controllerName(), "shoot"); + RoyalBossEntity.this.beamLoopSoundTicks = 20; + RoyalBossEntity.this.playRoyalSound(RoyalBossEntity.this.royalBeamStartSound(head), 1.0F); + RoyalBossEntity.this.playRoyalSound(RoyalBossEntity.this.royalBeamShootSound(), 1.0F); + } + + @Override + public void onComplete() { + if (RoyalBossEntity.this.activeBeamHead == head) { + RoyalBossEntity.this.stopRoyalBeam(); + } + } + })) { + continue; + } head.setBeamActive(true); this.activeBeamHead = head; this.beamHeadCursor = (head.slot().partIndex()) % this.heads.length; this.beamCooldownTicks = cooldown; - this.beamController.start(this.headAnchor(head), target.getEyePosition(), duration); - this.entityData.set(BEAM_ELEMENT, this.royalBeamElement(head).ordinal()); - this.setFiringRoyalBeam(true); - this.triggerAnim(head.slot().controllerName(), "shoot"); - this.beamLoopSoundTicks = 20; - this.playSound(this.royalBeamStartSound(head), 3.0F, 1.0F); - this.playSound(this.royalBeamShootSound(), 3.0F, 1.0F); + this.beamStarted = false; return; } } @@ -418,11 +486,14 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private void stopRoyalBeam() { if (this.activeBeamHead != null) { this.activeBeamHead.setBeamActive(false); + this.activeBeamHead.stopShoot(); } this.activeBeamHead = null; + this.beamStarted = false; + this.attackScheduler.cancel(this.beamLane()); this.beamController.stop(); this.entityData.set(BEAM_ELEMENT, RoyalBeamElement.GENERIC.ordinal()); - this.playSound(this.royalBeamEndSound(), 2.5F, 1.0F); + this.playRoyalSound(this.royalBeamEndSound(), 1.0F); this.setFiringRoyalBeam(false); this.setRoyalBeamEndPosition(null); } @@ -484,8 +555,11 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult return; } + boolean inverted = AntarchyGravityApi.isGravityInverted(this); double groundBelowTarget = this.groundYBelow(target.getX(), target.getZ()); - double wantedY = Mth.clamp(target.getY() + 3.0D, + double wantedY = inverted + ? target.getY() - 3.0D + : Mth.clamp(target.getY() + 3.0D, groundBelowTarget + FLYING_MIN_HOVER, groundBelowTarget + FLYING_MAX_HOVER_ABOVE_GROUND); boolean closeVertically = Math.abs(wantedY - this.getY()) <= 2.5D; @@ -502,6 +576,9 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } private void tickFlyingAltitude() { + if (AntarchyGravityApi.isGravityInverted(this)) { + return; + } if (this.onGround()) { this.setDeltaMovement(this.getDeltaMovement().add(0.0D, 0.2D, 0.0D)); } @@ -535,9 +612,44 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private void startBite(RoyalHead head, Phase phase) { int cooldown = Math.max(10, Mth.floor(AntarchySettings.royalBossBiteCooldownTicks() * phase.cooldownScale())); - head.startBite(BITE_DURATION_TICKS, BITE_HIT_TICK, cooldown); - this.triggerAnim(head.slot().controllerName(), "bite"); - this.playSound(this.royalBiteSound(), 3.0F, 0.9F + this.random.nextFloat() * 0.2F); + if (!this.attackScheduler.start("bite_" + head.slot().name(), headLane(head), cooldown, + BITE_HIT_TICK, 1, BITE_DURATION_TICKS - BITE_HIT_TICK, + new RoyalAttackScheduler.Action() { + @Override + public void onStart() { + RoyalBossEntity.this.triggerAnim(head.slot().controllerName(), "bite"); + RoyalBossEntity.this.playRoyalSound(RoyalBossEntity.this.royalBiteSound(), + 0.9F + RoyalBossEntity.this.random.nextFloat() * 0.2F); + } + + @Override + public void onActive(int elapsedTicks) { + RoyalBossEntity.this.applyBiteHit(head); + } + })) { + return; + } + } + + protected RoyalAttackLane headLane(RoyalHead head) { + return switch (head.slot()) { + case LEFT -> RoyalAttackLane.LEFT_HEAD; + case CENTER -> RoyalAttackLane.CENTER_HEAD; + case RIGHT -> RoyalAttackLane.RIGHT_HEAD; + }; + } + + protected RoyalAttackLane beamLane() { + return RoyalAttackLane.BODY; + } + + protected boolean beginRoyalAttack(String id, RoyalAttackLane lane, int cooldownTicks, int activeTicks) { + return this.attackScheduler.start(id, lane, cooldownTicks, activeTicks); + } + + protected boolean beginRoyalAttack(String id, RoyalAttackLane lane, int cooldownTicks, int windupTicks, + int activeTicks, int recoveryTicks, RoyalAttackScheduler.Action action) { + return this.attackScheduler.start(id, lane, cooldownTicks, windupTicks, activeTicks, recoveryTicks, action); } private void applyBiteHit(RoyalHead head) { @@ -578,7 +690,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult return AntarchySettings.royalBossBiteReach(); } - private Vec3 headAnchor(RoyalHead head) { + protected Vec3 headAnchor(RoyalHead head) { int partIndex = head.slot().partIndex(); Entity[] parts = this.multipartParts; if (parts != null && partIndex < parts.length && parts[partIndex] != null) { @@ -596,6 +708,10 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult this.getZ() + forward.z * spec.forwardOffset() + right.z * spec.lateralOffset()); } + protected RoyalHead royalHead(RoyalHead.Slot slot) { + return this.heads[slot.ordinal()]; + } + @Override public void die(DamageSource damageSource) { if (!this.level().isClientSide) { @@ -667,7 +783,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult @Override public boolean canBeAffected(net.minecraft.world.effect.MobEffectInstance effectInstance) { if (effectInstance.is(com.craisinlord.antarchy.content.AntarchyObjects.INVERTED_EFFECT.get())) { - return false; + return ThoraxisUndersideManager.isThoraxis(this.level()); } return super.canBeAffected(effectInstance); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java new file mode 100644 index 00000000..7db866f5 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java @@ -0,0 +1,199 @@ +package com.craisinlord.antarchy.content.entity.royal; + +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamElement; +import com.craisinlord.antarchy.config.AntarchySettings; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.projectile.ThrowableProjectile; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; +import software.bernie.geckolib.animatable.GeoEntity; +import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.animation.AnimatableManager; +import software.bernie.geckolib.animation.AnimationController; +import software.bernie.geckolib.animation.AnimationState; +import software.bernie.geckolib.animation.PlayState; +import software.bernie.geckolib.animation.RawAnimation; +import software.bernie.geckolib.util.GeckoLibUtil; + +/** Shared travelling shell for the King's fireball and iceball. Impact rules stay element-specific. */ +public class RoyalElementalProjectileEntity extends ThrowableProjectile implements GeoEntity { + private static final EntityDataAccessor ATTACK_TYPE = + SynchedEntityData.defineId(RoyalElementalProjectileEntity.class, EntityDataSerializers.INT); + private static final int FIREBALL = 0; + private static final int ICEBALL = 1; + private static final int MAX_LIFETIME = 100; + private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); + + public RoyalElementalProjectileEntity(EntityType type, Level level) { + super(type, level); + this.noCulling = true; + } + + public static RoyalElementalProjectileEntity create(Level level, LivingEntity owner, RoyalBeamElement element, + Vec3 position, Vec3 direction) { + RoyalElementalProjectileEntity projectile = new RoyalElementalProjectileEntity( + AntarchyObjects.ROYAL_ELEMENTAL_PROJECTILE.get(), level); + projectile.setOwner(owner); + projectile.setPos(position.x, position.y, position.z); + projectile.setAttackType(element == RoyalBeamElement.ICE ? ICEBALL : FIREBALL); + projectile.shoot(direction.x, direction.y, direction.z, element == RoyalBeamElement.ICE ? 0.8F : 1.05F, 0.0F); + return projectile; + } + + @Override + protected void defineSynchedData(SynchedEntityData.Builder builder) { + builder.define(ATTACK_TYPE, FIREBALL); + } + + public boolean isIceball() { + return this.entityData.get(ATTACK_TYPE) == ICEBALL; + } + + private void setAttackType(int type) { + this.entityData.set(ATTACK_TYPE, type); + } + + @Override + protected double getDefaultGravity() { + return this.isIceball() ? 0.012D : 0.018D; + } + + protected float getInertia() { + return this.isIceball() ? 0.985F : 0.96F; + } + + @Override + public void tick() { + if (!this.level().isClientSide && this.tickCount > MAX_LIFETIME) { + this.discard(); + return; + } + super.tick(); + if (this.level().isClientSide) { + this.level().addParticle(this.isIceball() ? ParticleTypes.SNOWFLAKE : ParticleTypes.FLAME, + this.getX(), this.getY(), this.getZ(), 0.0D, 0.0D, 0.0D); + } + } + + @Override + protected void onHitEntity(EntityHitResult result) { + if (!this.level().isClientSide && this.level() instanceof ServerLevel level) { + this.impact(level, result.getLocation()); + } + this.discard(); + } + + @Override + protected void onHitBlock(BlockHitResult result) { + if (!this.level().isClientSide && this.level() instanceof ServerLevel level) { + this.impact(level, result.getLocation()); + } + this.discard(); + } + + @Override + protected void onHit(HitResult result) { + super.onHit(result); + if (!this.level().isClientSide && result.getType() == HitResult.Type.MISS) { + this.discard(); + } + } + + private void impact(ServerLevel level, Vec3 center) { + if (this.isIceball()) { + impactIce(level, center); + } else { + impactFire(level, center); + } + } + + private void impactFire(ServerLevel level, Vec3 center) { + DamageSource source = this.damageSources().mobProjectile(this, this.getOwner() instanceof LivingEntity living ? living : null); + for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class, new AABB(center, center).inflate(5.0D), + entity -> entity.isAlive() && entity != this.getOwner())) { + double distance = Math.max(0.5D, living.position().distanceTo(center)); + float falloff = (float) Math.max(0.25D, 1.0D - distance / 5.0D); + living.hurt(source, (float) (AntarchySettings.kingFireballDamage() * falloff)); + living.setRemainingFireTicks(Math.max(living.getRemainingFireTicks(), 120)); + } + RoyalBlockDestruction.destroySphere(level, this, center, AntarchySettings.kingFireballRadius(), AntarchySettings.kingElementalTerrainCap(), 80.0D, 0.15F); + level.sendParticles(ParticleTypes.EXPLOSION_EMITTER, center.x, center.y, center.z, 4, 1.5D, 1.5D, 1.5D, 0.0D); + } + + private void impactIce(ServerLevel level, Vec3 center) { + DamageSource source = this.damageSources().mobProjectile(this, this.getOwner() instanceof LivingEntity living ? living : null); + for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class, new AABB(center, center).inflate(5.0D), + entity -> entity.isAlive() && entity != this.getOwner())) { + living.hurt(source, (float) AntarchySettings.kingIceballDamage()); + living.setTicksFrozen(Math.min(living.getTicksRequiredToFreeze() + 80, living.getTicksFrozen() + 180)); + living.addEffect(new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.MOVEMENT_SLOWDOWN, 120, 3)); + } + coverInIce(level, center, AntarchySettings.kingIceballRadius(), AntarchySettings.kingElementalTerrainCap()); + level.sendParticles(ParticleTypes.SNOWFLAKE, center.x, center.y, center.z, 80, 4.0D, 2.0D, 4.0D, 0.08D); + } + + private void coverInIce(ServerLevel level, Vec3 center, double radius, int cap) { + int changed = 0; + int minX = (int) Math.floor(center.x - radius); + int minY = (int) Math.floor(center.y - radius); + int minZ = (int) Math.floor(center.z - radius); + int maxX = (int) Math.floor(center.x + radius); + int maxY = (int) Math.floor(center.y + radius); + int maxZ = (int) Math.floor(center.z + radius); + for (BlockPos pos : BlockPos.betweenClosed(minX, minY, minZ, maxX, maxY, maxZ)) { + if (changed >= cap || pos.distToCenterSqr(center.x, center.y, center.z) > radius * radius) continue; + BlockState existing = level.getBlockState(pos); + if (existing.isAir() || !existing.getFluidState().isEmpty() || existing.hasBlockEntity()) continue; + if (existing.getDestroySpeed(level, pos) < 0.0F || existing.getBlock().getExplosionResistance() > 80.0F) continue; + BlockState frozen = pos.getY() >= center.y + 1.0D ? Blocks.SNOW_BLOCK.defaultBlockState() : Blocks.PACKED_ICE.defaultBlockState(); + if (existing != frozen && level.setBlockAndUpdate(pos, frozen)) changed++; + } + } + + protected net.minecraft.core.particles.ParticleOptions getTrailParticle() { + return this.isIceball() ? ParticleTypes.SNOWFLAKE : ParticleTypes.FLAME; + } + + @Override + public void addAdditionalSaveData(CompoundTag tag) { + super.addAdditionalSaveData(tag); + tag.putInt("AttackType", this.entityData.get(ATTACK_TYPE)); + } + + @Override + public void readAdditionalSaveData(CompoundTag tag) { + super.readAdditionalSaveData(tag); + this.setAttackType(tag.getInt("AttackType")); + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { + controllers.add(new AnimationController<>(this, "elemental_projectile", 0, this::animation)); + } + + private PlayState animation(AnimationState state) { + return state.setAndContinue(RawAnimation.begin().thenLoop(this.isIceball() ? "animation.ice_ball" : "animation.fire_ball")); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.geoCache; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalHead.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalHead.java index 9c403741..43e8de4b 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalHead.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalHead.java @@ -41,10 +41,7 @@ public final class RoyalHead { private final Slot slot; private int targetId = -1; - private int attackCooldown; - private int biteTicks; - private int biteHitTick = -1; - private int shootTicks; + private boolean shooting; private boolean beamActive; public RoyalHead(Slot slot) { @@ -68,22 +65,19 @@ public final class RoyalHead { } public boolean busy() { - return this.biteTicks > 0 || this.shootTicks > 0 || this.beamActive; + return this.shooting || this.beamActive; } public boolean readyToAttack() { - return !this.busy() && this.attackCooldown <= 0; + return !this.busy(); } - public void startBite(int durationTicks, int hitTick, int cooldownTicks) { - this.biteTicks = durationTicks; - this.biteHitTick = hitTick; - this.attackCooldown = cooldownTicks; + public void startShoot() { + this.shooting = true; } - public void startShoot(int durationTicks, int cooldownTicks) { - this.shootTicks = durationTicks; - this.attackCooldown = cooldownTicks; + public void stopShoot() { + this.shooting = false; } public void setBeamActive(boolean beamActive) { @@ -95,36 +89,12 @@ public final class RoyalHead { } public boolean shooting() { - return this.shootTicks > 0; - } - - public boolean tickBiteHit() { - if (this.biteTicks <= 0) { - return false; - } - this.biteTicks--; - boolean hit = this.biteTicks == this.biteHitTick; - if (hit) { - this.biteHitTick = -1; - } - return hit; - } - - public void tick() { - if (this.attackCooldown > 0) { - this.attackCooldown--; - } - if (this.shootTicks > 0) { - this.shootTicks--; - } + return this.shooting; } public void reset() { this.targetId = -1; - this.attackCooldown = 0; - this.biteTicks = 0; - this.biteHitTick = -1; - this.shootTicks = 0; + this.shooting = false; this.beamActive = false; } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalIceSpikeEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalIceSpikeEntity.java new file mode 100644 index 00000000..217b9606 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalIceSpikeEntity.java @@ -0,0 +1,98 @@ +package com.craisinlord.antarchy.content.entity.royal; + +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.craisinlord.antarchy.config.AntarchySettings; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +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 software.bernie.geckolib.animatable.GeoEntity; +import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.animation.AnimatableManager; +import software.bernie.geckolib.animation.AnimationController; +import software.bernie.geckolib.animation.AnimationState; +import software.bernie.geckolib.animation.PlayState; +import software.bernie.geckolib.animation.RawAnimation; +import software.bernie.geckolib.util.GeckoLibUtil; + +public class RoyalIceSpikeEntity extends Entity implements GeoEntity { + private static final RawAnimation EMERGE_ANIMATION = RawAnimation.begin().thenPlay("ice_spike"); + private static final RawAnimation IMPACT_ANIMATION = RawAnimation.begin().thenPlay("ice_spike_impact"); + private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); + private boolean impacted; + + public RoyalIceSpikeEntity(EntityType type, Level level) { + super(type, level); + this.noPhysics = true; + this.noCulling = true; + } + + public static RoyalIceSpikeEntity create(ServerLevel level, Vec3 position) { + RoyalIceSpikeEntity spike = new RoyalIceSpikeEntity(AntarchyObjects.ROYAL_ICE_SPIKE.get(), level); + spike.setPos(position.x, position.y, position.z); + return spike; + } + + @Override + protected void defineSynchedData(net.minecraft.network.syncher.SynchedEntityData.Builder builder) { + } + + @Override + public void tick() { + super.tick(); + if (!this.level().isClientSide && this.tickCount == 1) { + this.triggerAnim("ice_spike", "emerge"); + } + if (!this.level().isClientSide && this.tickCount == 6 && !this.impacted) { + this.impacted = true; + this.impact((ServerLevel) this.level()); + this.triggerAnim("ice_spike", "impact"); + } + if (!this.level().isClientSide && this.tickCount > 45) { + this.discard(); + } + if (this.level().isClientSide && this.tickCount < 10) { + this.level().addParticle(ParticleTypes.SNOWFLAKE, this.getX(), this.getY() + this.tickCount * 0.4D, this.getZ(), 0.0D, 0.03D, 0.0D); + } + } + + private void impact(ServerLevel level) { + DamageSource source = this.damageSources().magic(); + for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class, + new AABB(this.blockPosition()).inflate(2.2D), entity -> entity.isAlive())) { + living.hurt(source, (float) AntarchySettings.kingIceSpikeDamage()); + living.setTicksFrozen(Math.min(living.getTicksRequiredToFreeze() + 60, living.getTicksFrozen() + 100)); + living.setDeltaMovement(living.getDeltaMovement().add(0.0D, 0.35D, 0.0D)); + living.hasImpulse = true; + } + level.sendParticles(ParticleTypes.SNOWFLAKE, this.getX(), this.getY() + 1.5D, this.getZ(), 25, 1.5D, 1.0D, 1.5D, 0.04D); + } + + @Override + protected void readAdditionalSaveData(CompoundTag tag) { + this.impacted = tag.getBoolean("Impacted"); + } + + @Override + protected void addAdditionalSaveData(CompoundTag tag) { + tag.putBoolean("Impacted", this.impacted); + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { + controllers.add(new AnimationController<>(this, "ice_spike", 0, state -> PlayState.STOP) + .triggerableAnim("emerge", EMERGE_ANIMATION) + .triggerableAnim("impact", IMPACT_ANIMATION)); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.geoCache; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackLane.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackLane.java new file mode 100644 index 00000000..ef6a6143 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackLane.java @@ -0,0 +1,12 @@ +package com.craisinlord.antarchy.content.entity.royal.attack; + +public enum RoyalAttackLane { + BODY, + LEFT_HEAD, + CENTER_HEAD, + RIGHT_HEAD, + HAZARD, + SUMMON, + DECREE, + MOVEMENT +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java new file mode 100644 index 00000000..dfa2d0ea --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java @@ -0,0 +1,123 @@ +package com.craisinlord.antarchy.content.entity.royal.attack; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; +import java.util.function.ToIntFunction; +import net.minecraft.util.RandomSource; + +/** Shared server-side arbitration for Royal attack lifecycles. */ +public final class RoyalAttackScheduler { + public interface Action { + default void onStart() {} + default void onActive(int elapsedTicks) {} + default void onComplete() {} + } + + private static final class RunningAction { + private final Action action; + private final int windupTicks; + private final int activeTicks; + private final int recoveryTicks; + private int elapsedTicks; + + private RunningAction(Action action, int windupTicks, int activeTicks, int recoveryTicks) { + this.action = action; + this.windupTicks = Math.max(0, windupTicks); + this.activeTicks = Math.max(1, activeTicks); + this.recoveryTicks = Math.max(0, recoveryTicks); + } + + private int totalTicks() { + return this.windupTicks + this.activeTicks + this.recoveryTicks; + } + } + private final Map cooldowns = new HashMap<>(); + private final Map active = new EnumMap<>(RoyalAttackLane.class); + private final Deque recent = new ArrayDeque<>(); + + public void tick() { + cooldowns.replaceAll((key, value) -> Math.max(0, value - 1)); + for (var iterator = active.entrySet().iterator(); iterator.hasNext();) { + RunningAction running = iterator.next().getValue(); + running.elapsedTicks++; + int activeStart = running.windupTicks; + int activeEnd = activeStart + running.activeTicks; + if (running.elapsedTicks >= activeStart && running.elapsedTicks < activeEnd) { + running.action.onActive(running.elapsedTicks - activeStart); + } + if (running.elapsedTicks >= running.totalTicks()) { + iterator.remove(); + running.action.onComplete(); + } + } + } + + public boolean ready(String id, RoyalAttackLane lane) { + return cooldowns.getOrDefault(id, 0) <= 0 && !active.containsKey(lane); + } + + public boolean laneBusy(RoyalAttackLane lane) { + return active.containsKey(lane); + } + + public boolean start(String id, RoyalAttackLane lane, int cooldownTicks, int activeTicks) { + return start(id, lane, cooldownTicks, 0, activeTicks, 0, new Action() {}); + } + + public boolean start(String id, RoyalAttackLane lane, int cooldownTicks, int windupTicks, + int activeTicks, int recoveryTicks, Action action) { + if (!ready(id, lane)) { + return false; + } + cooldowns.put(id, Math.max(1, cooldownTicks)); + active.put(lane, new RunningAction(action, windupTicks, activeTicks, recoveryTicks)); + action.onStart(); + recent.remove(id); + recent.addFirst(id); + while (recent.size() > 8) { + recent.removeLast(); + } + return true; + } + + public int repetitionPenalty(String id) { + int penalty = 0; + for (String previous : recent) { + if (previous.equals(id)) { + penalty += 3; + } + } + return penalty; + } + + public String chooseWeighted(String[] ids, ToIntFunction weightFunction, RandomSource random) { + int total = 0; + int[] weights = new int[ids.length]; + for (int i = 0; i < ids.length; i++) { + weights[i] = Math.max(0, weightFunction.applyAsInt(ids[i]) - repetitionPenalty(ids[i])); + total += weights[i]; + } + if (total <= 0) { + return null; + } + int roll = random.nextInt(total); + for (int i = 0; i < ids.length; i++) { + roll -= weights[i]; + if (roll < 0) { + return ids[i]; + } + } + return null; + } + + public int cooldown(String id) { + return cooldowns.getOrDefault(id, 0); + } + + public void cancel(RoyalAttackLane lane) { + active.remove(lane); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalEffectController.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalEffectController.java new file mode 100644 index 00000000..f0da3ab0 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalEffectController.java @@ -0,0 +1,54 @@ +package com.craisinlord.antarchy.content.entity.royal.attack; + +import java.util.HashMap; +import java.util.Map; + +/** Owns persistent per-tick effects started by a Royal attack. */ +public final class RoyalEffectController { + private record Effect(Runnable tick, Runnable end, int duration, int age) { + private Effect advance() { + return new Effect(this.tick, this.end, this.duration, this.age + 1); + } + } + + private final Map active = new HashMap<>(); + + public void tick() { + for (var iterator = this.active.entrySet().iterator(); iterator.hasNext();) { + var entry = iterator.next(); + Effect effect = entry.getValue(); + effect.tick().run(); + Effect next = effect.advance(); + if (next.age() >= next.duration()) { + next.end().run(); + iterator.remove(); + } else { + entry.setValue(next); + } + } + } + + public void start(String id, int duration, Runnable onStart, Runnable tick, Runnable end) { + this.stop(id); + onStart.run(); + this.active.put(id, new Effect(tick, end, Math.max(1, duration), 0)); + } + + public boolean active(String id) { + return this.active.containsKey(id); + } + + public void stop(String id) { + Effect effect = this.active.remove(id); + if (effect != null) { + effect.end().run(); + } + } + + public void clear() { + for (Effect effect : this.active.values()) { + effect.end().run(); + } + this.active.clear(); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamController.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamController.java index 4ae93ee8..75fdfcfe 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamController.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamController.java @@ -26,10 +26,13 @@ import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; public final class RoyalBeamController { + private static final int INITIAL_TRACKING_DELAY_TICKS = 8; private final Mob owner; private Vec3 serverTarget; private Vec3 beamEndPosition; private int beamTicks; + private int beamAgeTicks; + private int trackingDelayTicks; private int terrainMutationsThisTick; private static final int ICE_MUTATIONS_PER_TICK = 3; private static final float ICE_IMPACT_RADIUS = 2.0F; @@ -55,12 +58,15 @@ public final class RoyalBeamController { this.serverTarget = target; this.beamEndPosition = target; this.beamTicks = Math.max(1, durationTicks); + this.beamAgeTicks = 0; + this.trackingDelayTicks = INITIAL_TRACKING_DELAY_TICKS; } public void stop() { this.serverTarget = null; this.beamEndPosition = null; this.beamTicks = 0; + this.beamAgeTicks = 0; } public void tick( @@ -76,8 +82,11 @@ public final class RoyalBeamController { } this.beamTicks--; + this.beamAgeTicks++; this.terrainMutationsThisTick = 0; - if (target != null && target.isAlive()) { + if (this.trackingDelayTicks > 0) { + this.trackingDelayTicks--; + } else if (target != null && target.isAlive()) { Vec3 targetEye = target.getEyePosition(); this.serverTarget = this.serverTarget == null ? targetEye @@ -93,7 +102,10 @@ public final class RoyalBeamController { if (direction.lengthSqr() < 1.0E-7D) { direction = this.owner.getLookAngle(); } - Vec3 clipEnd = shootFrom.add(direction.scale(settings.range())); + double committedDistance = Math.min(settings.range(), shootFrom.distanceTo(this.serverTarget)); + double travelProgress = Mth.clamp(this.beamAgeTicks / (double) settings.travelTicks(), 0.0D, 1.0D); + double currentRange = Math.max(settings.pathStep(), committedDistance * travelProgress); + Vec3 clipEnd = shootFrom.add(direction.scale(currentRange)); HitResult hit = this.owner.level().clip(new ClipContext( shootFrom, clipEnd, diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamSettings.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamSettings.java index 082338ee..240bba9b 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamSettings.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamSettings.java @@ -5,6 +5,7 @@ public record RoyalBeamSettings( double targetTracking, double pathStep, int durationTicks, + int travelTicks, int cooldownTicks, float pathDamageRadius, float impactDamageRadius, @@ -27,6 +28,7 @@ public record RoyalBeamSettings( 0.1D, 7.5D, 30, + 12, 90, 6.0F, 6.0F, @@ -50,6 +52,7 @@ public record RoyalBeamSettings( targetTracking = Math.clamp(targetTracking, 0.0D, 1.0D); pathStep = Math.max(1.0D, pathStep); durationTicks = Math.max(1, durationTicks); + travelTicks = Math.max(1, travelTicks); cooldownTicks = Math.max(1, cooldownTicks); pathDamageRadius = Math.max(0.0F, pathDamageRadius); impactDamageRadius = Math.max(0.0F, impactDamageRadius); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/AdvanceDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/AdvanceDecree.java index c5d0e13b..f28bf41a 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/AdvanceDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/AdvanceDecree.java @@ -5,11 +5,9 @@ import net.minecraft.world.entity.LivingEntity; public final class AdvanceDecree implements RoyalDecree { private static final double REQUIRED_RANGE = 14.0D; public String translationKey() { return "decree.antarchy.advance"; } - public void apply(ServerLevel level, KingEntity king, LivingEntity target) { - king.setDecreeRetreatPressure(true); - if (target.distanceTo(king) > REQUIRED_RANGE) { - king.invokeJudgment(target); - } + public void apply(ServerLevel level, KingEntity king, LivingEntity target) { king.setDecreeRetreatPressure(true); } + @Override public Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + return target.distanceTo(king) > REQUIRED_RANGE ? Evaluation.VIOLATED : Evaluation.COMPLIANT; } @Override public int contextWeight(KingEntity king, LivingEntity target) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/ComeNoCloserDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/ComeNoCloserDecree.java index 25120910..f98e4ef9 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/ComeNoCloserDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/ComeNoCloserDecree.java @@ -5,6 +5,9 @@ import net.minecraft.world.entity.LivingEntity; public final class ComeNoCloserDecree implements RoyalDecree { public String translationKey() { return "decree.antarchy.come_no_closer"; } public void apply(ServerLevel level, KingEntity king, LivingEntity target) { } + @Override public Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + return target.distanceTo(king) <= 16.0D ? Evaluation.VIOLATED : Evaluation.COMPLIANT; + } @Override public int contextWeight(KingEntity king, LivingEntity target) { return 4 + king.behaviorScore(KingEntity.Behavior.HUGGING); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/DoNotRunDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/DoNotRunDecree.java index 17e3f9b9..7940b4a4 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/DoNotRunDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/DoNotRunDecree.java @@ -4,7 +4,10 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.LivingEntity; public final class DoNotRunDecree implements RoyalDecree { public String translationKey() { return "decree.antarchy.do_not_run"; } - public void apply(ServerLevel level, KingEntity king, LivingEntity target) { if (target.isSprinting()) king.invokeJudgment(target); } + public void apply(ServerLevel level, KingEntity king, LivingEntity target) { } + @Override public Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + return target.isSprinting() ? Evaluation.VIOLATED : Evaluation.COMPLIANT; + } @Override public int contextWeight(KingEntity king, LivingEntity target) { return 4 + king.behaviorScore(KingEntity.Behavior.SPRINTING); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/FightMeCowardDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/FightMeCowardDecree.java index 24cebe64..d541f8b7 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/FightMeCowardDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/FightMeCowardDecree.java @@ -13,4 +13,8 @@ public final class FightMeCowardDecree implements RoyalDecree { target.hasImpulse = true; } } + @Override + public Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + return target.distanceTo(king) > 28.0D ? Evaluation.VIOLATED : Evaluation.COMPLIANT; + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/KeepYourDistanceDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/KeepYourDistanceDecree.java index f009eabb..cc876daa 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/KeepYourDistanceDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/KeepYourDistanceDecree.java @@ -5,10 +5,9 @@ import net.minecraft.world.entity.LivingEntity; public final class KeepYourDistanceDecree implements RoyalDecree { private static final double INNER_RADIUS = 16.0D; public String translationKey() { return "decree.antarchy.keep_your_distance"; } - public void apply(ServerLevel level, KingEntity king, LivingEntity target) { - if (target.distanceTo(king) <= INNER_RADIUS) { - king.invokeJudgment(target); - } + public void apply(ServerLevel level, KingEntity king, LivingEntity target) { } + @Override public Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + return target.distanceTo(king) <= INNER_RADIUS ? Evaluation.VIOLATED : Evaluation.COMPLIANT; } @Override public int contextWeight(KingEntity king, LivingEntity target) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/KneelDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/KneelDecree.java index fe1514ba..2f817a00 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/KneelDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/KneelDecree.java @@ -12,7 +12,7 @@ public final class KneelDecree implements RoyalDecree { UUID id = target.getUUID(); if (target.isCrouching()) { deadlines.remove(id); king.clearActiveDecree(target); return; } int deadline = deadlines.computeIfAbsent(id, ignored -> target.tickCount + 100); - if (target.tickCount >= deadline) { king.invokeJudgment(target); deadlines.put(id, target.tickCount + 100); } + if (target.tickCount >= deadline) { king.failActiveDecree(target); } } @Override diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/RoyalDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/RoyalDecree.java index d0c29d5e..b75a43c1 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/RoyalDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/RoyalDecree.java @@ -5,9 +5,19 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.LivingEntity; public interface RoyalDecree { + enum Evaluation { + COMPLIANT, + VIOLATED, + COMPLETE + } + String translationKey(); void apply(ServerLevel level, KingEntity king, LivingEntity target); + default Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + return Evaluation.COMPLIANT; + } + default int countdownTicks(LivingEntity target) { return -1; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/ShowNoMercyDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/ShowNoMercyDecree.java index 44ff3e2e..3f57deb0 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/ShowNoMercyDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/ShowNoMercyDecree.java @@ -6,8 +6,9 @@ public final class ShowNoMercyDecree implements RoyalDecree { private static final long IDLE_DAMAGE_LIMIT_TICKS = 80L; public String translationKey() { return "decree.antarchy.show_no_mercy"; } public void apply(ServerLevel level, KingEntity king, LivingEntity target) { - if (king.ticksSincePlayerDamage(target) > IDLE_DAMAGE_LIMIT_TICKS) { - king.invokeJudgment(target); - } + } + @Override public Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + return king.ticksSincePlayerDamage(target) > IDLE_DAMAGE_LIMIT_TICKS + ? Evaluation.VIOLATED : Evaluation.COMPLIANT; } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/SkyIsMineDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/SkyIsMineDecree.java index 3525844f..0fda8b16 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/SkyIsMineDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/SkyIsMineDecree.java @@ -4,7 +4,10 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.LivingEntity; public final class SkyIsMineDecree implements RoyalDecree { public String translationKey() { return "decree.antarchy.the_sky_is_mine"; } - public void apply(ServerLevel level, KingEntity king, LivingEntity target) { if (!target.onGround() && !target.isPassenger()) king.invokeJudgment(target); } + public void apply(ServerLevel level, KingEntity king, LivingEntity target) { } + @Override public Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + return !target.onGround() && !target.isPassenger() ? Evaluation.VIOLATED : Evaluation.COMPLIANT; + } @Override public int contextWeight(KingEntity king, LivingEntity target) { return 4 + king.behaviorScore(KingEntity.Behavior.AIRBORNE); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/StandTallDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/StandTallDecree.java index 7a04453d..823394ff 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/StandTallDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/StandTallDecree.java @@ -5,8 +5,8 @@ import net.minecraft.world.entity.LivingEntity; public final class StandTallDecree implements RoyalDecree { public String translationKey() { return "decree.antarchy.stand_tall"; } public void apply(ServerLevel level, KingEntity king, LivingEntity target) { - if (target.isCrouching()) { - king.invokeJudgment(target); - } + } + @Override public Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + return target.isCrouching() ? Evaluation.VIOLATED : Evaluation.COMPLIANT; } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/StandYourGroundDecree.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/StandYourGroundDecree.java index 5e46e984..622ff408 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/StandYourGroundDecree.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/decree/StandYourGroundDecree.java @@ -12,9 +12,11 @@ public final class StandYourGroundDecree implements RoyalDecree { public String translationKey() { return "decree.antarchy.stand_your_ground"; } public void apply(ServerLevel level, KingEntity king, LivingEntity target) { Vec3 anchor = this.anchors.computeIfAbsent(target.getUUID(), ignored -> target.position()); - if (target.position().distanceToSqr(anchor) > ALLOWED_DRIFT * ALLOWED_DRIFT) { - king.invokeJudgment(target); - } + } + @Override public Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + Vec3 anchor = this.anchors.computeIfAbsent(target.getUUID(), ignored -> target.position()); + return target.position().distanceToSqr(anchor) > ALLOWED_DRIFT * ALLOWED_DRIFT + ? Evaluation.VIOLATED : Evaluation.COMPLIANT; } @Override public void onEnded() { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/vortex/WindVortexEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/vortex/WindVortexEntity.java index d685d81f..4a9d34ab 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/vortex/WindVortexEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/vortex/WindVortexEntity.java @@ -8,6 +8,7 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; @@ -66,6 +67,8 @@ public class WindVortexEntity extends Entity { private static final String TRAVEL_Z_KEY = "TravelZ"; private static final String TRAVELLING_KEY = "Travelling"; private static final String HOMING_KEY = "Homing"; + private static final String ANCHORED_KEY = "Anchored"; + private static final String BOUNCE_ON_IMPACT_KEY = "BounceOnImpact"; private static final double BASE_RADIUS = 0.35D; private static final double DRIFT_FRICTION = 0.995D; @@ -82,15 +85,20 @@ public class WindVortexEntity extends Entity { } private int age; - private int durationTicks = 140; + private int durationTicks = 240; private double pullStrength = 0.32D; private double launchStrength = 1.0D; private float damageOverride = -1.0F; private Vec3 travelVelocity = Vec3.ZERO; private boolean travelling = false; private boolean homing = false; + private boolean bounceOnImpact = false; private int travelTicksRemaining; private int fadeOutTicksRemaining; + private boolean anchoredAtBlock; + private double flowTurnRate; + private double flowTurnTarget; + private int flowTurnChangeTicks; private final Map carriedProgress = new HashMap<>(); @Nullable private UUID ownerUuid; @@ -148,6 +156,18 @@ public class WindVortexEntity extends Entity { return; } + if (this.anchoredAtBlock) { + this.setDeltaMovement(Vec3.ZERO); + if ((this.tickCount & 1) == 0) { + this.applyVortexForces(); + } + this.age++; + if (this.age >= this.durationTicks) { + this.fadeOut(); + } + return; + } + boolean lensVortex = this.getMode() != VortexMode.UPWARD; if (!lensVortex && (this.isInLava() || this.isInsideSolidBlock())) { this.fadeOut(); @@ -164,20 +184,27 @@ public class WindVortexEntity extends Entity { if (this.homing) { this.steerTowardPrey(); } + if (this.bounceOnImpact) { + this.updateFluidDrift(); + } Vec3 from = this.position(); Vec3 to = from.add(this.travelVelocity); HitResult blockHit = this.level().clip( new ClipContext(from, to, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)); if (blockHit.getType() != HitResult.Type.MISS) { - this.fadeOut(); - return; - } - this.setDeltaMovement(this.travelVelocity); - this.move(net.minecraft.world.entity.MoverType.SELF, this.travelVelocity); - if (--this.travelTicksRemaining <= 0) { - this.travelling = false; - this.noPhysics = false; + if (this.bounceOnImpact) { + this.flowAroundBlock(blockHit); + } else { + this.anchorAtBlock(blockHit); + } + } else { this.setDeltaMovement(this.travelVelocity); + this.move(net.minecraft.world.entity.MoverType.SELF, this.travelVelocity); + if (--this.travelTicksRemaining <= 0) { + this.travelling = false; + this.noPhysics = false; + this.setDeltaMovement(this.travelVelocity); + } } } else if (!lensVortex) { Vec3 current = this.getDeltaMovement(); @@ -192,11 +219,15 @@ public class WindVortexEntity extends Entity { HitResult blockHit = this.level().clip( new ClipContext(from, to, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)); if (blockHit.getType() != HitResult.Type.MISS) { - this.fadeOut(); - return; + if (this.bounceOnImpact) { + this.flowAroundBlock(blockHit); + } else { + this.anchorAtBlock(blockHit); + } + } else { + this.setDeltaMovement(drift); + this.move(net.minecraft.world.entity.MoverType.SELF, drift); } - this.setDeltaMovement(drift); - this.move(net.minecraft.world.entity.MoverType.SELF, drift); } else { Vec3 drift = this.getDeltaMovement().multiply(DRIFT_FRICTION, DRIFT_FRICTION, DRIFT_FRICTION); this.setDeltaMovement(drift); @@ -256,6 +287,73 @@ public class WindVortexEntity extends Entity { } } + private void anchorAtBlock(HitResult hit) { + this.travelling = false; + this.noPhysics = false; + this.travelVelocity = Vec3.ZERO; + this.setDeltaMovement(Vec3.ZERO); + if (hit instanceof net.minecraft.world.phys.BlockHitResult blockHit) { + Vec3 normal = Vec3.atLowerCornerOf(blockHit.getDirection().getNormal()); + this.setPos(blockHit.getLocation().add(normal.scale(0.05D))); + } + this.anchoredAtBlock = true; + } + + private void updateFluidDrift() { + if (--this.flowTurnChangeTicks <= 0) { + this.flowTurnChangeTicks = 24 + this.random.nextInt(32); + this.flowTurnTarget = (this.random.nextDouble() * 2.0D - 1.0D) * 0.012D; + } + this.flowTurnRate = Mth.lerp(0.08D, this.flowTurnRate, this.flowTurnTarget); + Vec3 horizontal = new Vec3(this.travelVelocity.x, 0.0D, this.travelVelocity.z); + if (horizontal.lengthSqr() > 1.0E-6D) { + Vec3 turned = horizontal.yRot((float) this.flowTurnRate); + this.travelVelocity = new Vec3(turned.x, this.travelVelocity.y, turned.z); + } + } + + private void flowAroundBlock(HitResult hit) { + if (!(hit instanceof net.minecraft.world.phys.BlockHitResult blockHit)) { + return; + } + + Vec3 normal = Vec3.atLowerCornerOf(blockHit.getDirection().getNormal()); + Vec3 incoming = this.travelVelocity.lengthSqr() > 1.0E-6D + ? this.travelVelocity + : this.getDeltaMovement(); + double speed = Mth.clamp(incoming.length(), 0.2D, 0.9D); + Vec3 flow = incoming; + if (normal.y > 0.5D) { + flow = new Vec3(incoming.x, 0.0D, incoming.z); + } else if (normal.y < -0.5D) { + flow = new Vec3(incoming.x, 0.0D, incoming.z).add(0.0D, -0.08D, 0.0D); + } else { + Vec3 tangent = incoming.subtract(normal.scale(incoming.dot(normal))); + if (tangent.lengthSqr() < 1.0E-6D) { + tangent = new Vec3(-normal.z, 0.0D, normal.x); + if (tangent.lengthSqr() < 1.0E-6D) { + tangent = new Vec3(0.0D, 0.0D, 1.0D); + } + } + flow = tangent.normalize().scale(speed); + } + if (flow.lengthSqr() < 1.0E-6D) { + this.travelVelocity = Vec3.ZERO; + this.setDeltaMovement(Vec3.ZERO); + this.travelling = false; + this.noPhysics = false; + return; + } + this.setPos(blockHit.getLocation().add(normal.scale(0.08D))); + this.travelVelocity = flow.normalize().scale(speed * 0.82D); + this.setDeltaMovement(this.travelVelocity); + this.noPhysics = true; + if (--this.travelTicksRemaining <= 0) { + this.travelling = false; + this.noPhysics = false; + } + } + @Override public void handleEntityEvent(byte id) { if (id == 60) { @@ -431,18 +529,13 @@ public class WindVortexEntity extends Entity { updatedMovement = new Vec3(updatedMovement.x, Math.max(updatedMovement.y, minRise), updatedMovement.z); entity.setOnGround(false); } + entity.setDeltaMovement(updatedMovement); if (entity instanceof Player) { - Vec3 before = entity.position(); - Vec3 playerCarry = wanted.scale(0.65D); - entity.move(net.minecraft.world.entity.MoverType.SELF, playerCarry); - if (entity.position().distanceToSqr(before) < 1.0E-6D && playerCarry.lengthSqr() > 1.0E-6D) { - entity.setPos(before.add(playerCarry)); - } entity.setOnGround(false); } - entity.setDeltaMovement(updatedMovement); entity.fallDistance = 0.0F; entity.hasImpulse = true; + this.syncPlayerMotion(entity); } private void launch(Entity entity, Vec3 radialVector, double progress, Basis basis) { @@ -452,6 +545,7 @@ public class WindVortexEntity extends Entity { double scale = this.launchStrength * Mth.clamp(this.getVortexHeight() / 5.0D, 0.5D, 2.5D); entity.setDeltaMovement(tangent.scale(0.72D * scale).add(radial.scale(0.34D * scale)).add(basis.axis.scale((0.78D + progress * 0.28D) * scale))); entity.hasImpulse = true; + this.syncPlayerMotion(entity); } private void hurtCaughtEntity(Entity entity) { @@ -487,12 +581,20 @@ public class WindVortexEntity extends Entity { entity.fallDistance = 0.0F; entity.hasImpulse = true; entity.hurtMarked = true; + this.syncPlayerMotion(entity); if (this.isDamaging() && entity instanceof LivingEntity living && !living.getType().is(AntarchyTags.Entities.WIND_VORTEX_IMMUNE)) { living.hurt(this.damageSource(), this.resolveDamage()); } } + private void syncPlayerMotion(Entity entity) { + if (entity instanceof ServerPlayer player) { + player.hurtMarked = true; + player.connection.send(new ClientboundSetEntityMotionPacket(player)); + } + } + private DamageSource damageSource() { Entity owner = this.getOwnerEntity(); if (owner instanceof LivingEntity living) { @@ -582,6 +684,10 @@ public class WindVortexEntity extends Entity { this.homing = homing; } + public void setBounceOnImpact(boolean bounceOnImpact) { + this.bounceOnImpact = bounceOnImpact; + } + public void setVortexStrengths(double pullStrength, double launchStrength) { this.pullStrength = Math.max(0.0D, pullStrength); this.launchStrength = Math.max(0.0D, launchStrength); @@ -630,6 +736,8 @@ public class WindVortexEntity extends Entity { this.setAxis(new Vec3(tag.getFloat(AXIS_X_KEY), tag.getFloat(AXIS_Y_KEY), tag.getFloat(AXIS_Z_KEY))); this.travelling = tag.getBoolean(TRAVELLING_KEY); this.homing = tag.getBoolean(HOMING_KEY); + this.bounceOnImpact = tag.getBoolean(BOUNCE_ON_IMPACT_KEY); + this.anchoredAtBlock = tag.getBoolean(ANCHORED_KEY); this.travelVelocity = new Vec3(tag.getDouble(TRAVEL_X_KEY), tag.getDouble(TRAVEL_Y_KEY), tag.getDouble(TRAVEL_Z_KEY)); if (this.travelling) { this.noPhysics = true; @@ -654,6 +762,8 @@ public class WindVortexEntity extends Entity { tag.putFloat(AXIS_Z_KEY, (float) this.getAxis().z); tag.putBoolean(TRAVELLING_KEY, this.travelling); tag.putBoolean(HOMING_KEY, this.homing); + tag.putBoolean(BOUNCE_ON_IMPACT_KEY, this.bounceOnImpact); + tag.putBoolean(ANCHORED_KEY, this.anchoredAtBlock); tag.putDouble(TRAVEL_X_KEY, this.travelVelocity.x); tag.putDouble(TRAVEL_Y_KEY, this.travelVelocity.y); tag.putDouble(TRAVEL_Z_KEY, this.travelVelocity.z); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/GravityWalkNodeEvaluator.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/GravityWalkNodeEvaluator.java index b2e088b4..cda49d4f 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/GravityWalkNodeEvaluator.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/GravityWalkNodeEvaluator.java @@ -1,6 +1,8 @@ package com.craisinlord.antarchy.content.gravity; import net.minecraft.util.Mth; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.world.entity.Mob; import net.minecraft.world.level.PathNavigationRegion; import net.minecraft.world.level.pathfinder.Node; @@ -9,6 +11,11 @@ import net.minecraft.world.level.pathfinder.PathfindingContext; import net.minecraft.world.level.pathfinder.WalkNodeEvaluator; public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { + private static final long LOG_TIME_THRESHOLD_NANOS = 25_000_000L; + + private long antarchy$prepareStartNanos; + private int antarchy$nodeProbeCount; + private static final int[] START_Y_SEARCH = {0, 1, -1, 2, -2}; private static final int[][] INVERTED_CARDINAL_NEIGHBOR_OFFSETS = { {1, 0, 0}, @@ -26,10 +33,23 @@ public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { @Override public void prepare(PathNavigationRegion sourceIn, Mob mob) { super.prepare(sourceIn, mob); + this.antarchy$prepareStartNanos = System.nanoTime(); + this.antarchy$nodeProbeCount = 0; } @Override public void done() { + if (this.mob != null && AntarchyGravityApi.isGravityInverted(this.mob)) { + long elapsedNanos = System.nanoTime() - this.antarchy$prepareStartNanos; + if (elapsedNanos > LOG_TIME_THRESHOLD_NANOS) { + com.craisinlord.antarchy.Antarchy.LOGGER.warn( + "[antarchy-gravity] slow inverted pathfind: type={} uuid={} pos=({}, {}, {}) nodeProbes={} elapsedMs={}", + this.mob.getType(), this.mob.getUUID(), + this.mob.getX(), this.mob.getY(), this.mob.getZ(), + this.antarchy$nodeProbeCount, elapsedNanos / 1_000_000.0 + ); + } + } super.done(); } @@ -43,10 +63,9 @@ public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { int z = Mth.floor(this.mob.getZ()); int y = Mth.floor(this.mob.getY() + this.mob.getBbHeight()) - 1; Node node = this.antarchy$findStartNode(x, y, z); - if (node == null) { - return super.getStart(); - } - + // A floor-oriented start is a different coordinate model and must not + // be mixed into an inverted search. PathFinder treats null as a clean + // no-path result. return node; } @@ -66,7 +85,8 @@ public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { } private Node antarchy$createStartNode(int x, int y, int z) { - if (!this.antarchy$hasCeilingSupport(x, y, z)) { + this.antarchy$nodeProbeCount++; + if (!this.antarchy$hasCeilingSupport(this.currentContext, x, y, z)) { return null; } @@ -82,9 +102,16 @@ public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { return node; } - private boolean antarchy$hasCeilingSupport(int x, int y, int z) { - PathType ceilingType = this.getPathType(this.currentContext, x, y + 1, z); - return this.mob.getPathfindingMalus(ceilingType) < 0.0F; + private boolean antarchy$hasCeilingSupport(PathfindingContext context, int x, int y, int z) { + for (int dx = 0; dx < this.entityWidth; dx++) { + for (int dz = 0; dz < this.entityDepth; dz++) { + BlockPos ceilingPos = new BlockPos(x + dx, y + 1, z + dz); + if (!context.level().getBlockState(ceilingPos).isFaceSturdy(context.level(), ceilingPos, Direction.DOWN)) { + return false; + } + } + } + return true; } @Override @@ -93,8 +120,7 @@ public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { return super.getPathTypeOfMob(context, x, y, z, mob); } - PathType ceilingType = this.getPathType(context, x, y + 1, z); - if (mob.getPathfindingMalus(ceilingType) >= 0.0F) { + if (!this.antarchy$hasCeilingSupport(context, x, y, z)) { return PathType.OPEN; } @@ -145,6 +171,18 @@ public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { } } + // Relative "up" for an inverted mob is world-Y down. Keep both + // vertical directions available so a one-block ceiling step can be + // represented in the path instead of trapping the mob below it. + Node stepTowardInvertedUp = this.antarchy$getNeighbor(current.x, current.y - 1, current.z); + if (stepTowardInvertedUp != null) { + neighbors[count++] = stepTowardInvertedUp; + } + Node stepTowardInvertedDown = this.antarchy$getNeighbor(current.x, current.y + 1, current.z); + if (stepTowardInvertedDown != null) { + neighbors[count++] = stepTowardInvertedDown; + } + return count; } @@ -159,12 +197,16 @@ public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { } private Node antarchy$getNeighbor(int x, int y, int z) { + this.antarchy$nodeProbeCount++; PathType type = this.getPathTypeOfMob(this.currentContext, x, y, z, this.mob); - if (this.mob.getPathfindingMalus(type) < 0.0F) { + if (type == PathType.OPEN || this.mob.getPathfindingMalus(type) < 0.0F) { return null; } Node node = this.getNode(x, y, z); + if (node.closed) { + return null; + } node.type = type; node.costMalus = this.mob.getPathfindingMalus(type); return node; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/EyeOfTheStormItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/EyeOfTheStormItem.java index e07ea583..731210d2 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/EyeOfTheStormItem.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/EyeOfTheStormItem.java @@ -137,6 +137,7 @@ public class EyeOfTheStormItem extends Item implements GeoItem { vortex.setDamageOverride(AntarchySettings.eyeOfTheStormSurgeDamage()); vortex.setTravel(dir.scale(SURGE_PROJECTILE_SPEED)); vortex.setHoming(true); + vortex.setBounceOnImpact(true); level.addFreshEntity(vortex); level.playSound(null, origin.x, origin.y, origin.z, diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java index fa0af81b..0ca092fc 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/KrakensGraspItem.java @@ -79,12 +79,14 @@ public class KrakensGraspItem extends TridentItem { public static void strikeLightning(LivingEntity target, ServerLevel level) { strikeLightningAt(level, target.getX(), target.getY(), target.getZ()); + target.hurt(level.damageSources().lightningBolt(), (float) AntarchySettings.krakensGraspLightningDamage()); level.sendParticles(ParticleTypes.ELECTRIC_SPARK, target.getX(), target.getY(0.7D), target.getZ(), 10, 0.25D, 0.25D, 0.25D, 0.02D); } public static void strikeLightningAt(ServerLevel level, double x, double y, double z) { LightningBolt lightningBolt = new LightningBolt(net.minecraft.world.entity.EntityType.LIGHTNING_BOLT, level); lightningBolt.moveTo(x, y, z); + lightningBolt.setVisualOnly(true); level.addFreshEntity(lightningBolt); level.sendParticles(ParticleTypes.ELECTRIC_SPARK, x, y + 0.2D, z, 10, 0.25D, 0.25D, 0.25D, 0.02D); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/ManticoreWingsItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/ManticoreWingsItem.java index fa5ca15e..edd1f17e 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/ManticoreWingsItem.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/ManticoreWingsItem.java @@ -21,7 +21,9 @@ import net.minecraft.world.level.Level; public final class ManticoreWingsItem extends ElytraItem { private static final ResourceLocation REPAIR_MATERIAL_ID = ResourceLocation.fromNamespaceAndPath("antarchy", "manticore_wing"); private static final int DAMAGE_COOLDOWN_TICKS = 10; - private static final float COLLISION_DAMAGE = 8.0F; + private static final double MIN_COLLISION_SPEED = 0.2D; + private static final float COLLISION_DAMAGE_PER_BLOCK_PER_TICK = 8.0F; + private static final float MAX_COLLISION_DAMAGE = 20.0F; private static final Map LAST_COLLISION_DAMAGE = new ConcurrentHashMap<>(); public ManticoreWingsItem(Properties properties) { @@ -41,10 +43,16 @@ public final class ManticoreWingsItem extends ElytraItem { return; } long gameTime = level.getGameTime(); + double speed = player.getDeltaMovement().length(); + if (speed < MIN_COLLISION_SPEED) { + return; + } + float collisionDamage = Math.min(MAX_COLLISION_DAMAGE, + Math.max(1.0F, (float) speed * COLLISION_DAMAGE_PER_BLOCK_PER_TICK)); for (LivingEntity target : level.getEntitiesOfClass(LivingEntity.class, player.getBoundingBox().inflate(0.45D), living -> living != player && living.isAlive() && !player.isAlliedTo(living) && !living.isAlliedTo(player))) { long availableAt = LAST_COLLISION_DAMAGE.getOrDefault(target.getUUID(), 0L); - if (availableAt <= gameTime && target.hurt(level.damageSources().playerAttack(player), COLLISION_DAMAGE)) { + if (availableAt <= gameTime && target.hurt(level.damageSources().playerAttack(player), collisionDamage)) { LAST_COLLISION_DAMAGE.put(target.getUUID(), gameTime + DAMAGE_COOLDOWN_TICKS); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalAssailantArmorItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalAssailantArmorItem.java index 6801f2cd..31734408 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalAssailantArmorItem.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalAssailantArmorItem.java @@ -1,5 +1,6 @@ package com.craisinlord.antarchy.content.item; +import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.item.royal.RoyalGearHelper; @@ -142,8 +143,18 @@ public class RoyalAssailantArmorItem extends ArmorItem { } MobEffectInstance existing = player.getEffect(AntarchyObjects.INVERTED_EFFECT.get()); if (existing != null && existing.isInfiniteDuration()) { + Antarchy.LOGGER.info( + "[antarchy-gravity] royal chestplate toggling inversion off player={} uuid={} pos=({}, {}, {}) dim={} existingDuration={} gameTime={}", + player.getGameProfile().getName(), player.getUUID(), player.getX(), player.getY(), player.getZ(), + player.level().dimension().location(), existing.getDuration(), player.level().getGameTime() + ); player.removeEffect(AntarchyObjects.INVERTED_EFFECT.get()); } else { + Antarchy.LOGGER.info( + "[antarchy-gravity] royal chestplate toggling inversion on player={} uuid={} pos=({}, {}, {}) dim={} existingDuration={} gameTime={}", + player.getGameProfile().getName(), player.getUUID(), player.getX(), player.getY(), player.getZ(), + player.level().dimension().location(), existing != null ? existing.getDuration() : -1, player.level().getGameTime() + ); player.addEffect(new MobEffectInstance(AntarchyObjects.INVERTED_EFFECT.get(), -1, 0, false, false, true)); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationApi.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationApi.java index cf369de1..42f2faa6 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationApi.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationApi.java @@ -65,6 +65,18 @@ public final class TimeDilationApi { SYNCED_CLIENT_RATES.put(entityUuid, clampedRate); } + /** Clears both the authoritative entity state and any client-side UUID cache. */ + public static void clearRate(Entity entity) { + if (entity instanceof TimeDilationEntityAccess access) { + boolean wasDilated = access.antarchy$getTimeDilationRate() < TimeDilationMath.NORMAL_RATE; + access.antarchy$setTimeDilationRate(TimeDilationMath.NORMAL_RATE); + if (wasDilated) { + syncEntityRate(entity, TimeDilationMath.NORMAL_RATE); + } + } + SYNCED_CLIENT_RATES.remove(entity.getUUID()); + } + public static void clearSyncedClientRates() { SYNCED_CLIENT_RATES.clear(); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationManager.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationManager.java index c213de90..00b68271 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationManager.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationManager.java @@ -1,19 +1,16 @@ package com.craisinlord.antarchy.content.time; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.Level; +import com.craisinlord.antarchy.content.effect.DilatedMobEffect; +import com.craisinlord.antarchy.content.effect.RoyalEffectEligibility; +import com.craisinlord.antarchy.content.effect.RoyalEffectHooks; public final class TimeDilationManager { - private static final Set> DILATED_LEVELS = new HashSet<>(); - private TimeDilationManager() { } @@ -21,15 +18,10 @@ public final class TimeDilationManager { for (ServerLevel level : server.getAllLevels()) { List fields = collectFields(level); syncFieldSnapshots(level, fields); - if (fields.isEmpty()) { - if (DILATED_LEVELS.remove(level.dimension())) { - resetRates(level); - } - continue; - } - DILATED_LEVELS.add(level.dimension()); updateEntities(level, fields); - TimeDilationParticles.spawnFieldBorders(level, fields); + if (!fields.isEmpty()) { + TimeDilationParticles.spawnFieldBorders(level, fields); + } } } @@ -60,32 +52,30 @@ public final class TimeDilationManager { if (!(entity instanceof TimeDilationEntityAccess access) || entity instanceof TimeDilationFieldEntity) { continue; } - if (entity.getType().is(com.craisinlord.antarchy.content.AntarchyTags.Entities.TIME_DILATION_IMMUNE)) { - if (access.antarchy$getTimeDilationRate() < TimeDilationMath.NORMAL_RATE) { - access.antarchy$setTimeDilationRate(TimeDilationMath.NORMAL_RATE); - TimeDilationApi.syncEntityRate(entity, TimeDilationMath.NORMAL_RATE); + if (entity.getType().is(com.craisinlord.antarchy.content.AntarchyTags.Entities.TIME_DILATION_IMMUNE) + || (entity instanceof net.minecraft.world.entity.LivingEntity living && !RoyalEffectEligibility.canApplyDilated(living))) { + if (RoyalEffectHooks.dilatedHolder() != null && entity instanceof net.minecraft.world.entity.LivingEntity living) { + living.removeEffect(RoyalEffectHooks.dilatedHolder()); } + TimeDilationApi.clearRate(entity); continue; } double previousRate = access.antarchy$getTimeDilationRate(); - double rate = TimeDilationFieldSampler.sample(fields, entity.position()); - access.antarchy$setTimeDilationRate(rate); - if (Math.abs(previousRate - rate) > 0.001D) { + double fieldRate = TimeDilationFieldSampler.sample(fields, entity.position()); + double effectRate = RoyalEffectHooks.dilatedHolder() != null + && entity instanceof net.minecraft.world.entity.LivingEntity living + && living.hasEffect(RoyalEffectHooks.dilatedHolder()) + ? DilatedMobEffect.RATE : TimeDilationMath.NORMAL_RATE; + double rate = Math.min(fieldRate, effectRate); + if (rate >= TimeDilationMath.NORMAL_RATE) { + TimeDilationApi.clearRate(entity); + } else { + access.antarchy$setTimeDilationRate(rate); + } + if (rate < TimeDilationMath.NORMAL_RATE && Math.abs(previousRate - rate) > 0.001D) { TimeDilationApi.syncEntityRate(entity, rate); } } } - private static void resetRates(ServerLevel level) { - for (Entity entity : level.getAllEntities()) { - if (!(entity instanceof TimeDilationEntityAccess access) || entity instanceof TimeDilationFieldEntity) { - continue; - } - if (access.antarchy$getTimeDilationRate() >= TimeDilationMath.NORMAL_RATE) { - continue; - } - access.antarchy$setTimeDilationRate(TimeDilationMath.NORMAL_RATE); - TimeDilationApi.syncEntityRate(entity, TimeDilationMath.NORMAL_RATE); - } - } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/ElythiaFloraFeature.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/ElythiaFloraFeature.java index baba8d74..0c4db5f2 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/ElythiaFloraFeature.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/ElythiaFloraFeature.java @@ -20,6 +20,8 @@ import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import java.util.HashMap; +import java.util.Map; public class ElythiaFloraFeature extends Feature { private static final String SIZEABLE_FOLIAGE_MODID = "sizeable_foliage"; @@ -38,6 +40,8 @@ public class ElythiaFloraFeature extends Feature { WorldGenLevel level = context.level(); RandomSource random = context.random(); BlockPos origin = context.origin(); + Map surfaceHeightCache = new HashMap<>(); + Map oceanFloorHeightCache = new HashMap<>(); int attempts = switch (this.variant) { case FOREST -> 185; case MEADOW -> 95; @@ -68,7 +72,7 @@ public class ElythiaFloraFeature extends Feature { case FLOWER_FOREST_MILKWEED -> 0.0F; }; if (random.nextFloat() < torchflowerChance) { - placedAny |= this.placeTorchflowerPatch(level, origin, random); + placedAny |= this.placeTorchflowerPatch(level, origin, random, surfaceHeightCache); } } @@ -79,7 +83,7 @@ public class ElythiaFloraFeature extends Feature { case FOREST -> 0.05F; case FLOWER_FOREST_MILKWEED -> 0.0F; }) { - placedAny |= this.placePitcherPatch(level, origin, random); + placedAny |= this.placePitcherPatch(level, origin, random, surfaceHeightCache); } if (random.nextFloat() < switch (this.variant) { case MEADOW -> 0.16F; @@ -88,7 +92,7 @@ public class ElythiaFloraFeature extends Feature { case FOREST -> 0.06F; case FLOWER_FOREST_MILKWEED -> 0.18F; }) { - placedAny |= this.placeMilkweedPatch(level, origin, random, AntarchyObjects.ORANGE_MILKWEED.get()); + placedAny |= this.placeMilkweedPatch(level, origin, random, AntarchyObjects.ORANGE_MILKWEED.get(), surfaceHeightCache); } if (random.nextFloat() < switch (this.variant) { case MEADOW -> 0.16F; @@ -97,20 +101,20 @@ public class ElythiaFloraFeature extends Feature { case FOREST -> 0.06F; case FLOWER_FOREST_MILKWEED -> 0.18F; }) { - placedAny |= this.placeMilkweedPatch(level, origin, random, AntarchyObjects.PINK_MILKWEED.get()); + placedAny |= this.placeMilkweedPatch(level, origin, random, AntarchyObjects.PINK_MILKWEED.get(), surfaceHeightCache); } if (this.variant == Variant.PEACH_FOREST && random.nextFloat() < 0.14F) { - placedAny |= this.placeMilkweedPatch(level, origin, random, antarchyBlock(CAMELLIA_ID)); + placedAny |= this.placeMilkweedPatch(level, origin, random, antarchyBlock(CAMELLIA_ID), surfaceHeightCache); } if (this.variant == Variant.FOREST || this.variant == Variant.PEACH_FOREST) { - placedAny |= this.placeBigBushes(level, origin, random, radius); + placedAny |= this.placeBigBushes(level, origin, random, radius, surfaceHeightCache); } for (int i = 0; i < attempts; i++) { int x = origin.getX() + random.nextInt(radius * 2 + 1) - radius; int z = origin.getZ() + random.nextInt(radius * 2 + 1) - radius; - int y = level.getHeight(Heightmap.Types.WORLD_SURFACE_WG, x, z); + int y = cachedHeight(level, Heightmap.Types.WORLD_SURFACE_WG, x, z, surfaceHeightCache); BlockPos plantPos = new BlockPos(x, y, z); BlockPos groundPos = plantPos.below(); @@ -125,7 +129,7 @@ public class ElythiaFloraFeature extends Feature { } } - placedAny |= this.placeSeagrass(level, origin, random, radius); + placedAny |= this.placeSeagrass(level, origin, random, radius, oceanFloorHeightCache); return placedAny; } @@ -227,7 +231,7 @@ public class ElythiaFloraFeature extends Feature { return block; } - private boolean placeBigBushes(WorldGenLevel level, BlockPos origin, RandomSource random, int radius) { + private boolean placeBigBushes(WorldGenLevel level, BlockPos origin, RandomSource random, int radius, Map surfaceHeightCache) { Block bushBlock = BuiltInRegistries.BLOCK.get(ResourceLocation.fromNamespaceAndPath(SIZEABLE_FOLIAGE_MODID, "big_bush")); if (!(bushBlock instanceof BigBushBlock)) { return false; @@ -241,7 +245,7 @@ public class ElythiaFloraFeature extends Feature { for (int i = 0; i < bushAttempts; i++) { int x = origin.getX() + random.nextInt(radius * 2 + 1) - radius; int z = origin.getZ() + random.nextInt(radius * 2 + 1) - radius; - int y = level.getHeight(Heightmap.Types.WORLD_SURFACE_WG, x, z); + int y = cachedHeight(level, Heightmap.Types.WORLD_SURFACE_WG, x, z, surfaceHeightCache); BlockPos plantPos = new BlockPos(x, y, z); if (!isValidPlantSpot(level, plantPos, plantPos.below())) { @@ -333,8 +337,8 @@ public class ElythiaFloraFeature extends Feature { return true; } - private boolean placeTorchflowerPatch(WorldGenLevel level, BlockPos origin, RandomSource random) { - BlockPos patchCenter = sampleSurface(level, origin, random, this.variant == Variant.FOREST ? 8 : 12); + private boolean placeTorchflowerPatch(WorldGenLevel level, BlockPos origin, RandomSource random, Map surfaceHeightCache) { + BlockPos patchCenter = sampleSurface(level, origin, random, this.variant == Variant.FOREST ? 8 : 12, surfaceHeightCache); if (patchCenter == null) { return false; } @@ -346,7 +350,7 @@ public class ElythiaFloraFeature extends Feature { boolean bushEligible = this.variant == Variant.FOREST || this.variant == Variant.MEADOW; boolean placed = false; for (int i = 0; i < plants; i++) { - BlockPos plantPos = samplePatchPos(level, patchCenter, radius, random); + BlockPos plantPos = samplePatchPos(level, patchCenter, radius, random, surfaceHeightCache); if (plantPos == null) { continue; } @@ -369,8 +373,8 @@ public class ElythiaFloraFeature extends Feature { return placed; } - private boolean placePitcherPatch(WorldGenLevel level, BlockPos origin, RandomSource random) { - BlockPos patchCenter = sampleSurface(level, origin, random, this.variant == Variant.FOREST ? 8 : 13); + private boolean placePitcherPatch(WorldGenLevel level, BlockPos origin, RandomSource random, Map surfaceHeightCache) { + BlockPos patchCenter = sampleSurface(level, origin, random, this.variant == Variant.FOREST ? 8 : 13, surfaceHeightCache); if (patchCenter == null) { return false; } @@ -379,7 +383,7 @@ public class ElythiaFloraFeature extends Feature { int plants = this.variant == Variant.BUTTERFLY_FIELDS ? 10 + random.nextInt(12) : this.variant == Variant.FLOWER_FOREST_MILKWEED ? 2 + random.nextInt(3) : 5 + random.nextInt(11); boolean placed = false; for (int i = 0; i < plants; i++) { - BlockPos plantPos = samplePatchPos(level, patchCenter, radius, random); + BlockPos plantPos = samplePatchPos(level, patchCenter, radius, random, surfaceHeightCache); if (plantPos == null) { continue; } @@ -396,8 +400,8 @@ public class ElythiaFloraFeature extends Feature { return placed; } - private boolean placeMilkweedPatch(WorldGenLevel level, BlockPos origin, RandomSource random, Block flower) { - BlockPos patchCenter = sampleSurface(level, origin, random, this.variant == Variant.FOREST ? 8 : 13); + private boolean placeMilkweedPatch(WorldGenLevel level, BlockPos origin, RandomSource random, Block flower, Map surfaceHeightCache) { + BlockPos patchCenter = sampleSurface(level, origin, random, this.variant == Variant.FOREST ? 8 : 13, surfaceHeightCache); if (patchCenter == null) { return false; } @@ -406,7 +410,7 @@ public class ElythiaFloraFeature extends Feature { int plants = this.variant == Variant.BUTTERFLY_FIELDS ? 14 + random.nextInt(16) : this.variant == Variant.FLOWER_FOREST_MILKWEED ? 2 + random.nextInt(4) : 4 + random.nextInt(9); boolean placed = false; for (int i = 0; i < plants; i++) { - BlockPos plantPos = samplePatchPos(level, patchCenter, radius, random); + BlockPos plantPos = samplePatchPos(level, patchCenter, radius, random, surfaceHeightCache); if (plantPos == null) { continue; } @@ -423,7 +427,7 @@ public class ElythiaFloraFeature extends Feature { return placed; } - private boolean placeSeagrass(WorldGenLevel level, BlockPos origin, RandomSource random, int radius) { + private boolean placeSeagrass(WorldGenLevel level, BlockPos origin, RandomSource random, int radius, Map oceanFloorHeightCache) { int attempts = switch (this.variant) { case FOREST -> 3; case MEADOW -> 5; @@ -436,7 +440,7 @@ public class ElythiaFloraFeature extends Feature { for (int i = 0; i < attempts; i++) { int x = origin.getX() + random.nextInt(radius * 2 + 1) - radius; int z = origin.getZ() + random.nextInt(radius * 2 + 1) - radius; - int y = level.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, x, z); + int y = cachedHeight(level, Heightmap.Types.OCEAN_FLOOR_WG, x, z, oceanFloorHeightCache); BlockPos seagrassPos = new BlockPos(x, y, z); BlockPos floorPos = seagrassPos.below(); @@ -455,11 +459,11 @@ public class ElythiaFloraFeature extends Feature { return placed; } - private static BlockPos sampleSurface(WorldGenLevel level, BlockPos origin, RandomSource random, int radius) { + private static BlockPos sampleSurface(WorldGenLevel level, BlockPos origin, RandomSource random, int radius, Map surfaceHeightCache) { for (int attempt = 0; attempt < 8; attempt++) { int x = origin.getX() + random.nextInt(radius * 2 + 1) - radius; int z = origin.getZ() + random.nextInt(radius * 2 + 1) - radius; - int y = level.getHeight(Heightmap.Types.WORLD_SURFACE_WG, x, z); + int y = cachedHeight(level, Heightmap.Types.WORLD_SURFACE_WG, x, z, surfaceHeightCache); BlockPos plantPos = new BlockPos(x, y, z); if (isValidPlantSpot(level, plantPos, plantPos.below())) { return plantPos; @@ -468,14 +472,25 @@ public class ElythiaFloraFeature extends Feature { return null; } - private static BlockPos samplePatchPos(WorldGenLevel level, BlockPos center, int radius, RandomSource random) { + private static BlockPos samplePatchPos(WorldGenLevel level, BlockPos center, int radius, RandomSource random, Map surfaceHeightCache) { int x = center.getX() + random.nextInt(radius * 2 + 1) - radius; int z = center.getZ() + random.nextInt(radius * 2 + 1) - radius; - int y = level.getHeight(Heightmap.Types.WORLD_SURFACE_WG, x, z); + int y = cachedHeight(level, Heightmap.Types.WORLD_SURFACE_WG, x, z, surfaceHeightCache); BlockPos plantPos = new BlockPos(x, y, z); return isOpenPlantSpot(level, plantPos) ? plantPos : null; } + private static int cachedHeight(WorldGenLevel level, Heightmap.Types type, int x, int z, Map cache) { + long key = ((long) x << 32) ^ (z & 0xFFFFFFFFL); + Integer cached = cache.get(key); + if (cached != null) { + return cached; + } + int height = level.getHeight(type, x, z); + cache.put(key, height); + return height; + } + private static void normalizePeachForestGround(WorldGenLevel level, BlockPos groundPos, Variant variant) { if (variant != Variant.PEACH_FOREST) { return; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/OuranwoodTreeFeature.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/OuranwoodTreeFeature.java index 8b96e8e3..9dd44aad 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/OuranwoodTreeFeature.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/OuranwoodTreeFeature.java @@ -7,7 +7,10 @@ import com.craisinlord.antarchy.content.block.OuranwoodLeavesBlock; import com.craisinlord.antarchy.content.entity.flying_squirrel.FlyingSquirrelEntity; import com.mojang.serialization.Codec; import java.util.ArrayList; +import java.util.ArrayDeque; +import java.util.HashMap; import java.util.List; +import java.util.Map; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; @@ -1113,43 +1116,87 @@ public class OuranwoodTreeFeature extends Feature { int minY = Math.max(level.getMinBuildHeight(), origin.getY() - 2); int maxY = Math.min(level.getMaxBuildHeight() - 1, origin.getY() + height + canopyDepth + 8); List leafPositions = new ArrayList<>(); + Map distances = new HashMap<>(); + ArrayDeque queue = new ArrayDeque<>(); BlockPos.MutableBlockPos cursor = new BlockPos.MutableBlockPos(); for (int x = origin.getX() - horizontalRadius; x <= origin.getX() + horizontalRadius; x++) { for (int z = origin.getZ() - horizontalRadius; z <= origin.getZ() + horizontalRadius; z++) { for (int y = minY; y <= maxY; y++) { cursor.set(x, y, z); - if (level.getBlockState(cursor).getBlock() instanceof LeavesBlock) { - leafPositions.add(cursor.immutable()); + BlockState state = level.getBlockState(cursor); + if (state.getBlock() instanceof LeavesBlock && this.getLeafDistanceProperty(state) != null) { + BlockPos pos = cursor.immutable(); + leafPositions.add(pos); + distances.put(pos, this.getLeafDistanceLimit(state)); } } } } - for (int pass = 1; pass <= 16; pass++) { - boolean anyChanged = false; - for (BlockPos pos : leafPositions) { - BlockState state = level.getBlockState(pos); - IntegerProperty distanceProperty = this.getLeafDistanceProperty(state); - if (!(state.getBlock() instanceof LeavesBlock) || distanceProperty == null) { - continue; + for (BlockPos pos : leafPositions) { + BlockState state = level.getBlockState(pos); + int limit = this.getLeafDistanceLimit(state); + int bestDistance = limit; + for (Direction direction : Direction.values()) { + BlockPos neighborPos = pos.relative(direction); + BlockState neighbor = level.getBlockState(neighborPos); + if (neighbor.is(BlockTags.LOGS)) { + bestDistance = 1; + break; } - int computedDistance = this.computeLeafDistance(level, pos, state); - if (computedDistance == state.getValue(distanceProperty)) { - continue; + if (!distances.containsKey(neighborPos)) { + IntegerProperty neighborProperty = this.getLeafDistanceProperty(neighbor); + if (neighborProperty != null) { + bestDistance = Math.min(bestDistance, neighbor.getValue(neighborProperty) + 1); + } } - - BlockState updatedState; - if (state.getBlock() instanceof OuranwoodLeavesBlock) { - updatedState = OuranwoodLeavesBlock.setOuranwoodDistanceForWorldgen(state, computedDistance); - } else { - updatedState = state.setValue(distanceProperty, computedDistance); - } - setBlock(level, pos, updatedState); - anyChanged = true; } - if (!anyChanged) break; + if (bestDistance < distances.get(pos)) { + distances.put(pos, bestDistance); + queue.add(pos); + } + } + + while (!queue.isEmpty()) { + BlockPos pos = queue.removeFirst(); + int distance = distances.get(pos); + for (Direction direction : Direction.values()) { + BlockPos neighborPos = pos.relative(direction); + Integer neighborDistance = distances.get(neighborPos); + if (neighborDistance == null) { + continue; + } + + BlockState neighborState = level.getBlockState(neighborPos); + int candidate = Math.min(this.getLeafDistanceLimit(neighborState), distance + 1); + if (candidate < neighborDistance) { + distances.put(neighborPos, candidate); + queue.addLast(neighborPos); + } + } + } + + for (BlockPos pos : leafPositions) { + BlockState state = level.getBlockState(pos); + IntegerProperty distanceProperty = this.getLeafDistanceProperty(state); + if (distanceProperty == null) { + continue; + } + + int computedDistance = distances.get(pos); + if (computedDistance == state.getValue(distanceProperty)) { + continue; + } + + BlockState updatedState; + if (state.getBlock() instanceof OuranwoodLeavesBlock) { + updatedState = OuranwoodLeavesBlock.setOuranwoodDistanceForWorldgen(state, computedDistance); + } else { + updatedState = state.setValue(distanceProperty, computedDistance); + } + setBlock(level, pos, updatedState); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisIchorLakeFeature.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisIchorLakeFeature.java new file mode 100644 index 00000000..fec5c963 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisIchorLakeFeature.java @@ -0,0 +1,63 @@ +package com.craisinlord.antarchy.content.worldgen.thoraxis; + +import com.craisinlord.antarchy.Antarchy; +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +/** + * Fills the low, open main-side Thoraxis basin with source ichor during chunk generation. + * The feature works one chunk at a time so it does not depend on runtime fluid spreading. + */ +public final class ThoraxisIchorLakeFeature extends Feature { + private static final int LAKE_FLOOR_Y = 1; + private static final int LAKE_SURFACE_Y = 8; + private static final ResourceLocation ICHOR_BLOCK_ID = + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "ichor"); + + public ThoraxisIchorLakeFeature(Codec codec) { + super(codec); + } + + @Override + public boolean place(FeaturePlaceContext context) { + WorldGenLevel level = context.level(); + BlockPos origin = context.origin(); + BlockState ichorState = BuiltInRegistries.BLOCK.get(ICHOR_BLOCK_ID).defaultBlockState(); + if (ichorState.isAir() || ichorState.getFluidState().isEmpty()) { + return false; + } + + int chunkMinX = origin.getX() >> 4 << 4; + int chunkMinZ = origin.getZ() >> 4 << 4; + boolean placedAny = false; + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + + for (int x = chunkMinX; x < chunkMinX + 16; x++) { + for (int z = chunkMinZ; z < chunkMinZ + 16; z++) { + for (int y = LAKE_FLOOR_Y; y <= LAKE_SURFACE_Y; y++) { + mutable.set(x, y, z); + BlockState current = level.getBlockState(mutable); + if (!isOpenForLake(current)) { + continue; + } + + level.setBlock(mutable, ichorState, 2); + placedAny = true; + } + } + } + + return placedAny; + } + + private static boolean isOpenForLake(BlockState state) { + return state.isAir() || state.canBeReplaced() || !state.blocksMotion(); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisUndersideManager.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisUndersideManager.java index f27b3ba5..04e3ba75 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisUndersideManager.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisUndersideManager.java @@ -35,6 +35,8 @@ public final class ThoraxisUndersideManager { private static final int DISCOVERY_INTERVAL_TICKS = 5; private static final int SIMULATION_DISTANCE_MARGIN_CHUNKS = 1; private static final int MAX_FLIPS_PER_TICK = 8; + private static final double SLOW_TICK_WARN_MS = 25.0D; + private static final long DIAGNOSTIC_INTERVAL_TICKS = 100L; private static final int ENTER_UNDERSIDE_Y = GRAVITY_FLIP_Y - 4; private static final int EXIT_UNDERSIDE_Y = GRAVITY_FLIP_Y + 4; private static final int FLIP_COOLDOWN_TICKS = 40; @@ -55,12 +57,20 @@ public final class ThoraxisUndersideManager { return; } + long startNanos = System.nanoTime(); long now = level.getGameTime(); + int discoveredLiving = 0; + int discoveredItems = 0; if (now % DISCOVERY_INTERVAL_TICKS == 0L) { - tracking.discover(level); + DiscoveryStats stats = tracking.discover(level); + discoveredLiving = stats.livingEntities(); + discoveredItems = stats.itemEntities(); } int flipsRemaining = MAX_FLIPS_PER_TICK; + int refreshedLiving = 0; + int flippedItems = 0; + int restoredItems = 0; for (Entity entity : tracking.entities) { if (!entity.isAlive() || entity.isSpectator()) { continue; @@ -71,6 +81,7 @@ public final class ThoraxisUndersideManager { int threshold = hasEffect ? EXIT_UNDERSIDE_Y : ENTER_UNDERSIDE_Y; if (living.getY() < threshold) { refreshInvertedEffect(living); + refreshedLiving++; } continue; } @@ -94,6 +105,7 @@ public final class ThoraxisUndersideManager { flipsRemaining--; tracking.lastFlipTick.put(uuid, now); AntarchyGravityApi.setForcedGravityDirection(entity, AntarchyGravityDirection.UP, TRANSITION); + flippedItems++; } continue; } @@ -108,6 +120,7 @@ public final class ThoraxisUndersideManager { if (isForcedUp) { tracking.lastFlipTick.put(uuid, now); AntarchyGravityApi.setGravityDirection(entity, AntarchyGravityDirection.DOWN, false, TRANSITION); + restoredItems++; } } } @@ -115,26 +128,44 @@ public final class ThoraxisUndersideManager { tracking.entities.removeIf(entity -> !entity.isAlive() || entity.isRemoved()); tracking.forcedItems.removeIf(entity -> !entity.isAlive() || entity.isRemoved()); tracking.lastFlipTick.entrySet().removeIf(entry -> now - entry.getValue() > FLIP_COOLDOWN_TICKS * 4L); + + double elapsedMs = (System.nanoTime() - startNanos) / 1_000_000.0D; + if (elapsedMs >= SLOW_TICK_WARN_MS && now - tracking.lastDiagnosticTick >= DIAGNOSTIC_INTERVAL_TICKS) { + tracking.lastDiagnosticTick = now; + Antarchy.LOGGER.warn( + "[antarchy-thoraxis] slow underside tick dim={} gameTime={} elapsedMs={} trackedEntities={} forcedItems={} discoveredLiving={} discoveredItems={} refreshedLiving={} flippedItems={} restoredItems={} players={}", + level.dimension().location(), now, elapsedMs, tracking.entities.size(), tracking.forcedItems.size(), + discoveredLiving, discoveredItems, refreshedLiving, flippedItems, restoredItems, level.players().size() + ); + } } private static final class TrackingState { private final Set entities = Collections.newSetFromMap(new IdentityHashMap<>()); private final Set forcedItems = Collections.newSetFromMap(new IdentityHashMap<>()); private final Map lastFlipTick = new java.util.HashMap<>(); + private long lastDiagnosticTick = Long.MIN_VALUE / 2L; - private void discover(ServerLevel level) { + private DiscoveryStats discover(ServerLevel level) { int radius = (level.getServer().getPlayerList().getSimulationDistance() + SIMULATION_DISTANCE_MARGIN_CHUNKS) * 16; + int discoveredLiving = 0; + int discoveredItems = 0; for (ServerPlayer player : level.players()) { AABB area = new AABB( player.getX() - radius, level.getMinBuildHeight(), player.getZ() - radius, player.getX() + radius, level.getMaxBuildHeight(), player.getZ() + radius ); entities.add(player); - entities.addAll(level.getEntitiesOfClass(LivingEntity.class, area, - entity -> !entity.isSpectator() && entity.getY() < EXIT_UNDERSIDE_Y)); - entities.addAll(level.getEntitiesOfClass(ItemEntity.class, area, - entity -> !entity.isSpectator() && entity.getY() < EXIT_UNDERSIDE_Y)); + java.util.List livingEntities = level.getEntitiesOfClass(LivingEntity.class, area, + entity -> !entity.isSpectator() && entity.getY() < EXIT_UNDERSIDE_Y); + java.util.List itemEntities = level.getEntitiesOfClass(ItemEntity.class, area, + entity -> !entity.isSpectator() && entity.getY() < EXIT_UNDERSIDE_Y); + discoveredLiving += livingEntities.size(); + discoveredItems += itemEntities.size(); + entities.addAll(livingEntities); + entities.addAll(itemEntities); } + return new DiscoveryStats(discoveredLiving, discoveredItems); } private void clear() { @@ -149,6 +180,9 @@ public final class ThoraxisUndersideManager { return last == null || now - last >= FLIP_COOLDOWN_TICKS; } + private record DiscoveryStats(int livingEntities, int itemEntities) { + } + public static void applyUndersideInversion(LivingEntity living) { refreshInvertedEffect(living); } @@ -184,4 +218,8 @@ public final class ThoraxisUndersideManager { public static boolean isThoraxis(Level level) { return level.dimension().location().equals(THORAXIS_DIMENSION); } + + public static boolean isAboveUndersideExit(Entity entity) { + return isThoraxis(entity.level()) && entity.getY() >= EXIT_UNDERSIDE_Y; + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/truffalo/TruffaloTreeConfiguration.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/truffalo/TruffaloTreeConfiguration.java index e0654ec1..806d6eb3 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/truffalo/TruffaloTreeConfiguration.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/truffalo/TruffaloTreeConfiguration.java @@ -8,10 +8,14 @@ import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvi public record TruffaloTreeConfiguration( BlockStateProvider trunkProvider, - IntProvider height + IntProvider height, + int tuftRadius, + int tuftHeight ) implements FeatureConfiguration { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( BlockStateProvider.CODEC.fieldOf("trunk_provider").forGetter(TruffaloTreeConfiguration::trunkProvider), - IntProvider.codec(4, 9).fieldOf("height").forGetter(TruffaloTreeConfiguration::height) + IntProvider.codec(4, 18).fieldOf("height").forGetter(TruffaloTreeConfiguration::height), + Codec.INT.optionalFieldOf("tuft_radius", 1).forGetter(TruffaloTreeConfiguration::tuftRadius), + Codec.INT.optionalFieldOf("tuft_height", 3).forGetter(TruffaloTreeConfiguration::tuftHeight) ).apply(instance, TruffaloTreeConfiguration::new)); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/truffalo/TruffaloTreeFeature.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/truffalo/TruffaloTreeFeature.java index 25dd4374..1e570985 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/truffalo/TruffaloTreeFeature.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/truffalo/TruffaloTreeFeature.java @@ -58,9 +58,9 @@ public class TruffaloTreeFeature extends Feature { return false; } } - for (int dy = 0; dy <= 2; dy++) { - for (int dx = -1; dx <= 1; dx++) { - for (int dz = -1; dz <= 1; dz++) { + for (int dy = 0; dy < config.tuftHeight(); dy++) { + for (int dx = -config.tuftRadius(); dx <= config.tuftRadius(); dx++) { + for (int dz = -config.tuftRadius(); dz <= config.tuftRadius(); dz++) { if (!canReplace(level, capBase.offset(dx, dy, dz))) { return false; } @@ -74,9 +74,9 @@ public class TruffaloTreeFeature extends Feature { Block tuft = BuiltInRegistries.BLOCK.get(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, color.getName() + "_truffalo_tuft")); BlockState tuftState = tuft.defaultBlockState(); - for (int dy = 0; dy <= 2; dy++) { - for (int dx = -1; dx <= 1; dx++) { - for (int dz = -1; dz <= 1; dz++) { + for (int dy = 0; dy < config.tuftHeight(); dy++) { + for (int dx = -config.tuftRadius(); dx <= config.tuftRadius(); dx++) { + for (int dz = -config.tuftRadius(); dz <= config.tuftRadius(); dz++) { setBlock(level, capBase.offset(dx, dy, dz), tuftState); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/CommandedMobMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/CommandedMobMixin.java new file mode 100644 index 00000000..0dd0ff3f --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/CommandedMobMixin.java @@ -0,0 +1,52 @@ +package com.craisinlord.antarchy.mixins; + +import com.craisinlord.antarchy.content.effect.CommandedEntityAccess; +import java.util.UUID; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.Mob; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(Mob.class) +public abstract class CommandedMobMixin implements CommandedEntityAccess { + @Unique + private UUID antarchy$commanderUuid; + @Unique + private boolean antarchy$commandedTargetOwned; + + @Override + public UUID antarchy$getCommanderUuid() { + return antarchy$commanderUuid; + } + + @Override + public void antarchy$setCommanderUuid(UUID uuid) { + antarchy$commanderUuid = uuid; + } + + @Override + public boolean antarchy$isCommandedTargetOwned() { + return antarchy$commandedTargetOwned; + } + + @Override + public void antarchy$setCommandedTargetOwned(boolean owned) { + antarchy$commandedTargetOwned = owned; + } + + @org.spongepowered.asm.mixin.injection.Inject(method = "addAdditionalSaveData", at = @org.spongepowered.asm.mixin.injection.At("TAIL")) + private void antarchy$saveCommandedData(CompoundTag tag, org.spongepowered.asm.mixin.injection.callback.CallbackInfo ci) { + if (antarchy$commanderUuid != null) { + tag.putUUID("AntarchyCommander", antarchy$commanderUuid); + tag.putBoolean("AntarchyCommandedTargetOwned", antarchy$commandedTargetOwned); + } + } + + @org.spongepowered.asm.mixin.injection.Inject(method = "readAdditionalSaveData", at = @org.spongepowered.asm.mixin.injection.At("TAIL")) + private void antarchy$loadCommandedData(CompoundTag tag, org.spongepowered.asm.mixin.injection.callback.CallbackInfo ci) { + if (tag.hasUUID("AntarchyCommander")) { + antarchy$commanderUuid = tag.getUUID("AntarchyCommander"); + antarchy$commandedTargetOwned = tag.getBoolean("AntarchyCommandedTargetOwned"); + } + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/LivingEntityRoyalEffectsMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/LivingEntityRoyalEffectsMixin.java new file mode 100644 index 00000000..f9e325c6 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/LivingEntityRoyalEffectsMixin.java @@ -0,0 +1,90 @@ +package com.craisinlord.antarchy.mixins; + +import com.craisinlord.antarchy.content.effect.CommandedEntityAccess; +import com.craisinlord.antarchy.content.effect.RoyalEffectEligibility; +import java.util.UUID; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.AreaEffectCloud; +import net.minecraft.world.entity.projectile.Projectile; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(LivingEntity.class) +public abstract class LivingEntityRoyalEffectsMixin { + @Unique + private UUID antarchy$previousCommander; + + @Inject(method = "canBeAffected", at = @At("HEAD"), cancellable = true) + private void antarchy$checkRoyalEffectBlacklist(MobEffectInstance instance, CallbackInfoReturnable cir) { + if (!RoyalEffectEligibility.canApply((LivingEntity) (Object) this, instance)) { + cir.setReturnValue(false); + } + } + + @Inject(method = "addEffect(Lnet/minecraft/world/effect/MobEffectInstance;Lnet/minecraft/world/entity/Entity;)Z", at = @At("HEAD"), cancellable = true) + private void antarchy$prepareCommandedSource(MobEffectInstance instance, Entity source, CallbackInfoReturnable cir) { + if (!RoyalEffectEligibility.isCommanded(instance)) { + return; + } + LivingEntity entity = (LivingEntity) (Object) this; + if (!RoyalEffectEligibility.canApplyCommanded(entity) || !(entity instanceof Mob mob)) { + cir.setReturnValue(false); + return; + } + PlayerSource playerSource = antarchy$resolvePlayer(source); + if (playerSource == null) { + cir.setReturnValue(false); + return; + } + CommandedEntityAccess access = (CommandedEntityAccess) mob; + UUID current = access.antarchy$getCommanderUuid(); + if (current != null && !current.equals(playerSource.player().getUUID())) { + cir.setReturnValue(false); + return; + } + antarchy$previousCommander = current; + access.antarchy$setCommanderUuid(playerSource.player().getUUID()); + } + + @Inject(method = "addEffect(Lnet/minecraft/world/effect/MobEffectInstance;Lnet/minecraft/world/entity/Entity;)Z", at = @At("RETURN")) + private void antarchy$finishCommandedSource(MobEffectInstance instance, Entity source, CallbackInfoReturnable cir) { + if (!RoyalEffectEligibility.isCommanded(instance) || cir.getReturnValue()) { + return; + } + LivingEntity entity = (LivingEntity) (Object) this; + if (entity instanceof CommandedEntityAccess access) { + access.antarchy$setCommanderUuid(antarchy$previousCommander); + } + } + + @Inject(method = "onEffectRemoved", at = @At("HEAD")) + private void antarchy$clearCommandedState(MobEffectInstance instance, org.spongepowered.asm.mixin.injection.callback.CallbackInfo ci) { + if (RoyalEffectEligibility.isCommanded(instance) && (Object) this instanceof Mob mob) { + com.craisinlord.antarchy.content.effect.CommandedBehavior.clear(mob); + } + } + + @Unique + private PlayerSource antarchy$resolvePlayer(Entity source) { + if (source instanceof net.minecraft.world.entity.player.Player player) { + return new PlayerSource(player); + } + if (source instanceof Projectile projectile && projectile.getOwner() instanceof net.minecraft.world.entity.player.Player player) { + return new PlayerSource(player); + } + if (source instanceof AreaEffectCloud cloud && cloud.getOwner() instanceof net.minecraft.world.entity.player.Player player) { + return new PlayerSource(player); + } + return null; + } + + @Unique + private record PlayerSource(net.minecraft.world.entity.player.Player player) { + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/MobCommandedTargetMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/MobCommandedTargetMixin.java new file mode 100644 index 00000000..25e33859 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/MobCommandedTargetMixin.java @@ -0,0 +1,29 @@ +package com.craisinlord.antarchy.mixins; + +import com.craisinlord.antarchy.content.effect.CommandedBehavior; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +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.CallbackInfo; + +@Mixin(Mob.class) +public abstract class MobCommandedTargetMixin { + @Inject(method = "setTarget", at = @At("HEAD"), cancellable = true) + private void antarchy$protectCommandedAllies(LivingEntity target, CallbackInfo ci) { + Mob mob = (Mob) (Object) this; + if (target != null && CommandedBehavior.isProtectedAlly(mob, target)) { + ci.cancel(); + } + } + + @Inject(method = "doHurtTarget", at = @At("HEAD"), cancellable = true) + private void antarchy$preventCommandedFriendlyFire(net.minecraft.world.entity.Entity target, + org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable cir) { + Mob mob = (Mob) (Object) this; + if (CommandedBehavior.isProtectedAlly(mob, target)) { + cir.setReturnValue(false); + } + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/EntityGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/EntityGravityMixin.java index 72db7976..620a4975 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/EntityGravityMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/EntityGravityMixin.java @@ -5,10 +5,16 @@ import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import com.craisinlord.antarchy.content.gravity.AntarchyGravityTransition; +import com.craisinlord.antarchy.content.entity.BedBugEntity; +import com.craisinlord.antarchy.content.entity.portal.DimensionalTearEntity; +import com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisUndersideManager; import net.minecraft.nbt.CompoundTag; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.AABB; import org.spongepowered.asm.mixin.Mixin; @@ -71,6 +77,51 @@ public abstract class EntityGravityMixin implements AntarchyGravityAccess { this.antarchy$gravityForced = tag.getBoolean(ANTARCHY_GRAVITY_FORCED_TAG); this.antarchy$gravityTransitionDuration = Math.max(0, tag.getInt(ANTARCHY_GRAVITY_TRANSITION_DURATION_TAG)); this.antarchy$gravityTransitionRemaining = Math.max(0, tag.getInt(ANTARCHY_GRAVITY_TRANSITION_REMAINING_TAG)); + + Entity entity = this.antarchy$entity(); + if (this.antarchy$gravityDirection.isInverted() && this.antarchy$gravityForced + && entity instanceof Mob mob) { + MobEffectInstance invertedEffect = mob.getEffect(com.craisinlord.antarchy.content.AntarchyObjects.INVERTED_EFFECT.get()); + boolean aboveUndersideExit = ThoraxisUndersideManager.isAboveUndersideExit(mob); + int nearbyDimensionalTears = this.antarchy$countNearbyDimensionalTears(mob); + if (invertedEffect != null + && invertedEffect.isAmbient() + && !invertedEffect.isVisible() + && aboveUndersideExit) { + this.antarchy$clearLoadedInversion(mob); + com.craisinlord.antarchy.Antarchy.LOGGER.warn( + "[antarchy-gravity] cleared stale underside inversion from loaded mob type={} uuid={} pos=({}, {}, {}) dim={} effectDuration={} nearbyDimensionalTears={}", + mob.getType(), mob.getUUID(), mob.getX(), mob.getY(), mob.getZ(), + mob.level() != null ? mob.level().dimension().location() : "?", + invertedEffect.getDuration(), nearbyDimensionalTears + ); + return; + } + if (invertedEffect != null + && mob instanceof BedBugEntity + && aboveUndersideExit + && ThoraxisUndersideManager.isThoraxis(mob.level())) { + this.antarchy$clearLoadedInversion(mob); + com.craisinlord.antarchy.Antarchy.LOGGER.warn( + "[antarchy-gravity] cleared loaded inverted bed bug above underside exit type={} uuid={} pos=({}, {}, {}) dim={} effectDuration={} effectAmbient={} effectVisible={} nearbyDimensionalTears={}", + mob.getType(), mob.getUUID(), mob.getX(), mob.getY(), mob.getZ(), + mob.level() != null ? mob.level().dimension().location() : "?", + invertedEffect.getDuration(), invertedEffect.isAmbient(), invertedEffect.isVisible(), nearbyDimensionalTears + ); + return; + } + com.craisinlord.antarchy.Antarchy.LOGGER.info( + "[antarchy-gravity] loaded inverted mob type={} uuid={} pos=({}, {}, {}) dim={} hasInvertedEffect={} effectDuration={} effectAmbient={} effectVisible={} aboveUndersideExit={} nearbyDimensionalTears={}", + mob.getType(), mob.getUUID(), mob.getX(), mob.getY(), mob.getZ(), + mob.level() != null ? mob.level().dimension().location() : "?", + invertedEffect != null, + invertedEffect != null ? invertedEffect.getDuration() : -1, + invertedEffect != null && invertedEffect.isAmbient(), + invertedEffect != null && invertedEffect.isVisible(), + aboveUndersideExit, + nearbyDimensionalTears + ); + } } @Inject(method = "baseTick", at = @At("TAIL")) @@ -134,6 +185,11 @@ public abstract class EntityGravityMixin implements AntarchyGravityAccess { } this.antarchy$gravityForced = forced; + if (changed && this.antarchy$entity() instanceof Mob mob) { + // Any existing path is expressed in the previous gravity frame. + // Keep goals from following stale nodes after a flip. + mob.getNavigation().stop(); + } if (changed && !this.antarchy$entity().level().isClientSide) { AntarchyGravityApi.notifyGravityStateChanged(this.antarchy$entity()); } @@ -172,6 +228,29 @@ public abstract class EntityGravityMixin implements AntarchyGravityAccess { this.setBoundingBox(this.makeBoundingBox()); } + @Unique + private void antarchy$clearLoadedInversion(Mob mob) { + mob.removeEffect(com.craisinlord.antarchy.content.AntarchyObjects.INVERTED_EFFECT.get()); + this.antarchy$gravityDirection = AntarchyGravityDirection.DOWN; + this.antarchy$prevGravityDirection = AntarchyGravityDirection.DOWN; + this.antarchy$gravityForced = false; + this.antarchy$gravityTransitionDuration = 0; + this.antarchy$gravityTransitionRemaining = 0; + this.antarchy$refreshGravityBounds(); + } + + @Unique + private int antarchy$countNearbyDimensionalTears(Mob mob) { + if (!(mob.level() instanceof ServerLevel serverLevel)) { + return -1; + } + return serverLevel.getEntitiesOfClass( + DimensionalTearEntity.class, + mob.getBoundingBox().inflate(48.0D), + Entity::isAlive + ).size(); + } + @Unique private void antarchy$adjustPositionForGravityChange(AntarchyGravityDirection oldDirection, AntarchyGravityDirection newDirection) { if (oldDirection == newDirection) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/GroundPathNavigationMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/GroundPathNavigationMixin.java index fc10d605..6442a003 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/GroundPathNavigationMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/GroundPathNavigationMixin.java @@ -1,26 +1,89 @@ package com.craisinlord.antarchy.mixins.gravity; -import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; import com.craisinlord.antarchy.content.gravity.GravityWalkNodeEvaluator; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.entity.EntityDimensions; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.navigation.GroundPathNavigation; import net.minecraft.world.level.pathfinder.NodeEvaluator; import net.minecraft.world.level.pathfinder.PathFinder; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; 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(GroundPathNavigation.class) -/* - * Makes ground pathing read gravity-aware floor checks. - */ public abstract class GroundPathNavigationMixin { @Inject(method = "createPathFinder", at = @At("HEAD"), cancellable = true) private void antarchy$useGravityEvaluator(int maxVisitedNodes, CallbackInfoReturnable cir) { var accessor = (PathNavigationAccessor) (Object) this; - var mob = accessor.antarchy$getMob(); NodeEvaluator evaluator = new GravityWalkNodeEvaluator(); + // GroundPathNavigation enables door passing on its vanilla evaluator. + // Preserve that setting when swapping in the gravity-aware evaluator. + evaluator.setCanPassDoors(true); accessor.antarchy$setNodeEvaluator(evaluator); cir.setReturnValue(new PathFinder(evaluator, maxVisitedNodes)); } + + /** + * GroundPathNavigation normalizes entity destinations toward the floor + * before delegating to PathNavigation. For inverted mobs, replace that + * final destination with a bounded, collision-free ceiling anchor. + */ + @org.spongepowered.asm.mixin.injection.ModifyArg( + method = "createPath(Lnet/minecraft/core/BlockPos;I)Lnet/minecraft/world/level/pathfinder/Path;", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/entity/ai/navigation/PathNavigation;createPath(Lnet/minecraft/core/BlockPos;I)Lnet/minecraft/world/level/pathfinder/Path;" + ), + index = 0 + ) + private BlockPos antarchy$projectInvertedDestination(BlockPos normalizedDestination) { + Mob mob = ((PathNavigationAccessor) (Object) this).antarchy$getMob(); + if (!AntarchyGravityApi.isGravityInverted(mob)) { + return normalizedDestination; + } + + EntityDimensions dimensions = mob.getDimensions(mob.getPose()); + int centerX = normalizedDestination.getX(); + int centerZ = normalizedDestination.getZ(); + int baseY = normalizedDestination.getY(); + int minY = Math.max(mob.level().getMinBuildHeight(), baseY - 32); + int maxY = Math.min(mob.level().getMaxBuildHeight() - 2, baseY + 32); + for (int candidateY = baseY; candidateY <= maxY; candidateY++) { + BlockPos support = new BlockPos(centerX, candidateY + 1, centerZ); + if (!mob.level().getBlockState(support).isFaceSturdy(mob.level(), support, Direction.DOWN)) { + continue; + } + + double topY = candidateY + 1.0D - 1.0E-3D; + double halfWidth = dimensions.width() / 2.0D; + AABB body = new AABB( + centerX + 0.5D - halfWidth, + topY - dimensions.height(), + centerZ + 0.5D - halfWidth, + centerX + 0.5D + halfWidth, + topY, + centerZ + 0.5D + halfWidth + ).deflate(1.0E-4D); + if (mob.level().noCollision(mob, body)) { + return new BlockPos(centerX, candidateY, centerZ); + } + } + + return normalizedDestination; + } + + @Inject(method = "getTempMobPos", at = @At("HEAD"), cancellable = true) + private void antarchy$useInvertedMobAnchor(CallbackInfoReturnable cir) { + Mob mob = ((PathNavigationAccessor) (Object) this).antarchy$getMob(); + if (AntarchyGravityApi.isGravityInverted(mob)) { + cir.setReturnValue(new Vec3(mob.getX(), mob.getY(), mob.getZ())); + } + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/MeleeAttackGoalGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/MeleeAttackGoalGravityMixin.java new file mode 100644 index 00000000..d69998dc --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/MeleeAttackGoalGravityMixin.java @@ -0,0 +1,101 @@ +package com.craisinlord.antarchy.mixins.gravity; + +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.PathfinderMob; +import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; +import net.minecraft.world.entity.player.Player; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(MeleeAttackGoal.class) +public abstract class MeleeAttackGoalGravityMixin { + @Shadow + @Final + protected PathfinderMob mob; + + @Shadow + @Final + private double speedModifier; + + @Shadow + @Final + private boolean followingTargetEvenIfNotSeen; + + @Shadow + private int ticksUntilNextAttack; + + @Shadow + protected abstract void checkAndPerformAttack(LivingEntity enemy); + + @Inject(method = "canUse", at = @At("HEAD"), cancellable = true) + private void antarchy$useInvertedMelee(CallbackInfoReturnable cir) { + if (!AntarchyGravityApi.isGravityInverted(this.mob)) { + return; + } + + LivingEntity target = this.mob.getTarget(); + cir.setReturnValue(this.antarchy$isValidInvertedMeleeTarget(target)); + } + + @Inject(method = "canContinueToUse", at = @At("HEAD"), cancellable = true) + private void antarchy$continueInvertedMelee(CallbackInfoReturnable cir) { + if (!AntarchyGravityApi.isGravityInverted(this.mob)) { + return; + } + + LivingEntity target = this.mob.getTarget(); + cir.setReturnValue(this.antarchy$isValidInvertedMeleeTarget(target)); + } + + @Inject(method = "start", at = @At("HEAD"), cancellable = true) + private void antarchy$startInvertedMelee(CallbackInfo ci) { + if (!AntarchyGravityApi.isGravityInverted(this.mob)) { + return; + } + + LivingEntity target = this.mob.getTarget(); + this.mob.getNavigation().stop(); + this.mob.setAggressive(true); + this.ticksUntilNextAttack = 0; + ci.cancel(); + } + + @Inject(method = "tick", at = @At("HEAD"), cancellable = true) + private void antarchy$tickInvertedMelee(CallbackInfo ci) { + if (!AntarchyGravityApi.isGravityInverted(this.mob)) { + return; + } + + LivingEntity target = this.mob.getTarget(); + if (!this.antarchy$isValidInvertedMeleeTarget(target)) { + this.mob.getNavigation().stop(); + ci.cancel(); + return; + } + + this.mob.getLookControl().setLookAt(target, 30.0F, 30.0F); + // Do not call PathNavigation.moveTo here: that starts the unsafe vanilla + // path acquisition path. MoveControl receives a world-space target and + // the gravity movement mixin converts it into the inverted frame. + this.mob.getMoveControl().setWantedPosition(target.getX(), target.getY(), target.getZ(), this.speedModifier); + this.ticksUntilNextAttack = Math.max(0, this.ticksUntilNextAttack - 1); + this.checkAndPerformAttack(target); + ci.cancel(); + } + + private boolean antarchy$isValidInvertedMeleeTarget(LivingEntity target) { + if (target == null || !target.isAlive()) { + return false; + } + if (this.followingTargetEvenIfNotSeen && !this.mob.isWithinRestriction(target.blockPosition())) { + return false; + } + return !(target instanceof Player player) || (!player.isSpectator() && !player.isCreative()); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/MoveControlGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/MoveControlGravityMixin.java new file mode 100644 index 00000000..60116734 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/MoveControlGravityMixin.java @@ -0,0 +1,48 @@ +package com.craisinlord.antarchy.mixins.gravity; + +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.control.MoveControl; +import net.minecraft.world.phys.Vec3; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MoveControl.class) +public abstract class MoveControlGravityMixin { + @Shadow + @Final + protected Mob mob; + + @Shadow + protected double wantedX; + + @Shadow + protected double wantedY; + + @Shadow + protected double wantedZ; + + @Shadow + protected double speedModifier; + + @Inject(method = "setWantedPosition", at = @At("TAIL")) + private void antarchy$convertInvertedWantedPosition(double x, double y, double z, double speed, CallbackInfo ci) { + if (!AntarchyGravityApi.isGravityInverted(this.mob)) { + return; + } + + Vec3 worldOffset = new Vec3(x - this.mob.getX(), y - this.mob.getY(), z - this.mob.getZ()); + Vec3 localOffset = AntarchyGravityRotationUtil.vecWorldToPlayer( + worldOffset, + AntarchyGravityApi.getGravityDirection(this.mob)); + this.wantedX = this.mob.getX() + localOffset.x; + this.wantedY = this.mob.getY() + localOffset.y; + this.wantedZ = this.mob.getZ() + localOffset.z; + this.speedModifier = speed; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/RandomStrollGoalGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/RandomStrollGoalGravityMixin.java new file mode 100644 index 00000000..a82324be --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/RandomStrollGoalGravityMixin.java @@ -0,0 +1,161 @@ +package com.craisinlord.antarchy.mixins.gravity; + +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.PathfinderMob; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.ai.goal.RandomStrollGoal; +import net.minecraft.world.entity.EntityDimensions; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(RandomStrollGoal.class) +public abstract class RandomStrollGoalGravityMixin { + @Unique + private static final int ANTARCHY$INVERTED_STROLL_ATTEMPTS = 12; + @Unique + private static final int ANTARCHY$INVERTED_STROLL_HORIZONTAL_RANGE = 7; + @Unique + private static final int ANTARCHY$INVERTED_STROLL_VERTICAL_RANGE = 2; + + @Shadow + @Final + protected PathfinderMob mob; + + @Shadow + protected double wantedX; + + @Shadow + protected double wantedY; + + @Shadow + protected double wantedZ; + + @Shadow + @Final + protected double speedModifier; + + @Shadow + protected int interval; + + @Shadow + protected boolean forceTrigger; + + @Shadow + @Final + private boolean checkNoActionTime; + + @Unique + private int antarchy$invertedStrollTicks; + + @Inject(method = "canUse", at = @At("HEAD"), cancellable = true) + private void antarchy$useInvertedRandomStroll(CallbackInfoReturnable cir) { + if (!AntarchyGravityApi.isGravityInverted(this.mob)) { + return; + } + + if (this.mob.hasControllingPassenger()) { + cir.setReturnValue(false); + return; + } + + if (!this.forceTrigger) { + if (this.checkNoActionTime && this.mob.getNoActionTime() >= 100) { + cir.setReturnValue(false); + return; + } + int chance = Math.max(1, this.interval); + if (this.mob.getRandom().nextInt(chance) != 0) { + cir.setReturnValue(false); + return; + } + } + + cir.setReturnValue(this.antarchy$findInvertedStrollTarget()); + } + + @Inject(method = "start", at = @At("HEAD"), cancellable = true) + private void antarchy$startInvertedRandomStroll(CallbackInfo ci) { + if (!AntarchyGravityApi.isGravityInverted(this.mob)) { + return; + } + + this.mob.getNavigation().stop(); + this.mob.getMoveControl().setWantedPosition(this.wantedX, this.wantedY, this.wantedZ, this.speedModifier); + this.antarchy$invertedStrollTicks = 0; + this.forceTrigger = false; + ci.cancel(); + } + + @Inject(method = "canContinueToUse", at = @At("HEAD"), cancellable = true) + private void antarchy$continueInvertedRandomStroll(CallbackInfoReturnable cir) { + if (!AntarchyGravityApi.isGravityInverted(this.mob)) { + return; + } + + double dx = this.wantedX - this.mob.getX(); + double dy = this.wantedY - this.mob.getY(); + double dz = this.wantedZ - this.mob.getZ(); + boolean arrived = dx * dx + dy * dy + dz * dz <= 1.0D; + boolean timedOut = this.antarchy$invertedStrollTicks++ >= 200; + if (!arrived && !timedOut && !this.mob.hasControllingPassenger()) { + // RandomStrollGoal inherits Goal.tick(), so continuation is the + // declared per-tick hook available for refreshing direct movement. + this.mob.getMoveControl().setWantedPosition(this.wantedX, this.wantedY, this.wantedZ, this.speedModifier); + } + cir.setReturnValue(!this.mob.hasControllingPassenger() && !arrived && !timedOut); + } + + @Unique + private boolean antarchy$findInvertedStrollTarget() { + int baseX = Mth.floor(this.mob.getX()); + int baseY = Mth.floor(this.mob.getY() + this.mob.getBbHeight()) - 1; + int baseZ = Mth.floor(this.mob.getZ()); + + for (int attempt = 0; attempt < ANTARCHY$INVERTED_STROLL_ATTEMPTS; attempt++) { + int x = baseX + this.mob.getRandom().nextInt(ANTARCHY$INVERTED_STROLL_HORIZONTAL_RANGE * 2 + 1) - ANTARCHY$INVERTED_STROLL_HORIZONTAL_RANGE; + int y = baseY + this.mob.getRandom().nextInt(ANTARCHY$INVERTED_STROLL_VERTICAL_RANGE * 2 + 1) - ANTARCHY$INVERTED_STROLL_VERTICAL_RANGE; + int z = baseZ + this.mob.getRandom().nextInt(ANTARCHY$INVERTED_STROLL_HORIZONTAL_RANGE * 2 + 1) - ANTARCHY$INVERTED_STROLL_HORIZONTAL_RANGE; + if (this.antarchy$isValidInvertedStrollTarget(x, y, z)) { + this.wantedX = x + 0.5D; + this.wantedY = y + 1.0D - 1.0E-3D; + this.wantedZ = z + 0.5D; + return true; + } + } + + return false; + } + + @Unique + private boolean antarchy$isValidInvertedStrollTarget(int x, int y, int z) { + Level level = this.mob.level(); + BlockPos ceilingPos = new BlockPos(x, y + 1, z); + if (!level.getBlockState(ceilingPos).isFaceSturdy(level, ceilingPos, Direction.DOWN)) { + return false; + } + + EntityDimensions dimensions = this.mob.getDimensions(Pose.STANDING); + double halfWidth = dimensions.width() / 2.0D; + double topY = y + 1.0D - 1.0E-3D; + AABB bodyBox = new AABB( + x + 0.5D - halfWidth, + topY - dimensions.height(), + z + 0.5D - halfWidth, + x + 0.5D + halfWidth, + topY, + z + 0.5D + halfWidth + ).deflate(1.0E-4D); + return level.noCollision(this.mob, bodyBox); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/time/LivingEntityTimeDilationCleanupMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/time/LivingEntityTimeDilationCleanupMixin.java new file mode 100644 index 00000000..d4dd7984 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/time/LivingEntityTimeDilationCleanupMixin.java @@ -0,0 +1,17 @@ +package com.craisinlord.antarchy.mixins.time; + +import com.craisinlord.antarchy.content.time.TimeDilationApi; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.LivingEntity; +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.CallbackInfo; + +@Mixin(LivingEntity.class) +public abstract class LivingEntityTimeDilationCleanupMixin { + @Inject(method = "die", at = @At("HEAD")) + private void antarchy$clearTimeDilationOnDeath(DamageSource damageSource, CallbackInfo ci) { + TimeDilationApi.clearRate((LivingEntity) (Object) this); + } +} diff --git a/common-1.21.1/src/main/resources/antarchy-common.mixins.json b/common-1.21.1/src/main/resources/antarchy-common.mixins.json index 89355d20..48c690eb 100644 --- a/common-1.21.1/src/main/resources/antarchy-common.mixins.json +++ b/common-1.21.1/src/main/resources/antarchy-common.mixins.json @@ -28,6 +28,9 @@ "GlowVinesUnderLeavesMixin", "GrindstoneMenuMixin", "LivingEntityJumpingAccessor", + "CommandedMobMixin", + "LivingEntityRoyalEffectsMixin", + "MobCommandedTargetMixin", "RoyalNoRespiteMixin", "MantisClawWallClimbMixin", "MilkBucketSizeResetMixin", @@ -64,12 +67,15 @@ "gravity.FireworkRocketGravityMixin", "gravity.GroundPathNavigationMixin", "gravity.LivingEntityMixin", + "gravity.MeleeAttackGoalGravityMixin", + "gravity.MoveControlGravityMixin", "gravity.MobHurtMixin", "gravity.PathNavigationAccessor", "gravity.PlayerAttackMixin", "gravity.PlayerGravityMixin", "gravity.PlayerPoseFitMixin", "gravity.PlayerSneakMixin", + "gravity.RandomStrollGoalGravityMixin", "gravity.ProjectileGravityMixin", "gravity.ServerChunkCacheAccessor", "gravity.ServerEntityAccessor", @@ -85,7 +91,8 @@ "time.LivingEntityKnockbackTimeDilationMixin", "time.CreeperTimeDilationMixin", "time.EndCrystalTimeDilationMixin", - "time.LivingEntityTimeDilationMixin", + "time.LivingEntityTimeDilationMixin", + "time.LivingEntityTimeDilationCleanupMixin", "time.LivingEntityAttackCooldownTimeDilationMixin", "time.LookControlTimeDilationMixin", "time.MeleeAttackGoalTimeDilationMixin", diff --git a/common-1.21.1/src/main/resources/assets/antarchy/animations/black_hole.animation.json b/common-1.21.1/src/main/resources/assets/antarchy/animations/black_hole.animation.json new file mode 100644 index 00000000..93a78a4e --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/animations/black_hole.animation.json @@ -0,0 +1,381 @@ +{ + "format_version": "1.8.0", + "animations": { + "animation": { + "loop": true, + "animation_length": 20.125, + "bones": { + "black_hole": { + "position": { + "0.0": { + "vector": [0, -100, 0] + }, + "19.125": { + "vector": [0, 505, 0] + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "19.125": { + "vector": [10, 10, 10] + }, + "19.25": { + "vector": [0, 0, 0] + } + } + }, + "blocks": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "0.875": { + "post": { + "vector": [-141, 71, 0] + }, + "lerp_mode": "catmullrom" + }, + "2.375": { + "post": { + "vector": [-141, 104, 0] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "blocks2": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "0.875": { + "post": { + "vector": [116, 72, 0] + }, + "lerp_mode": "catmullrom" + }, + "2.375": { + "post": { + "vector": [116, 124, 0] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "blocks3": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "1.4167": { + "post": { + "vector": [-69, 96, -164] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "blocks4": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "0.9583": { + "post": { + "vector": [35, 96, 135] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "blocks5": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "2.375": { + "post": { + "vector": [113, 118, -188] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "blocks6": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "0.7083": { + "post": { + "vector": [-114, 64, 112] + }, + "lerp_mode": "catmullrom" + }, + "1.2083": { + "post": { + "vector": [-146, 81, 162] + }, + "lerp_mode": "catmullrom" + }, + "1.9583": { + "post": { + "vector": [-146, 94, 162] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "blocks7": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "1.9583": { + "post": { + "vector": [187, 123, 137] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "blocks8": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "2.375": { + "post": { + "vector": [236, 124, 0] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "blocks9": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "1.9583": { + "post": { + "vector": [-239, 106, 0] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "blocks10": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "0.375": { + "post": { + "vector": [-10, 65, 0] + }, + "lerp_mode": "catmullrom" + }, + "2.375": { + "post": { + "vector": [-10, 119, 0] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "blocks11": { + "position": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "2.375": { + "post": { + "vector": [-223, 106, -145] + }, + "lerp_mode": "catmullrom" + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "2.4583": { + "vector": [0, 0, 0] + } + } + }, + "beam": { + "scale": { + "0.0": { + "post": { + "vector": [0.2, 0.5, 0.5] + }, + "lerp_mode": "catmullrom" + }, + "0.4167": { + "post": { + "vector": [-0.2, 3.6, 0.1] + }, + "lerp_mode": "catmullrom" + }, + "1.5833": { + "post": { + "vector": [-0.1, 3.6, 0.1] + }, + "lerp_mode": "catmullrom" + }, + "13.0833": { + "post": { + "vector": [0.4, 122.1, -0.4] + }, + "lerp_mode": "catmullrom" + } + } + }, + "group": { + "position": { + "0.0": { + "vector": [0, 0, 0] + }, + "18.9167": { + "vector": [0, 0, 0] + }, + "19.125": { + "vector": [0, 445, 0] + } + }, + "scale": { + "0.0": { + "vector": [0, 0, 0] + }, + "18.9167": { + "vector": [0, 0, 0] + }, + "19.5833": { + "vector": [83.7, 1, 0] + }, + "20.125": { + "vector": [0, 0, 0] + } + } + } + } + } + } +} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/animations/fire_ball.animation.json b/common-1.21.1/src/main/resources/assets/antarchy/animations/fire_ball.animation.json new file mode 100644 index 00000000..2d171838 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/animations/fire_ball.animation.json @@ -0,0 +1,33 @@ +{ + "format_version": "1.8.0", + "animations": { + "idle": { + "loop": true, + "animation_length": 0.25, + "bones": { + "fireball": { + "scale": { + "0.0": { + "post": { + "vector": [1, 1, 1] + }, + "lerp_mode": "catmullrom" + }, + "0.125": { + "post": { + "vector": [1, 1, 1.2] + }, + "lerp_mode": "catmullrom" + }, + "0.25": { + "post": { + "vector": [1, 1, 1] + }, + "lerp_mode": "catmullrom" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/animations/ice_ball.animation.json b/common-1.21.1/src/main/resources/assets/antarchy/animations/ice_ball.animation.json new file mode 100644 index 00000000..01453f7a --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/animations/ice_ball.animation.json @@ -0,0 +1,56 @@ +{ + "format_version": "1.8.0", + "animations": { + "animation": { + "loop": true, + "animation_length": 0.5, + "bones": { + "ice_ball": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.25": { + "vector": [180, 0, 52.5] + }, + "0.5": { + "vector": [360, 0, 0] + } + }, + "scale": { + "0.0": { + "post": { + "vector": [1, 1, 1] + }, + "lerp_mode": "catmullrom" + }, + "0.125": { + "post": { + "vector": [1, 1.1, 1] + }, + "lerp_mode": "catmullrom" + }, + "0.25": { + "post": { + "vector": [1, 1, 1] + }, + "lerp_mode": "catmullrom" + }, + "0.375": { + "post": { + "vector": [1, 1.1, 1] + }, + "lerp_mode": "catmullrom" + }, + "0.5": { + "post": { + "vector": [1, 1, 1] + }, + "lerp_mode": "catmullrom" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/animations/ice_spike.animation.json b/common-1.21.1/src/main/resources/assets/antarchy/animations/ice_spike.animation.json new file mode 100644 index 00000000..87bfd1db --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/animations/ice_spike.animation.json @@ -0,0 +1,363 @@ +{ + "format_version": "1.8.0", + "animations": { + "animation": { + "animation_length": 5.0833, + "bones": { + "ice_spike": { + "position": { + "0.0": { + "vector": [0, -80, 0] + }, + "0.0417": { + "vector": [-6, -66.67, 0] + }, + "0.0833": { + "vector": [0, -53.34, 0] + }, + "0.125": { + "vector": [-5, -40.01, 0] + }, + "0.1667": { + "vector": [-0.33, -26.67, 0] + }, + "0.25": { + "vector": [0, 0, 0] + }, + "0.8333": { + "vector": [0, 0, 0] + }, + "1.0": { + "vector": [0, -47, 0] + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "0.2083": { + "vector": [1, 1, 1] + }, + "0.25": { + "vector": [0, 0, 0] + }, + "0.3333": { + "vector": [1, 1, 1] + }, + "0.8333": { + "vector": [1, 1, 1] + }, + "1.0": { + "vector": [1, 0, 1] + } + } + }, + "ice_spike_impact": { + "scale": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.0417": [0, 0, 0], + "0.2083": { + "vector": [0, 0, 0] + }, + "0.25": { + "vector": [1, 1, 1] + }, + "0.2917": { + "vector": [1, 1.3, 1] + }, + "0.3333": { + "vector": [0, 0, 0] + } + } + }, + "sparkle": { + "scale": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.2917": { + "vector": [0, 0, 0] + }, + "0.4583": { + "vector": [1.2, 2.5, 1] + }, + "0.625": { + "vector": [0, 1, 1] + } + } + }, + "ice_spike_impact2": { + "scale": { + "1.0": { + "vector": [0, 0, 0] + }, + "1.0417": [0, 0, 0], + "1.2083": { + "vector": [0, 0, 0] + }, + "1.25": { + "vector": [1, 1, 1] + }, + "1.2917": { + "vector": [1, 1.3, 1] + }, + "1.3333": { + "vector": [0, 0, 0] + } + } + }, + "ice_spike2": { + "position": { + "1.0": { + "vector": [0, -80, 0] + }, + "1.0417": { + "vector": [-6, -66.67, 0] + }, + "1.0833": { + "vector": [0, -53.34, 0] + }, + "1.125": { + "vector": [-5, -40.01, 0] + }, + "1.1667": { + "vector": [-0.33, -26.67, 0] + }, + "1.25": { + "vector": [0, 0, 0] + }, + "1.8333": { + "vector": [0, 0, 0] + }, + "2.0": { + "vector": [0, -47, 0] + } + }, + "scale": { + "1.0": { + "vector": [1, 1, 1] + }, + "1.2083": { + "vector": [1, 1, 1] + }, + "1.25": { + "vector": [0, 0, 0] + }, + "1.3333": { + "vector": [1, 1, 1] + }, + "1.8333": { + "vector": [1, 1, 1] + }, + "2.0": { + "vector": [1, 0, 1] + } + } + }, + "sparkle2": { + "scale": { + "1.0": { + "vector": [0, 0, 0] + }, + "1.2917": { + "vector": [0, 0, 0] + }, + "1.4583": { + "vector": [1.2, 2.5, 1] + }, + "1.625": { + "vector": [0, 1, 1] + } + } + }, + "ice_spike_impact3": { + "scale": { + "2.0": { + "vector": [0, 0, 0] + }, + "2.0417": [0, 0, 0], + "2.2083": { + "vector": [0, 0, 0] + }, + "2.25": { + "vector": [1, 1, 1] + }, + "2.2917": { + "vector": [1, 1.3, 1] + }, + "2.3333": { + "vector": [0, 0, 0] + } + } + }, + "ice_spike3": { + "position": { + "2.0": { + "vector": [0, -80, 0] + }, + "2.0417": { + "vector": [-6, -66.67, 0] + }, + "2.0833": { + "vector": [0, -53.34, 0] + }, + "2.125": { + "vector": [-5, -40.01, 0] + }, + "2.1667": { + "vector": [-0.33, -26.67, 0] + }, + "2.25": { + "vector": [0, 0, 0] + }, + "2.8333": { + "vector": [0, 0, 0] + }, + "3.0": { + "vector": [0, -47, 0] + } + }, + "scale": { + "2.0": { + "vector": [1, 1, 1] + }, + "2.2083": { + "vector": [1, 1, 1] + }, + "2.25": { + "vector": [0, 0, 0] + }, + "2.3333": { + "vector": [1, 1, 1] + }, + "2.8333": { + "vector": [1, 1, 1] + }, + "3.0": { + "vector": [1, 0, 1] + } + } + }, + "sparkle3": { + "scale": { + "2.0": { + "vector": [0, 0, 0] + }, + "2.2917": { + "vector": [0, 0, 0] + }, + "2.4583": { + "vector": [1.2, 2.5, 1] + }, + "2.625": { + "vector": [0, 1, 1] + } + } + }, + "ice_spike_impact4": { + "scale": { + "3.0": { + "vector": [0, 0, 0] + }, + "3.0417": [0, 0, 0], + "3.2083": { + "vector": [0, 0, 0] + }, + "3.25": { + "vector": [1, 1, 1] + }, + "3.2917": { + "vector": [1, 1.3, 1] + }, + "3.3333": { + "vector": [0, 0, 0] + } + } + }, + "ice_spike4": { + "position": { + "3.0": { + "vector": [0, -80, 0] + }, + "3.0417": { + "vector": [-6, -66.67, 0] + }, + "3.0833": { + "vector": [0, -53.34, 0] + }, + "3.125": { + "vector": [-5, -40.01, 0] + }, + "3.1667": { + "vector": [-0.33, -26.67, 0] + }, + "3.25": { + "vector": [0, 0, 0] + }, + "3.8333": { + "vector": [0, 0, 0] + }, + "4.0": { + "vector": [0, -47, 0] + } + }, + "scale": { + "3.0": { + "vector": [1, 1, 1] + }, + "3.2083": { + "vector": [1, 1, 1] + }, + "3.25": { + "vector": [0, 0, 0] + }, + "3.3333": { + "vector": [1, 1, 1] + }, + "3.8333": { + "vector": [1, 1, 1] + }, + "4.0": { + "vector": [1, 0, 1] + } + } + }, + "sparkle4": { + "scale": { + "3.0": { + "vector": [0, 0, 0] + }, + "3.2917": { + "vector": [0, 0, 0] + }, + "3.4583": { + "vector": [1.2, 2.5, 1] + }, + "3.625": { + "vector": [0, 1, 1] + } + } + } + }, + "particle_effects": { + "0.0": { + "effect": "particles" + }, + "1.0": { + "effect": "particles", + "locator": "spike_2" + }, + "2.0": { + "effect": "particles", + "locator": "spike_3" + }, + "3.0": { + "effect": "particles", + "locator": "spike_4" + } + } + } + } +} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/blockstates/dimensional_tear_marker.json b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/dimensional_tear_marker.json new file mode 100644 index 00000000..f17f93e2 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/dimensional_tear_marker.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_base.json b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_base.json new file mode 100644 index 00000000..f17f93e2 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_base.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_master.json b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_master.json new file mode 100644 index 00000000..f17f93e2 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/portal_gun_portal_master.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/blockstates/typhonite_spike.json b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/typhonite_spike.json index c069e566..b22e8a99 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/blockstates/typhonite_spike.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/typhonite_spike.json @@ -1,31 +1,41 @@ { "variants": { "thickness=base,vertical_direction=down": { - "model": "antarchy:block/typhonite_spike_down_base" + "model": "antarchy:block/typhonite_spike_down_base", + "x": 180, + "uvlock": true }, "thickness=base,vertical_direction=up": { "model": "antarchy:block/typhonite_spike_up_base" }, "thickness=frustum,vertical_direction=down": { - "model": "antarchy:block/typhonite_spike_down_frustum" + "model": "antarchy:block/typhonite_spike_down_frustum", + "x": 180, + "uvlock": true }, "thickness=frustum,vertical_direction=up": { "model": "antarchy:block/typhonite_spike_up_frustum" }, "thickness=middle,vertical_direction=down": { - "model": "antarchy:block/typhonite_spike_down_middle" + "model": "antarchy:block/typhonite_spike_down_middle", + "x": 180, + "uvlock": true }, "thickness=middle,vertical_direction=up": { "model": "antarchy:block/typhonite_spike_up_middle" }, "thickness=tip,vertical_direction=down": { - "model": "antarchy:block/typhonite_spike_down_tip" + "model": "antarchy:block/typhonite_spike_down_tip", + "x": 180, + "uvlock": true }, "thickness=tip,vertical_direction=up": { "model": "antarchy:block/typhonite_spike_up_tip" }, "thickness=tip_merge,vertical_direction=down": { - "model": "antarchy:block/typhonite_spike_down_tip_merge" + "model": "antarchy:block/typhonite_spike_down_tip_merge", + "x": 180, + "uvlock": true }, "thickness=tip_merge,vertical_direction=up": { "model": "antarchy:block/typhonite_spike_up_tip_merge" diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/black_hole.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/black_hole.geo.json new file mode 100644 index 00000000..7bc78ad5 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/black_hole.geo.json @@ -0,0 +1,118 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 300, + "texture_height": 300, + "visible_bounds_width": 33, + "visible_bounds_height": 16, + "visible_bounds_offset": [0, 7, 0] + }, + "bones": [ + { + "name": "blocks", + "pivot": [136, -9, 0], + "cubes": [ + {"origin": [128, -17, -8], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "blocks11", + "pivot": [230, -9, 133], + "cubes": [ + {"origin": [222, -17, 125], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "blocks10", + "pivot": [18, -9, 0], + "cubes": [ + {"origin": [10, -17, -8], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "blocks9", + "pivot": [245, -9, 0], + "cubes": [ + {"origin": [237, -17, -8], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "blocks6", + "pivot": [155, -9, -152], + "cubes": [ + {"origin": [147, -17, -160], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "blocks3", + "pivot": [66, -9, 175], + "cubes": [ + {"origin": [58, -17, 167], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "blocks2", + "pivot": [-111, -9, 0], + "cubes": [ + {"origin": [-119, -17, -8], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "blocks8", + "pivot": [-248, -9, 0], + "cubes": [ + {"origin": [-256, -17, -8], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "blocks5", + "pivot": [-111, -9, 176], + "cubes": [ + {"origin": [-119, -17, 168], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "blocks4", + "pivot": [-35, -9, -146], + "cubes": [ + {"origin": [-43, -17, -154], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "blocks7", + "pivot": [-193, -9, -146], + "cubes": [ + {"origin": [-201, -17, -154], "size": [16, 16, 16], "uv": [0, 214]} + ] + }, + { + "name": "black_hole", + "pivot": [0, 151, 0], + "cubes": [ + {"origin": [-75, 151, -75], "size": [150, 0, 150], "uv": [-150, 0]}, + {"origin": [-16, 130, -16], "size": [32, 32, 32], "uv": [0, 150]}, + {"origin": [-75, 151, -75], "size": [150, 0, 150], "pivot": [0, 151, 0], "rotation": [90, 0, 0], "uv": [-150, 0]} + ] + }, + { + "name": "beam", + "parent": "black_hole", + "pivot": [0, 147, 0], + "cubes": [ + {"origin": [-16, 123, -16], "size": [32, 48, 32], "uv": [172, 152]} + ] + }, + { + "name": "group", + "pivot": [0, 147, 0], + "cubes": [ + {"origin": [-16, 123, -16], "size": [32, 48, 32], "uv": [172, 152]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/eye_of_the_storm.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/eye_of_the_storm.geo.json index d448465f..0526dfce 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/geo/eye_of_the_storm.geo.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/eye_of_the_storm.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -214,4 +214,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/fallen_king_crown.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/fallen_king_crown.geo.json index c8f22646..afa9b466 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/geo/fallen_king_crown.geo.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/fallen_king_crown.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -80,4 +80,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/fire_ball.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/fire_ball.geo.json new file mode 100644 index 00000000..dc9ff1f0 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/fire_ball.geo.json @@ -0,0 +1,28 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 128, + "texture_height": 128, + "visible_bounds_width": 7, + "visible_bounds_height": 4, + "visible_bounds_offset": [0, 1, 0] + }, + "bones": [ + { + "name": "fireball", + "pivot": [0, 8, 8.1], + "cubes": [ + {"origin": [-6, -25, -8], "size": [0, 36, 52], "pivot": [0, -7, 18], "rotation": [0, 0, 90], "uv": [0, 40]}, + {"origin": [-24, -25, -8], "size": [0, 36, 52], "pivot": [0, -7, 18], "rotation": [0, 0, 90], "uv": [0, 40]}, + {"origin": [-23, -14, -8], "size": [15, 14, 13], "pivot": [0, -7, 18], "rotation": [0, 0, 90], "uv": [0, 0]}, + {"origin": [8, -10, -8], "size": [0, 36, 52], "uv": [0, 40], "mirror": true}, + {"origin": [-8, -10, -8], "size": [0, 36, 52], "uv": [0, 40]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/ice_ball.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/ice_ball.geo.json new file mode 100644 index 00000000..9e51b94b --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/ice_ball.geo.json @@ -0,0 +1,24 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 64, + "texture_height": 64, + "visible_bounds_width": 2, + "visible_bounds_height": 2.5, + "visible_bounds_offset": [0, 0.75, 0] + }, + "bones": [ + { + "name": "ice_ball", + "pivot": [0, 8, 0], + "cubes": [ + {"origin": [-8, 0, -8], "size": [16, 16, 16], "uv": [0, 0]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/ice_spike.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/ice_spike.geo.json new file mode 100644 index 00000000..89c4648d --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/ice_spike.geo.json @@ -0,0 +1,214 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 256, + "texture_height": 256, + "visible_bounds_width": 17, + "visible_bounds_height": 6.5, + "visible_bounds_offset": [0, 2.75, 0] + }, + "bones": [ + { + "name": "bb_main", + "pivot": [0, 0, 0], + "locators": { + "spike_2": [0, 0, -39], + "spike_3": [0, 0, -80], + "spike_4": [0, 0, -121] + } + }, + { + "name": "group", + "pivot": [0, 0, 0], + "rotation": [0, 90, 0] + }, + { + "name": "ice_spike_impact", + "parent": "group", + "pivot": [-1.4, 46.7, 0], + "cubes": [ + {"origin": [-7, 0, -7], "size": [14, 29, 14], "inflate": -0.03, "uv": [0, 108]}, + {"origin": [-6, 29, -6], "size": [12, 10, 12], "inflate": -0.03, "uv": [0, 151]}, + {"origin": [-5, 39, -5], "size": [10, 10, 10], "inflate": -0.03, "uv": [56, 108]}, + {"origin": [-3, 59, -3], "size": [6, 10, 6], "inflate": -0.03, "uv": [50, 146]}, + {"origin": [-4, 49, -4], "size": [8, 10, 8], "inflate": -0.03, "uv": [56, 128]}, + {"origin": [-2, 69, -2], "size": [4, 10, 4], "inflate": -0.03, "uv": [48, 162]}, + {"origin": [5, 39, 0], "size": [19, 16, 0], "inflate": -0.03, "uv": [74, 146]}, + {"origin": [-25, 9, 0], "size": [18, 26, 0], "inflate": -0.03, "uv": [0, 173]}, + {"origin": [-16, 40, 0], "size": [18, 17, 0], "inflate": -0.03, "uv": [0, 199]}, + {"origin": [-8, 61, 0], "size": [5, 8, 0], "inflate": -0.03, "uv": [65, 162]} + ] + }, + { + "name": "ice_spike", + "parent": "group", + "pivot": [-1.4, 46.7, 0], + "cubes": [ + {"origin": [-7, 0, -7], "size": [14, 29, 14], "uv": [0, 0]}, + {"origin": [-6, 29, -6], "size": [12, 10, 12], "uv": [0, 43]}, + {"origin": [-5, 39, -5], "size": [10, 10, 10], "uv": [56, 0]}, + {"origin": [-3, 59, -3], "size": [6, 10, 6], "uv": [50, 38]}, + {"origin": [-4, 49, -4], "size": [8, 10, 8], "uv": [56, 20]}, + {"origin": [-2, 69, -2], "size": [4, 10, 4], "uv": [48, 54]}, + {"origin": [5, 39, 0], "size": [19, 16, 0], "uv": [74, 38]}, + {"origin": [-25, 9, 0], "size": [18, 26, 0], "uv": [0, 65]}, + {"origin": [-16, 40, 0], "size": [18, 17, 0], "uv": [0, 91]}, + {"origin": [-8, 61, 0], "size": [5, 8, 0], "uv": [65, 54]} + ] + }, + { + "name": "sparkle", + "parent": "ice_spike", + "pivot": [2.5, 79.5, -3], + "cubes": [ + {"origin": [1, 77, -3], "size": [3, 5, 0], "uv": [38, 46]} + ] + }, + { + "name": "group2", + "pivot": [0, 0, -40], + "rotation": [0, 90, 0] + }, + { + "name": "ice_spike_impact2", + "parent": "group2", + "pivot": [-1.4, 46.7, -40], + "cubes": [ + {"origin": [-7, 0, -47], "size": [14, 29, 14], "inflate": -0.03, "uv": [0, 108]}, + {"origin": [-6, 29, -46], "size": [12, 10, 12], "inflate": -0.03, "uv": [0, 151]}, + {"origin": [-5, 39, -45], "size": [10, 10, 10], "inflate": -0.03, "uv": [56, 108]}, + {"origin": [-3, 59, -43], "size": [6, 10, 6], "inflate": -0.03, "uv": [50, 146]}, + {"origin": [-4, 49, -44], "size": [8, 10, 8], "inflate": -0.03, "uv": [56, 128]}, + {"origin": [-2, 69, -42], "size": [4, 10, 4], "inflate": -0.03, "uv": [48, 162]}, + {"origin": [5, 39, -40], "size": [19, 16, 0], "inflate": -0.03, "uv": [74, 146]}, + {"origin": [-25, 9, -40], "size": [18, 26, 0], "inflate": -0.03, "uv": [0, 173]}, + {"origin": [-16, 40, -40], "size": [18, 17, 0], "inflate": -0.03, "uv": [0, 199]}, + {"origin": [-8, 61, -40], "size": [5, 8, 0], "inflate": -0.03, "uv": [65, 162]} + ] + }, + { + "name": "ice_spike2", + "parent": "group2", + "pivot": [-1.4, 46.7, -40], + "cubes": [ + {"origin": [-7, 0, -47], "size": [14, 29, 14], "uv": [0, 0]}, + {"origin": [-6, 29, -46], "size": [12, 10, 12], "uv": [0, 43]}, + {"origin": [-5, 39, -45], "size": [10, 10, 10], "uv": [56, 0]}, + {"origin": [-3, 59, -43], "size": [6, 10, 6], "uv": [50, 38]}, + {"origin": [-4, 49, -44], "size": [8, 10, 8], "uv": [56, 20]}, + {"origin": [-2, 69, -42], "size": [4, 10, 4], "uv": [48, 54]}, + {"origin": [5, 39, -40], "size": [19, 16, 0], "uv": [74, 38]}, + {"origin": [-25, 9, -40], "size": [18, 26, 0], "uv": [0, 65]}, + {"origin": [-16, 40, -40], "size": [18, 17, 0], "uv": [0, 91]}, + {"origin": [-8, 61, -40], "size": [5, 8, 0], "uv": [65, 54]} + ] + }, + { + "name": "sparkle2", + "parent": "ice_spike2", + "pivot": [2.5, 79.5, -43], + "cubes": [ + {"origin": [1, 77, -43], "size": [3, 5, 0], "uv": [38, 46]} + ] + }, + { + "name": "group3", + "pivot": [0, 0, -80], + "rotation": [0, 90, 0] + }, + { + "name": "ice_spike_impact3", + "parent": "group3", + "pivot": [-1.4, 46.7, -80], + "cubes": [ + {"origin": [-7, 0, -87], "size": [14, 29, 14], "inflate": -0.03, "uv": [0, 108]}, + {"origin": [-6, 29, -86], "size": [12, 10, 12], "inflate": -0.03, "uv": [0, 151]}, + {"origin": [-5, 39, -85], "size": [10, 10, 10], "inflate": -0.03, "uv": [56, 108]}, + {"origin": [-3, 59, -83], "size": [6, 10, 6], "inflate": -0.03, "uv": [50, 146]}, + {"origin": [-4, 49, -84], "size": [8, 10, 8], "inflate": -0.03, "uv": [56, 128]}, + {"origin": [-2, 69, -82], "size": [4, 10, 4], "inflate": -0.03, "uv": [48, 162]}, + {"origin": [5, 39, -80], "size": [19, 16, 0], "inflate": -0.03, "uv": [74, 146]}, + {"origin": [-25, 9, -80], "size": [18, 26, 0], "inflate": -0.03, "uv": [0, 173]}, + {"origin": [-16, 40, -80], "size": [18, 17, 0], "inflate": -0.03, "uv": [0, 199]}, + {"origin": [-8, 61, -80], "size": [5, 8, 0], "inflate": -0.03, "uv": [65, 162]} + ] + }, + { + "name": "ice_spike3", + "parent": "group3", + "pivot": [-1.4, 46.7, -80], + "cubes": [ + {"origin": [-7, 0, -87], "size": [14, 29, 14], "uv": [0, 0]}, + {"origin": [-6, 29, -86], "size": [12, 10, 12], "uv": [0, 43]}, + {"origin": [-5, 39, -85], "size": [10, 10, 10], "uv": [56, 0]}, + {"origin": [-3, 59, -83], "size": [6, 10, 6], "uv": [50, 38]}, + {"origin": [-4, 49, -84], "size": [8, 10, 8], "uv": [56, 20]}, + {"origin": [-2, 69, -82], "size": [4, 10, 4], "uv": [48, 54]}, + {"origin": [5, 39, -80], "size": [19, 16, 0], "uv": [74, 38]}, + {"origin": [-25, 9, -80], "size": [18, 26, 0], "uv": [0, 65]}, + {"origin": [-16, 40, -80], "size": [18, 17, 0], "uv": [0, 91]}, + {"origin": [-8, 61, -80], "size": [5, 8, 0], "uv": [65, 54]} + ] + }, + { + "name": "sparkle3", + "parent": "ice_spike3", + "pivot": [2.5, 79.5, -83], + "cubes": [ + {"origin": [1, 77, -83], "size": [3, 5, 0], "uv": [38, 46]} + ] + }, + { + "name": "group4", + "pivot": [0, 0, -120], + "rotation": [0, 90, 0] + }, + { + "name": "ice_spike_impact4", + "parent": "group4", + "pivot": [-1.4, 46.7, -120], + "cubes": [ + {"origin": [-7, 0, -127], "size": [14, 29, 14], "inflate": -0.03, "uv": [0, 108]}, + {"origin": [-6, 29, -126], "size": [12, 10, 12], "inflate": -0.03, "uv": [0, 151]}, + {"origin": [-5, 39, -125], "size": [10, 10, 10], "inflate": -0.03, "uv": [56, 108]}, + {"origin": [-3, 59, -123], "size": [6, 10, 6], "inflate": -0.03, "uv": [50, 146]}, + {"origin": [-4, 49, -124], "size": [8, 10, 8], "inflate": -0.03, "uv": [56, 128]}, + {"origin": [-2, 69, -122], "size": [4, 10, 4], "inflate": -0.03, "uv": [48, 162]}, + {"origin": [5, 39, -120], "size": [19, 16, 0], "inflate": -0.03, "uv": [74, 146]}, + {"origin": [-25, 9, -120], "size": [18, 26, 0], "inflate": -0.03, "uv": [0, 173]}, + {"origin": [-16, 40, -120], "size": [18, 17, 0], "inflate": -0.03, "uv": [0, 199]}, + {"origin": [-8, 61, -120], "size": [5, 8, 0], "inflate": -0.03, "uv": [65, 162]} + ] + }, + { + "name": "ice_spike4", + "parent": "group4", + "pivot": [-1.4, 46.7, -120], + "cubes": [ + {"origin": [-7, 0, -127], "size": [14, 29, 14], "uv": [0, 0]}, + {"origin": [-6, 29, -126], "size": [12, 10, 12], "uv": [0, 43]}, + {"origin": [-5, 39, -125], "size": [10, 10, 10], "uv": [56, 0]}, + {"origin": [-3, 59, -123], "size": [6, 10, 6], "uv": [50, 38]}, + {"origin": [-4, 49, -124], "size": [8, 10, 8], "uv": [56, 20]}, + {"origin": [-2, 69, -122], "size": [4, 10, 4], "uv": [48, 54]}, + {"origin": [5, 39, -120], "size": [19, 16, 0], "uv": [74, 38]}, + {"origin": [-25, 9, -120], "size": [18, 26, 0], "uv": [0, 65]}, + {"origin": [-16, 40, -120], "size": [18, 17, 0], "uv": [0, 91]}, + {"origin": [-8, 61, -120], "size": [5, 8, 0], "uv": [65, 54]} + ] + }, + { + "name": "sparkle4", + "parent": "ice_spike4", + "pivot": [2.5, 79.5, -123], + "cubes": [ + {"origin": [1, 77, -123], "size": [3, 5, 0], "uv": [38, 46]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/krakens_grasp.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/krakens_grasp.geo.json index a8e4f668..b3df7394 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/geo/krakens_grasp.geo.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/krakens_grasp.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -199,4 +199,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/portal_gun.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/portal_gun.geo.json index 9219f398..0cc853e2 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/geo/portal_gun.geo.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/portal_gun.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -165,4 +165,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/royal_assailant_staff.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/royal_assailant_staff.geo.json index e7818125..78cabd84 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/geo/royal_assailant_staff.geo.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/royal_assailant_staff.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -111,4 +111,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/royal_guardian_sword.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/royal_guardian_sword.geo.json index 24e29db7..378a1c1a 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/geo/royal_guardian_sword.geo.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/royal_guardian_sword.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -222,4 +222,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/rpo_launcher.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/rpo_launcher.geo.json index 07451faf..794ca38d 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/geo/rpo_launcher.geo.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/rpo_launcher.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -284,4 +284,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/water_cannon.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/water_cannon.geo.json index 4240f801..6b844883 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/geo/water_cannon.geo.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/water_cannon.geo.json @@ -1,5 +1,5 @@ { - "format_version": "1.21.110", + "format_version": "1.12.0", "minecraft:geometry": [ { "description": { @@ -92,4 +92,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json b/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json index 4bbfff86..2c631b4e 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json @@ -751,6 +751,10 @@ "effect.antarchy.paralyzed.description": "Prevents targets from moving.", "effect.antarchy.inverted": "Inverted", "effect.antarchy.inverted.description": "Inverts the target's gravity.", + "effect.antarchy.commanded": "Commanded", + "effect.antarchy.commanded.description": "Fights for the player who commanded it.", + "effect.antarchy.dilated": "Dilated", + "effect.antarchy.dilated.description": "Slows the passage of time for the affected entity.", "effect.antarchy.stinky": "Stinky", "effect.antarchy.stinky.description": "Repels passive and neutral mobs, attracts arthropods.", "effect.antarchy.gooped": "Gooped", @@ -1072,6 +1076,22 @@ "item.minecraft.lingering_potion.effect.long_inversion": "Lingering Potion of Inversion", "item.minecraft.tipped_arrow.effect.inversion": "Arrow of Inversion", "item.minecraft.tipped_arrow.effect.long_inversion": "Arrow of Inversion", + "item.minecraft.potion.effect.command": "Potion of Command", + "item.minecraft.potion.effect.long_command": "Potion of Command", + "item.minecraft.splash_potion.effect.command": "Splash Potion of Command", + "item.minecraft.splash_potion.effect.long_command": "Splash Potion of Command", + "item.minecraft.lingering_potion.effect.command": "Lingering Potion of Command", + "item.minecraft.lingering_potion.effect.long_command": "Lingering Potion of Command", + "item.minecraft.tipped_arrow.effect.command": "Arrow of Command", + "item.minecraft.tipped_arrow.effect.long_command": "Arrow of Command", + "item.minecraft.potion.effect.time_dilation": "Potion of Time Dilation", + "item.minecraft.potion.effect.long_time_dilation": "Potion of Time Dilation", + "item.minecraft.splash_potion.effect.time_dilation": "Splash Potion of Time Dilation", + "item.minecraft.splash_potion.effect.long_time_dilation": "Splash Potion of Time Dilation", + "item.minecraft.lingering_potion.effect.time_dilation": "Lingering Potion of Time Dilation", + "item.minecraft.lingering_potion.effect.long_time_dilation": "Lingering Potion of Time Dilation", + "item.minecraft.tipped_arrow.effect.time_dilation": "Arrow of Time Dilation", + "item.minecraft.tipped_arrow.effect.long_time_dilation": "Arrow of Time Dilation", "item.minecraft.potion.effect.paralysis": "Potion of Paralysis", "item.minecraft.potion.effect.long_paralysis": "Potion of Paralysis", "item.minecraft.splash_potion.effect.paralysis": "Splash Potion of Paralysis", diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/block/nadir_hanging_sign.json b/common-1.21.1/src/main/resources/assets/antarchy/models/block/nadir_hanging_sign.json index c101c4af..cc1d471b 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/block/nadir_hanging_sign.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/block/nadir_hanging_sign.json @@ -1,5 +1,5 @@ { "textures": { - "particle": "antarchy:block/nadir/nadir_hanging" + "particle": "antarchy:block/nadir/nadir_planks" } } diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/block/nadir_wall_hanging_sign.json b/common-1.21.1/src/main/resources/assets/antarchy/models/block/nadir_wall_hanging_sign.json index c101c4af..cc1d471b 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/block/nadir_wall_hanging_sign.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/block/nadir_wall_hanging_sign.json @@ -1,5 +1,5 @@ { "textures": { - "particle": "antarchy:block/nadir/nadir_hanging" + "particle": "antarchy:block/nadir/nadir_planks" } } diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_base.json b/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_base.json index 9bb5a57b..7254ce81 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_base.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_base.json @@ -1,6 +1,5 @@ { "parent": "minecraft:block/pointed_dripstone", - "x": 180, "textures": { "cross": "antarchy:block/typhonite/typhonite_spike_base" } diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_frustum.json b/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_frustum.json index aff88525..13db257a 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_frustum.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_frustum.json @@ -1,6 +1,5 @@ { "parent": "minecraft:block/pointed_dripstone", - "x": 180, "textures": { "cross": "antarchy:block/typhonite/typhonite_spike_middle" } diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_middle.json b/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_middle.json index aff88525..13db257a 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_middle.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_middle.json @@ -1,6 +1,5 @@ { "parent": "minecraft:block/pointed_dripstone", - "x": 180, "textures": { "cross": "antarchy:block/typhonite/typhonite_spike_middle" } diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_tip.json b/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_tip.json index 10c0420f..969fe71c 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_tip.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_tip.json @@ -1,6 +1,5 @@ { "parent": "minecraft:block/pointed_dripstone", - "x": 180, "textures": { "cross": "antarchy:block/typhonite/typhonite_spike_tip" } diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_tip_merge.json b/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_tip_merge.json index 10c0420f..969fe71c 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_tip_merge.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/block/typhonite_spike_down_tip_merge.json @@ -1,6 +1,5 @@ { "parent": "minecraft:block/pointed_dripstone", - "x": 180, "textures": { "cross": "antarchy:block/typhonite/typhonite_spike_tip" } diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/block/verdant_nyxium.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/block/verdant_nyxium.png index ed655b7f..a0c1b67f 100644 Binary files a/common-1.21.1/src/main/resources/assets/antarchy/textures/block/verdant_nyxium.png and b/common-1.21.1/src/main/resources/assets/antarchy/textures/block/verdant_nyxium.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/block/verdant_nyxium_old.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/block/verdant_nyxium_old.png new file mode 100644 index 00000000..15e56c68 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/block/verdant_nyxium_old.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/king/fire_ball.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/king/fire_ball.png new file mode 100644 index 00000000..d7a971ed Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/king/fire_ball.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/king/ice_ball.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/king/ice_ball.png new file mode 100644 index 00000000..4104a295 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/king/ice_ball.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/king/ice_spike.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/king/ice_spike.png new file mode 100644 index 00000000..7ea12b56 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/king/ice_spike.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/queen/black_hole.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/queen/black_hole.png new file mode 100644 index 00000000..17d72ada Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/queen/black_hole.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/queen/black_hole.png.mcmeta b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/queen/black_hole.png.mcmeta new file mode 100644 index 00000000..78df88c4 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/queen/black_hole.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 1 + } +} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/item/critter_cage_item_overlay.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/critter_cage_item_overlay.png new file mode 100644 index 00000000..aabed591 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/critter_cage_item_overlay.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/mob_effect/commanded.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/mob_effect/commanded.png new file mode 100644 index 00000000..b73a5b56 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/mob_effect/commanded.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/mob_effect/dilated.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/mob_effect/dilated.png new file mode 100644 index 00000000..d8527f96 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/mob_effect/dilated.png differ diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_cavaryn.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_cavaryn.json index 27995abf..01cfb732 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_cavaryn.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_cavaryn.json @@ -9,7 +9,7 @@ }, "display": { "announce_to_chat": true, - "background": "antarchy:block/myrmite", + "background": "antarchy:textures/block/myrmite/myrmite", "description": { "translate": "advancements.antarchy.visit_cavaryn.description" }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_elythia.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_elythia.json index 5b935177..90923ec0 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_elythia.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_elythia.json @@ -9,7 +9,7 @@ }, "display": { "announce_to_chat": true, - "background": "antarchy:block/ouranwood/mossy_ouranwood_log", + "background": "antarchy:textures/block/ouranwood/mossy_ouranwood_log", "description": { "translate": "advancements.antarchy.visit_elythia.description" }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_thoraxis.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_thoraxis.json index f605b113..d15356df 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_thoraxis.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_thoraxis.json @@ -9,7 +9,7 @@ }, "display": { "announce_to_chat": true, - "background": "antarchy:block/nyxite", + "background": "antarchy:textures/block/nyxite", "description": { "translate": "advancements.antarchy.visit_thoraxis.description" }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/dimension/elythia.json b/common-1.21.1/src/main/resources/data/antarchy/dimension/elythia.json index 935aec5f..61f88ac1 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/dimension/elythia.json +++ b/common-1.21.1/src/main/resources/data/antarchy/dimension/elythia.json @@ -4,536 +4,117 @@ "type": "minecraft:noise", "settings": "antarchy:elythia", "biome_source": { - "type": "antarchy:elythia_biome_source", - "moleworm_caves_max_y": 30, - "surface_biome_sample_y": 160, - "ocean_max_y": 62, - "sea_level": 60, + "type": "minecraft:multi_noise", "biomes": [ { - "biome": "antarchy:moleworm_caves", + "biome": "antarchy:elythia_ocean", "parameters": { - "temperature": 0.69, - "humidity": 0.95, - "continentalness": 0.56, - "erosion": 0.2, - "weirdness": 0.16, - "depth": 0.3, - "offset": 0.27 + "temperature": [0.45, 0.85], + "humidity": [0.75, 1.0], + "continentalness": [-1.0, -0.93], + "erosion": [-1.0, 1.0], + "weirdness": [-1.0, 1.0], + "depth": [0.0, 0.25], + "offset": 0.0 } }, { - "biome": "antarchy:moleworm_caves", + "biome": "antarchy:elythia_coral_spikes", "parameters": { - "temperature": 0.62, - "humidity": 0.92, - "continentalness": 0.48, - "erosion": 0.38, - "weirdness": -0.55, - "depth": 0.3, - "offset": 0.27 - } - }, - { - "biome": "antarchy:moleworm_caves", - "parameters": { - "temperature": 0.75, - "humidity": 0.96, - "continentalness": 0.64, - "erosion": 0.1, - "weirdness": 0.65, - "depth": 0.3, - "offset": 0.27 - } - }, - { - "biome": "antarchy:elythia_lush_caves", - "parameters": { - "temperature": 0.72, - "humidity": 1.0, - "continentalness": 0.52, - "erosion": 0.15, - "weirdness": -0.1, - "depth": 0.35, - "offset": 0.1 - } - }, - { - "biome": "antarchy:elythia_lush_caves", - "parameters": { - "temperature": 0.68, - "humidity": 0.99, - "continentalness": 0.6, - "erosion": 0.28, - "weirdness": 0.42, - "depth": 0.4, - "offset": 0.1 + "temperature": [0.72, 0.86], + "humidity": [0.78, 0.93], + "continentalness": [-1.0, -0.93], + "erosion": [-0.2, 0.45], + "weirdness": [0.35, 0.7], + "depth": [0.0, 0.25], + "offset": 0.0 } }, { "biome": "antarchy:elythia_meadow", "parameters": { - "temperature": 0.7, - "humidity": 0.94, - "continentalness": 0.55, - "erosion": 0.22, - "weirdness": -0.3, - "depth": 0.3, + "temperature": [0.55, 0.8], + "humidity": [0.82, 1.0], + "continentalness": [-0.93, 0.25], + "erosion": [-1.0, 0.65], + "weirdness": [-1.0, 0.2], + "depth": [0.0, 0.35], "offset": 0.0 } }, { "biome": "antarchy:truffalo_forest", "parameters": { - "temperature": 0.68, - "humidity": 0.96, - "continentalness": 0.57, - "erosion": 0.18, - "weirdness": 0.55, - "depth": 0.3, + "temperature": [0.55, 0.8], + "humidity": [0.82, 1.0], + "continentalness": [-0.93, 0.25], + "erosion": [-1.0, 0.65], + "weirdness": [0.2, 0.75], + "depth": [0.0, 0.3], "offset": 0.0 } }, { - "biome": "antarchy:peach_forest", + "biome": "antarchy:butterfly_fields", "parameters": { - "temperature": 0.67, - "humidity": 0.91, - "continentalness": 0.54, - "erosion": 0.16, - "weirdness": -0.42, - "depth": 0.45, + "temperature": [0.55, 0.8], + "humidity": [0.82, 1.0], + "continentalness": [-0.93, 0.25], + "erosion": [-1.0, 0.65], + "weirdness": [0.75, 1.0], + "depth": [0.0, 0.25], "offset": 0.0 } }, { - "biome": "antarchy:peach_forest", + "biome": "antarchy:ouranwood_forest", "parameters": { - "temperature": 0.66, - "humidity": 0.89, - "continentalness": 0.54, - "erosion": 0.38, - "weirdness": -0.42, - "depth": 0.45, + "temperature": [0.52, 0.78], + "humidity": [0.84, 1.0], + "continentalness": [0.25, 0.72], + "erosion": [-0.5, 0.55], + "weirdness": [-0.55, 0.62], + "depth": [0.0, 0.35], "offset": 0.0 } }, { - "biome": "antarchy:peach_forest", + "biome": "antarchy:fungal_ouranwood_forest", "parameters": { - "temperature": 0.68, - "humidity": 0.93, - "continentalness": 0.54, - "erosion": 0.16, - "weirdness": -0.74, - "depth": 0.45, - "offset": 0.0 - } - }, - { - "biome": "antarchy:peach_forest", - "parameters": { - "temperature": 0.65, - "humidity": 0.87, - "continentalness": 0.55, - "erosion": 0.38, - "weirdness": -0.74, - "depth": 0.45, + "temperature": [0.5, 0.68], + "humidity": [0.88, 1.0], + "continentalness": [0.32, 0.67], + "erosion": [-0.1, 0.35], + "weirdness": [0.68, 1.0], + "depth": [0.0, 0.3], "offset": 0.0 } }, { "biome": "antarchy:glimmering_pools", "parameters": { - "temperature": 0.67, - "humidity": 0.95, - "continentalness": 0.54, - "erosion": 0.23, - "weirdness": -0.46, - "depth": 0.45, + "temperature": [0.58, 0.76], + "humidity": [0.88, 1.0], + "continentalness": [0.3, 0.65], + "erosion": [-0.05, 0.45], + "weirdness": [-0.7, -0.25], + "depth": [0.0, 0.25], "offset": 0.0 } }, { - "biome": "antarchy:ouranwood_forest", + "biome": "antarchy:peach_forest", "parameters": { - "temperature": 0.67, - "humidity": 0.93, - "continentalness": 0.54, - "erosion": 0.25, - "weirdness": -0.5, - "depth": 0.45, + "temperature": [0.58, 0.8], + "humidity": [0.78, 0.98], + "continentalness": [0.72, 1.0], + "erosion": [-0.5, 0.65], + "weirdness": [-0.85, 0.7], + "depth": [0.0, 0.35], "offset": 0.0 } - }, - { - "biome": "antarchy:ouranwood_forest", - "parameters": { - "temperature": 0.67, - "humidity": 0.93, - "continentalness": 0.54, - "erosion": 0.2, - "weirdness": -0.4, - "depth": 0.45, - "offset": 0.0 - } - }, - { - "biome": "antarchy:ouranwood_forest", - "parameters": { - "temperature": 0.55, - "humidity": 0.9, - "continentalness": 0.9, - "erosion": 0.12, - "weirdness": -0.2, - "depth": 0.3, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_meadow", - "parameters": { - "temperature": 0.7, - "humidity": 0.95, - "continentalness": 0.38, - "erosion": 0.12, - "weirdness": -0.1, - "depth": 0.3, - "offset": 0.0 - } - }, - { - "biome": "antarchy:truffalo_forest", - "parameters": { - "temperature": 0.62, - "humidity": 0.98, - "continentalness": 0.78, - "erosion": 0.05, - "weirdness": 0.5, - "depth": 0.3, - "offset": 0.0 - } - }, - { - "biome": "antarchy:ouranwood_forest", - "parameters": { - "temperature": 0.55, - "humidity": 0.9, - "continentalness": 0.9, - "erosion": 0.12, - "weirdness": -0.2, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:sparse_ouranwood_forest", - "parameters": { - "temperature": 0.2, - "humidity": 0.62, - "continentalness": 0.95, - "erosion": -0.35, - "weirdness": 0.98, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:ouranwood_forest", - "parameters": { - "temperature": 0.55, - "humidity": 0.9, - "continentalness": 0.9, - "erosion": 0.12, - "weirdness": -0.2, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:fungal_ouranwood_forest", - "parameters": { - "temperature": 0.55, - "humidity": 0.9, - "continentalness": 0.75, - "erosion": 0.0, - "weirdness": 0.85, - "depth": 0.45, - "offset": 0.0 - } - }, - { - "biome": "antarchy:fungal_ouranwood_forest", - "parameters": { - "temperature": 0.55, - "humidity": 0.9, - "continentalness": 0.75, - "erosion": 0.0, - "weirdness": 0.85, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:butterfly_fields", - "parameters": { - "temperature": 0.74, - "humidity": 0.99, - "continentalness": 0.6, - "erosion": 0.17, - "weirdness": 0.28, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:butterfly_fields", - "parameters": { - "temperature": 0.76, - "humidity": 0.995, - "continentalness": 0.68, - "erosion": 0.12, - "weirdness": 0.36, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_meadow", - "parameters": { - "temperature": 0.7, - "humidity": 0.95, - "continentalness": 0.38, - "erosion": 0.12, - "weirdness": -0.1, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:truffalo_forest", - "parameters": { - "temperature": 0.7, - "humidity": 0.95, - "continentalness": 0.55, - "erosion": 0.22, - "weirdness": 0.15, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:ouranwood_forest", - "parameters": { - "temperature": 0.45, - "humidity": 0.85, - "continentalness": 0.75, - "erosion": 0.0, - "weirdness": 0.7, - "depth": 0.5, - "offset": 0.0 - } - }, - { - "biome": "antarchy:ouranwood_forest", - "parameters": { - "temperature": 0.55, - "humidity": 0.9, - "continentalness": 0.9, - "erosion": 0.12, - "weirdness": -0.2, - "depth": 0.5, - "offset": 0.0 - } - }, - { - "biome": "antarchy:butterfly_fields", - "parameters": { - "temperature": 0.66, - "humidity": 0.96, - "continentalness": 0.62, - "erosion": 0.13, - "weirdness": 0.2, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:butterfly_fields", - "parameters": { - "temperature": 0.7, - "humidity": 0.97, - "continentalness": 0.64, - "erosion": 0.15, - "weirdness": 0.1, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:butterfly_fields", - "parameters": { - "temperature": 0.72, - "humidity": 0.98, - "continentalness": 0.66, - "erosion": 0.14, - "weirdness": 0.32, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_meadow", - "parameters": { - "temperature": 0.66, - "humidity": 0.96, - "continentalness": 0.62, - "erosion": 0.13, - "weirdness": 0.2, - "depth": 0.85, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_ocean", - "parameters": { - "temperature": 0.65, - "humidity": 0.9, - "continentalness": -0.88, - "erosion": 0.3, - "weirdness": 0.0, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_ocean", - "parameters": { - "temperature": 0.6, - "humidity": 0.88, - "continentalness": -0.92, - "erosion": 0.25, - "weirdness": -0.4, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_ocean", - "parameters": { - "temperature": 0.7, - "humidity": 0.92, - "continentalness": -0.85, - "erosion": 0.35, - "weirdness": 0.4, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_ocean", - "parameters": { - "temperature": 0.65, - "humidity": 0.9, - "continentalness": -0.88, - "erosion": 0.3, - "weirdness": 0.0, - "depth": 0.5, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_ocean", - "parameters": { - "temperature": 0.6, - "humidity": 0.88, - "continentalness": -0.92, - "erosion": 0.25, - "weirdness": -0.4, - "depth": 0.5, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_coral_spikes", - "parameters": { - "temperature": 0.8, - "humidity": 0.85, - "continentalness": -0.88, - "erosion": 0.2, - "weirdness": 0.5, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_coral_spikes", - "parameters": { - "temperature": 0.75, - "humidity": 0.82, - "continentalness": -0.9, - "erosion": 0.15, - "weirdness": -0.55, - "depth": 0.0, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_coral_spikes", - "parameters": { - "temperature": 0.8, - "humidity": 0.85, - "continentalness": -0.88, - "erosion": 0.2, - "weirdness": 0.5, - "depth": 0.5, - "offset": 0.0 - } - }, - { - "biome": "antarchy:elythia_coral_spikes", - "parameters": { - "temperature": 0.75, - "humidity": 0.82, - "continentalness": -0.9, - "erosion": 0.15, - "weirdness": -0.55, - "depth": 0.5, - "offset": 0.0 - } - }, - { - "biome": "antarchy:cloud_sea", - "parameters": { - "temperature": [ - -1.0, - 1.0 - ], - "humidity": [ - -1.0, - 1.0 - ], - "continentalness": [ - -1.0, - 1.0 - ], - "erosion": [ - -1.0, - 1.0 - ], - "weirdness": [ - -1.0, - 1.0 - ], - "depth": [ - 0.0, - 1.0 - ], - "offset": 0.999 - } } - ], - "cloud_sea_min_y": 360 + ] } } } diff --git a/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/commanded_blacklist.json b/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/commanded_blacklist.json new file mode 100644 index 00000000..f42387d1 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/commanded_blacklist.json @@ -0,0 +1,14 @@ +{ + "replace": false, + "values": [ + "minecraft:player", + "minecraft:ender_dragon", + "minecraft:wither", + "minecraft:warden", + "#antarchy:spell_resistant_boss", + "antarchy:king", + "antarchy:queen", + "antarchy:prince", + "antarchy:princess" + ] +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/dilated_blacklist.json b/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/dilated_blacklist.json new file mode 100644 index 00000000..40b41861 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/dilated_blacklist.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "#antarchy:time_dilation_immune" + ] +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/butterfly_fields.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/butterfly_fields.json index 612deba5..2d9ca7c6 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/butterfly_fields.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/butterfly_fields.json @@ -87,7 +87,7 @@ }, { "type": "antarchy:enchanted_golden_apple_cow", - "weight": 4, + "weight": 1, "minCount": 1, "maxCount": 1 } diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/dream_dunes.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/dream_dunes.json index 5cf53a75..26d6fc25 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/dream_dunes.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/dream_dunes.json @@ -49,6 +49,7 @@ [], [ "antarchy:bluestone_ore", + "antarchy:thoraxis_ichor_lake", "antarchy:dimensional_tears" ], [], @@ -69,7 +70,7 @@ "monster": [ { "type": "antarchy:scorpion", - "weight": 20, + "weight": 40, "minCount": 2, "maxCount": 5 }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/elythia_meadow.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/elythia_meadow.json index 34cd6c3e..1b27eea0 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/elythia_meadow.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/elythia_meadow.json @@ -106,7 +106,7 @@ }, { "type": "antarchy:enchanted_golden_apple_cow", - "weight": 2, + "weight": 1, "minCount": 1, "maxCount": 1 }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/lucid_pools.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/lucid_pools.json index 75627be2..d6a77366 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/lucid_pools.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/lucid_pools.json @@ -46,7 +46,8 @@ [], [], [ - "antarchy:bluestone_ore" + "antarchy:bluestone_ore", + "antarchy:thoraxis_ichor_lake" ], [ "antarchy:lucid_blood_crystal_spires", diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/nadir_forest.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/nadir_forest.json index 9daa3733..1b1989fe 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/nadir_forest.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/nadir_forest.json @@ -44,6 +44,7 @@ [], [ "antarchy:bluestone_ore", + "antarchy:thoraxis_ichor_lake", "antarchy:dimensional_tears" ], [], diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/nightmare_wastes.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/nightmare_wastes.json index 16d3f49f..c853f78f 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/nightmare_wastes.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/nightmare_wastes.json @@ -46,7 +46,8 @@ [], [], [ - "antarchy:bluestone_ore" + "antarchy:bluestone_ore", + "antarchy:thoraxis_ichor_lake" ], [ "antarchy:thoraxis_floor_rib_columns", diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/truffalo_forest.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/truffalo_forest.json index 0c70145c..65623f09 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/truffalo_forest.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/truffalo_forest.json @@ -74,6 +74,7 @@ [], [ "antarchy:truffalo_forest_trees", + "antarchy:truffalo_large_forest_trees", "antarchy:elythia_meadow_large_tuff_boulders", "antarchy:elythia_meadow_tuff_boulders", "antarchy:elythia_meadow_flora", @@ -107,7 +108,7 @@ }, { "type": "antarchy:enchanted_golden_apple_cow", - "weight": 2, + "weight": 1, "minCount": 1, "maxCount": 1 }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/umbral_hills.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/umbral_hills.json index 942f7809..618f7bb7 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/umbral_hills.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/umbral_hills.json @@ -46,7 +46,8 @@ [], [], [ - "antarchy:bluestone_ore" + "antarchy:bluestone_ore", + "antarchy:thoraxis_ichor_lake" ], [ "antarchy:thoraxis_floor_spikes", diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/vortex_expanse.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/vortex_expanse.json index b649ded5..8d2563e2 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/vortex_expanse.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/biome/vortex_expanse.json @@ -53,6 +53,7 @@ [], [ "antarchy:bluestone_ore", + "antarchy:thoraxis_ichor_lake", "antarchy:dimensional_tears", "antarchy:typhonite_veined_ore" ], @@ -61,7 +62,7 @@ "antarchy:patch_fire" ], [ - "antarchy:typhonite_spikes", + "antarchy:vortex_expanse_typhonite_spikes", "antarchy:typhonite_swirls", "antarchy:patch_ceiling_fire" ], diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/configured_feature/thoraxis_ichor_lake.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/configured_feature/thoraxis_ichor_lake.json new file mode 100644 index 00000000..83423330 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/configured_feature/thoraxis_ichor_lake.json @@ -0,0 +1,4 @@ +{ + "type": "antarchy:thoraxis_ichor_lake", + "config": {} +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/configured_feature/truffalo_large_tree.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/configured_feature/truffalo_large_tree.json new file mode 100644 index 00000000..b19984b5 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/configured_feature/truffalo_large_tree.json @@ -0,0 +1,21 @@ +{ + "type": "antarchy:truffalo_tree", + "config": { + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "antarchy:truffalo_wood", + "Properties": { + "axis": "y" + } + } + }, + "height": { + "type": "minecraft:uniform", + "min_inclusive": 8, + "max_inclusive": 18 + }, + "tuft_radius": 2, + "tuft_height": 5 + } +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/density_function/elythia_surface.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/density_function/elythia_surface.json index 62c0bc38..4c151ba9 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/density_function/elythia_surface.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/density_function/elythia_surface.json @@ -1,86 +1,137 @@ { "type": "minecraft:cache_once", "argument": { - "type": "minecraft:clamp", - "min": -10.0, - "max": 10.0, - "input": { - "type": "minecraft:add", - "argument1": { - "type": "minecraft:y_clamped_gradient", - "from_y": -64, - "to_y": 220, - "from_value": 2.20, - "to_value": -1.90 - }, - "argument2": { - "type": "minecraft:add", - "argument1": { + "type": "minecraft:clamp", + "min": -10.0, + "max": 10.0, + "input": { "type": "minecraft:add", "argument1": { - "type": "minecraft:mul", - "argument1": 0.565, - "argument2": { - "type": "minecraft:noise", - "noise": "antarchy:elythia_surface", - "xz_scale": 0.65, - "y_scale": 0 - } + "type": "minecraft:y_clamped_gradient", + "from_y": -64, + "to_y": 220, + "from_value": 2.20, + "to_value": -1.90 }, "argument2": { "type": "minecraft:add", "argument1": { - "type": "minecraft:mul", - "argument1": 0.01, - "argument2": { - "type": "minecraft:noise", - "noise": "antarchy:elythia_surface_detail", - "xz_scale": 1.8, - "y_scale": 0 + "type": "minecraft:add", + "argument1": { + "type": "minecraft:add", + "argument1": { + "type": "minecraft:mul", + "argument1": 0.565, + "argument2": { + "type": "minecraft:noise", + "noise": "antarchy:elythia_surface", + "xz_scale": 0.65, + "y_scale": 0 + } + }, + "argument2": { + "type": "minecraft:add", + "argument1": { + "type": "minecraft:mul", + "argument1": 0.01, + "argument2": { + "type": "minecraft:noise", + "noise": "antarchy:elythia_surface_detail", + "xz_scale": 1.8, + "y_scale": 0 + } + }, + "argument2": { + "type": "minecraft:mul", + "argument1": 0.002, + "argument2": { + "type": "minecraft:noise", + "noise": "antarchy:elythia_surface_edge", + "xz_scale": 4.2, + "y_scale": 0 + } + } + } + }, + "argument2": { + "type": "minecraft:add", + "argument1": { + "type": "minecraft:mul", + "argument1": 0.17, + "argument2": "minecraft:overworld/depth" + }, + "argument2": { + "type": "minecraft:add", + "argument1": { + "type": "minecraft:mul", + "argument1": 0.003, + "argument2": "minecraft:overworld/ridges" + }, + "argument2": { + "type": "minecraft:add", + "argument1": { + "type": "antarchy:elythia_river_carve", + "erosion": "minecraft:overworld/erosion", + "ridges": "minecraft:overworld/ridges" + }, + "argument2": { + "type": "minecraft:mul", + "argument1": 0.58, + "argument2": "minecraft:overworld/continents" + } + } + } } }, - "argument2": { - "type": "minecraft:mul", - "argument1": 0.002, - "argument2": { - "type": "minecraft:noise", - "noise": "antarchy:elythia_surface_edge", - "xz_scale": 4.2, - "y_scale": 0 - } - } - } - }, - "argument2": { - "type": "minecraft:add", - "argument1": { - "type": "minecraft:mul", - "argument1": 0.17, - "argument2": "minecraft:overworld/depth" - }, - "argument2": { - "type": "minecraft:add", - "argument1": { - "type": "minecraft:mul", - "argument1": 0.003, - "argument2": "minecraft:overworld/ridges" - }, "argument2": { "type": "minecraft:add", "argument1": { - "type": "minecraft:mul", - "argument1": -0.06, - "argument2": "minecraft:overworld/erosion" + "type": "minecraft:range_choice", + "input": "minecraft:overworld/continents", + "min_inclusive": -1.0, + "max_exclusive": -0.93, + "when_in_range": { + "type": "minecraft:add", + "argument1": -0.85, + "argument2": { + "type": "minecraft:mul", + "argument1": 0.05, + "argument2": { + "type": "minecraft:noise", + "noise": "antarchy:elythia_terrain_roughness", + "xz_scale": 0.55, + "y_scale": 0 + } + } + }, + "when_out_of_range": 0.0 }, "argument2": { - "type": "minecraft:mul", - "argument1": 0.58, - "argument2": "minecraft:overworld/continents" + "type": "minecraft:range_choice", + "input": "minecraft:overworld/depth", + "min_inclusive": 0.35, + "max_exclusive": 0.52, + "when_in_range": { + "type": "minecraft:range_choice", + "input": "minecraft:overworld/ridges", + "min_inclusive": -0.80, + "max_exclusive": -0.30, + "when_in_range": { + "type": "minecraft:mul", + "argument1": 0.07, + "argument2": { + "type": "minecraft:noise", + "noise": "antarchy:elythia_terrain_roughness", + "xz_scale": 0.75, + "y_scale": 0 + } + }, + "when_out_of_range": 0.0 + }, + "when_out_of_range": 0.0 } } } } } - } - } } diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/noise/elythia_terrain_roughness.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/noise/elythia_terrain_roughness.json new file mode 100644 index 00000000..9641ed0e --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/noise/elythia_terrain_roughness.json @@ -0,0 +1,9 @@ +{ + "firstOctave": -5, + "amplitudes": [ + 1.0, + 0.8, + 0.5, + 0.3 + ] +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/noise_settings/elythia.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/noise_settings/elythia.json index 90c87438..7407b1a5 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/noise_settings/elythia.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/noise_settings/elythia.json @@ -515,12 +515,6 @@ "Name": "minecraft:sand" } } - }, - { - "type": "minecraft:block", - "result_state": { - "Name": "minecraft:sand" - } } ] } @@ -537,7 +531,7 @@ "then_run": { "type": "minecraft:block", "result_state": { - "Name": "antarchy:shellstone" + "Name": "minecraft:gravel" } } }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/elythia_underground.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/elythia_underground.json index e7cd0ebf..676693f1 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/elythia_underground.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/elythia_underground.json @@ -16,7 +16,7 @@ "absolute": -48 }, "max_inclusive": { - "absolute": 96 + "absolute": 32 } } }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/thoraxis_ichor_lake.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/thoraxis_ichor_lake.json new file mode 100644 index 00000000..5ef5b1e4 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/thoraxis_ichor_lake.json @@ -0,0 +1,23 @@ +{ + "feature": "antarchy:thoraxis_ichor_lake", + "placement": [ + { + "type": "minecraft:count", + "count": 1 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "min_inclusive": { "absolute": 1 }, + "max_inclusive": { "absolute": 1 } + } + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/truffalo_large_forest_trees.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/truffalo_large_forest_trees.json new file mode 100644 index 00000000..9e4be354 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/truffalo_large_forest_trees.json @@ -0,0 +1,19 @@ +{ + "feature": "antarchy:truffalo_large_tree", + "placement": [ + { + "type": "minecraft:rarity_filter", + "chance": 96 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "WORLD_SURFACE_WG" + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/typhonite_spikes.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/typhonite_spikes.json index 84b99253..62000750 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/typhonite_spikes.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/typhonite_spikes.json @@ -3,7 +3,7 @@ "placement": [ { "type": "minecraft:count", - "count": 3 + "count": 6 }, { "type": "minecraft:in_square" diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/typhonite_veined_ore.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/typhonite_veined_ore.json index 22e8c988..6f2d2b7d 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/typhonite_veined_ore.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/typhonite_veined_ore.json @@ -5,8 +5,8 @@ "type": "minecraft:count", "count": { "type": "minecraft:uniform", - "min_inclusive": 4, - "max_inclusive": 8 + "min_inclusive": 8, + "max_inclusive": 12 } }, { diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/vortex_expanse_typhonite_spikes.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/vortex_expanse_typhonite_spikes.json new file mode 100644 index 00000000..877b3e80 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/vortex_expanse_typhonite_spikes.json @@ -0,0 +1,27 @@ +{ + "feature": "antarchy:typhonite_spikes", + "placement": [ + { + "type": "minecraft:count", + "count": 18 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "min_inclusive": { + "above_bottom": 16 + }, + "max_inclusive": { + "below_top": 16 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/fabric-1.20.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java b/fabric-1.20.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java index 7cdd94f5..7edab2bd 100644 --- a/fabric-1.20.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java +++ b/fabric-1.20.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java @@ -206,7 +206,7 @@ public final class AntarchyFabric implements ModInitializer { ); BiomeModifications.addSpawn( BiomeSelectors.tag(OCTOPUS_BOMB_SPAWN_BIOMES), - net.minecraft.world.entity.MobCategory.MONSTER, + net.minecraft.world.entity.MobCategory.WATER_CREATURE, AntarchyFabricEntities.OCTOPUS_BOMB.get(), 2, 1, 2 ); diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java index 8ee6fde0..2b1701de 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabric.java @@ -207,7 +207,7 @@ public final class AntarchyFabric implements ModInitializer { ); BiomeModifications.addSpawn( BiomeSelectors.tag(OCTOPUS_BOMB_SPAWN_BIOMES), - net.minecraft.world.entity.MobCategory.MONSTER, + net.minecraft.world.entity.MobCategory.WATER_CREATURE, AntarchyFabricEntities.OCTOPUS_BOMB.get(), 2, 1, 2 ); diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java index 57d3f89d..da4596d5 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java @@ -92,6 +92,10 @@ public final class AntarchyFabricContent { builder.registerPotionRecipe(net.minecraft.world.item.alchemy.Potions.AWKWARD, Ingredient.of(AntarchyFabricItems.TITANIUM_NUGGET.get()), potionHolder(AntarchyFabricMisc.GROWING)); builder.registerPotionRecipe(potionHolder(AntarchyFabricMisc.GROWING), Ingredient.of(Items.GLOWSTONE_DUST), potionHolder(AntarchyFabricMisc.STRONG_GROWING)); builder.registerPotionRecipe(potionHolder(AntarchyFabricMisc.STRONG_GROWING), Ingredient.of(Items.GLOWSTONE_DUST), potionHolder(AntarchyFabricMisc.EXTREME_GROWING)); + builder.registerPotionRecipe(net.minecraft.world.item.alchemy.Potions.AWKWARD, Ingredient.of(AntarchyFabricItems.KING_SCALE.get()), potionHolder(AntarchyFabricMisc.COMMAND)); + builder.registerPotionRecipe(potionHolder(AntarchyFabricMisc.COMMAND), Ingredient.of(Items.REDSTONE), potionHolder(AntarchyFabricMisc.LONG_COMMAND)); + builder.registerPotionRecipe(net.minecraft.world.item.alchemy.Potions.AWKWARD, Ingredient.of(AntarchyFabricItems.QUEEN_SCALE.get()), potionHolder(AntarchyFabricMisc.TIME_DILATION)); + builder.registerPotionRecipe(potionHolder(AntarchyFabricMisc.TIME_DILATION), Ingredient.of(Items.REDSTONE), potionHolder(AntarchyFabricMisc.LONG_TIME_DILATION)); builder.registerPotionRecipe(net.minecraft.world.item.alchemy.Potions.AWKWARD, Ingredient.of(AntarchyFabricItems.CLOUD_SHARK_FIN.get()), net.minecraft.world.item.alchemy.Potions.SLOW_FALLING); builder.registerPotionRecipe(net.minecraft.world.item.alchemy.Potions.AWKWARD, Ingredient.of(AntarchyFabricItems.JUMPY_BUG_LEG.get()), Potions.LEAPING); builder.registerPotionRecipe(net.minecraft.world.item.alchemy.Potions.AWKWARD, Ingredient.of(AntarchyFabricItems.CORNEA_EAR.get()), net.minecraft.world.item.alchemy.Potions.NIGHT_VISION); @@ -324,6 +328,7 @@ public final class AntarchyFabricContent { AntarchyFabricSounds.KING_ROAR, AntarchyFabricSounds.KING_WING_FLAP, AntarchyFabricSounds.KING_FLY_LOOP, + AntarchyFabricSounds.QUEEN_FLY_LOOP, AntarchyFabricSounds.PRINCE_IDLE, AntarchyFabricSounds.PRINCE_BITE, AntarchyFabricSounds.PRINCE_SHOOT, @@ -360,6 +365,8 @@ public final class AntarchyFabricContent { AntarchyObjects.setQueen(() -> AntarchyFabricEntities.QUEEN.get()); AntarchyObjects.setManticore(() -> AntarchyFabricEntities.MANTICORE.get()); AntarchyObjects.setRoyalBolt(() -> AntarchyFabricEntities.ROYAL_BOLT.get()); + AntarchyObjects.setRoyalElementalProjectile(() -> AntarchyFabricEntities.ROYAL_ELEMENTAL_PROJECTILE.get()); + AntarchyObjects.setRoyalIceSpike(() -> AntarchyFabricEntities.ROYAL_ICE_SPIKE.get()); AntarchyObjects.setPrinceEgg(() -> AntarchyFabricBlocks.PRINCE_EGG.get()); AntarchyObjects.setPrincessEgg(() -> AntarchyFabricBlocks.PRINCESS_EGG.get()); AntarchyObjects.setRoyalEggBlockEntity(() -> AntarchyFabricBlocks.ROYAL_EGG_BLOCK_ENTITY.get()); diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java index 2a31b6b4..d019edc2 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java @@ -146,7 +146,7 @@ public final class AntarchyFabricClientBootstrap { EntityRendererRegistry.register(AntarchyFabricEntities.VORTEX_CHARGE_PROJECTILE.get(), ThrownItemRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.WIND_VORTEX.get(), WindVortexRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.TIME_DILATION_FIELD.get(), TimeDilationFieldRenderer::new); - EntityRendererRegistry.register(AntarchyFabricEntities.ROYAL_BLACK_HOLE.get(), net.minecraft.client.renderer.entity.NoopRenderer::new); + EntityRendererRegistry.register(AntarchyFabricEntities.ROYAL_BLACK_HOLE.get(), com.craisinlord.antarchy.content.client.renderer.RoyalBlackHoleRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.CRITTER_CAGE_PROJECTILE.get(), ThrownItemRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.WORM_HOOK_PROJECTILE.get(), ThrownItemRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.HUSH_PROJECTILE.get(), HushProjectileRenderer::new); @@ -172,6 +172,8 @@ public final class AntarchyFabricClientBootstrap { EntityRendererRegistry.register(AntarchyFabricEntities.KING.get(), com.craisinlord.antarchy.content.client.renderer.RoyalBossRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.QUEEN.get(), com.craisinlord.antarchy.content.client.renderer.RoyalBossRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.ROYAL_BOLT.get(), com.craisinlord.antarchy.content.client.renderer.RoyalBoltRenderer::new); + EntityRendererRegistry.register(AntarchyFabricEntities.ROYAL_ELEMENTAL_PROJECTILE.get(), com.craisinlord.antarchy.content.client.renderer.RoyalElementalProjectileRenderer::new); + EntityRendererRegistry.register(AntarchyFabricEntities.ROYAL_ICE_SPIKE.get(), com.craisinlord.antarchy.content.client.renderer.RoyalIceSpikeRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.JERRY.get(), JerryRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.JUMPY_BUG.get(), JumpyBugRenderer::new); EntityRendererRegistry.register(AntarchyFabricEntities.SPIT_BUG.get(), SpitBugRenderer::new); diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntities.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntities.java index be1ddd37..43ef66f1 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntities.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricEntities.java @@ -512,6 +512,7 @@ public final class AntarchyFabricEntities { () -> EntityType.Builder.of(ScorpionEntity::new, MobCategory.MONSTER) .sized(1.5F, 1.0F) .clientTrackingRange(8) + .fireImmune() .build("scorpion")); @@ -526,6 +527,7 @@ public final class AntarchyFabricEntities { () -> EntityType.Builder.of(EmperorScorpionEntity::new, MobCategory.MONSTER) .sized(6.0F, 3.0F) .clientTrackingRange(12) + .fireImmune() .build("emperor_scorpion")); @@ -613,6 +615,7 @@ public final class AntarchyFabricEntities { () -> EntityType.Builder.of(com.craisinlord.antarchy.content.entity.ManticoreEntity::new, MobCategory.MONSTER) .sized(1.95F, 2.0F) .clientTrackingRange(10) + .fireImmune() .build("manticore")); @@ -678,6 +681,18 @@ public final class AntarchyFabricEntities { .clientTrackingRange(8) .updateInterval(1) .fireImmune().build("royal_bolt")); + public static final DeferredHolder, EntityType> ROYAL_ELEMENTAL_PROJECTILE = ENTITY_TYPES.register("royal_elemental_projectile", + () -> EntityType.Builder.of(com.craisinlord.antarchy.content.entity.royal.RoyalElementalProjectileEntity::new, MobCategory.MISC) + .sized(1.0F, 1.0F) + .clientTrackingRange(16) + .updateInterval(1) + .fireImmune().build("royal_elemental_projectile")); + public static final DeferredHolder, EntityType> ROYAL_ICE_SPIKE = ENTITY_TYPES.register("royal_ice_spike", + () -> EntityType.Builder.of(com.craisinlord.antarchy.content.entity.royal.RoyalIceSpikeEntity::new, MobCategory.MISC) + .sized(2.0F, 4.0F) + .clientTrackingRange(16) + .updateInterval(1) + .fireImmune().build("royal_ice_spike")); public static final DeferredHolder, EntityType> OURANWOOD_DEER = ENTITY_TYPES.register("ouranwood_deer", diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricMisc.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricMisc.java index 4667b59b..626843a5 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricMisc.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricMisc.java @@ -23,11 +23,14 @@ import com.craisinlord.antarchy.content.worldgen.thoraxis.TyphoniteSpikeConfigur import com.craisinlord.antarchy.content.worldgen.thoraxis.TyphoniteSpikeFeature; import com.craisinlord.antarchy.content.worldgen.thoraxis.TyphoniteSwirlFeature; import com.craisinlord.antarchy.content.worldgen.thoraxis.PotentNyxiteFeature; +import com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisIchorLakeFeature; import com.craisinlord.antarchy.fabric.content.fluid.AntiwaterFluid; import com.craisinlord.antarchy.content.effect.DreadMobEffect; import com.craisinlord.antarchy.content.effect.GoopedMobEffect; import com.craisinlord.antarchy.content.effect.GrowthMobEffect; import com.craisinlord.antarchy.content.effect.InvertedMobEffect; +import com.craisinlord.antarchy.content.effect.CommandedMobEffect; +import com.craisinlord.antarchy.content.effect.DilatedMobEffect; import com.craisinlord.antarchy.content.effect.ParalyzedMobEffect; import com.craisinlord.antarchy.content.effect.ShrinkMobEffect; import com.craisinlord.antarchy.content.effect.StinkyMobEffect; @@ -391,6 +394,8 @@ public final class AntarchyFabricMisc { public static final DeferredHolder INVERTED = MOB_EFFECTS.register("inverted", InvertedMobEffect::new); + public static final DeferredHolder COMMANDED = MOB_EFFECTS.register("commanded", CommandedMobEffect::new); + public static final DeferredHolder DILATED = MOB_EFFECTS.register("dilated", DilatedMobEffect::new); public static final DeferredHolder STINKY = MOB_EFFECTS.register("stinky", StinkyMobEffect::new); @@ -425,6 +430,14 @@ public final class AntarchyFabricMisc { public static final DeferredHolder LONG_INVERSION = POTIONS.register("long_inversion", () -> new Potion("inversion", new MobEffectInstance(mobEffectHolder(INVERTED), 2400))); + public static final DeferredHolder COMMAND = POTIONS.register("command", + () -> new Potion(new MobEffectInstance(mobEffectHolder(COMMANDED), 600))); + public static final DeferredHolder LONG_COMMAND = POTIONS.register("long_command", + () -> new Potion("command", new MobEffectInstance(mobEffectHolder(COMMANDED), 1200))); + public static final DeferredHolder TIME_DILATION = POTIONS.register("time_dilation", + () -> new Potion(new MobEffectInstance(mobEffectHolder(DILATED), 300))); + public static final DeferredHolder LONG_TIME_DILATION = POTIONS.register("long_time_dilation", + () -> new Potion("time_dilation", new MobEffectInstance(mobEffectHolder(DILATED), 600))); public static final DeferredHolder STINKY_POTION = POTIONS.register("stinky", @@ -833,6 +846,9 @@ public final class AntarchyFabricMisc { public static final DeferredHolder, DimensionalTearFeature> DIMENSIONAL_TEAR = FEATURES.register("dimensional_tear", () -> new DimensionalTearFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, ThoraxisIchorLakeFeature> THORAXIS_ICHOR_LAKE = FEATURES.register("thoraxis_ichor_lake", + () -> new ThoraxisIchorLakeFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, CoralSpikeFeature> ELYTHIA_CORAL_SPIKE = FEATURES.register("elythia_coral_spike", () -> new CoralSpikeFeature(NoneFeatureConfiguration.CODEC)); diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyConfigModuleNeoforge.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyConfigModuleNeoforge.java index 14f681c5..f8012706 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyConfigModuleNeoforge.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyConfigModuleNeoforge.java @@ -152,6 +152,8 @@ public final class AntarchyConfigModuleNeoforge { AntarchySettings.setQueenBeamDamage(AntarchyMobsConfig.queenBeamDamage()); AntarchySettings.setQueenBeamRange(AntarchyMobsConfig.queenBeamRange()); AntarchySettings.setQueenBeamDurationTicks(AntarchyMobsConfig.queenBeamDurationTicks()); + AntarchySettings.setQueenBeamWindupTicks(AntarchyMobsConfig.queenBeamWindupTicks()); + AntarchySettings.setQueenBeamTravelTicks(AntarchyMobsConfig.queenBeamTravelTicks()); AntarchySettings.setQueenBeamCooldownTicks(AntarchyMobsConfig.queenBeamCooldownTicks()); AntarchySettings.setQueenBeamTracking(AntarchyMobsConfig.queenBeamTracking()); AntarchySettings.setQueenBeamTerrainRadius(AntarchyMobsConfig.queenBeamTerrainRadius()); @@ -159,11 +161,30 @@ public final class AntarchyConfigModuleNeoforge { AntarchySettings.setKingBeamDamage(AntarchyMobsConfig.kingBeamDamage()); AntarchySettings.setKingBeamRange(AntarchyMobsConfig.kingBeamRange()); AntarchySettings.setKingBeamDurationTicks(AntarchyMobsConfig.kingBeamDurationTicks()); + AntarchySettings.setKingBeamWindupTicks(AntarchyMobsConfig.kingBeamWindupTicks()); + AntarchySettings.setKingBeamTravelTicks(AntarchyMobsConfig.kingBeamTravelTicks()); AntarchySettings.setKingBeamCooldownTicks(AntarchyMobsConfig.kingBeamCooldownTicks()); AntarchySettings.setKingBeamTracking(AntarchyMobsConfig.kingBeamTracking()); AntarchySettings.setKingBeamTerrainRadius(AntarchyMobsConfig.kingBeamTerrainRadius()); AntarchySettings.setKingBeamTerrainCap(AntarchyMobsConfig.kingBeamTerrainCap()); AntarchySettings.setRoyalDecreeCooldownTicks(AntarchyMobsConfig.royalDecreeCooldownTicks()); + AntarchySettings.setQueenBlackHoleRadius(AntarchyMobsConfig.queenBlackHoleRadius()); + AntarchySettings.setQueenBlackHoleActiveTicks(AntarchyMobsConfig.queenBlackHoleActiveTicks()); + AntarchySettings.setQueenBlackHolePullStrength(AntarchyMobsConfig.queenBlackHolePullStrength()); + AntarchySettings.setQueenFinalTimeFieldRadius(AntarchyMobsConfig.queenFinalTimeFieldRadius()); + AntarchySettings.setQueenFinalTimeFieldRate(AntarchyMobsConfig.queenFinalTimeFieldRate()); + AntarchySettings.setQueenFinalTimeFieldDurationTicks(AntarchyMobsConfig.queenFinalTimeFieldDurationTicks()); + AntarchySettings.setQueenFinalTimeFieldCooldownTicks(AntarchyMobsConfig.queenFinalTimeFieldCooldownTicks()); + AntarchySettings.setKingFireballDamage(AntarchyMobsConfig.kingFireballDamage()); + AntarchySettings.setKingFireballRadius(AntarchyMobsConfig.kingFireballRadius()); + AntarchySettings.setKingFireballCooldownTicks(AntarchyMobsConfig.kingFireballCooldownTicks()); + AntarchySettings.setKingIceballDamage(AntarchyMobsConfig.kingIceballDamage()); + AntarchySettings.setKingIceballRadius(AntarchyMobsConfig.kingIceballRadius()); + AntarchySettings.setKingIceballCooldownTicks(AntarchyMobsConfig.kingIceballCooldownTicks()); + AntarchySettings.setKingIceSpikeDamage(AntarchyMobsConfig.kingIceSpikeDamage()); + AntarchySettings.setKingIceSpikeCooldownTicks(AntarchyMobsConfig.kingIceSpikeCooldownTicks()); + AntarchySettings.setKingElementalTerrainCap(AntarchyMobsConfig.kingElementalTerrainCap()); + AntarchySettings.setRoyalBossSoundVolume(AntarchyMobsConfig.royalBossSoundVolume()); AntarchySettings.setRoyalEggHatchChance(AntarchyMobsConfig.royalEggHatchChance()); AntarchySettings.setRoyalBoltDamage(AntarchyMobsConfig.royalBoltDamage()); diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMobsConfig.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMobsConfig.java index 1bc19d80..26b4c255 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMobsConfig.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMobsConfig.java @@ -125,10 +125,17 @@ public final class AntarchyMobsConfig { private static final ModConfigSpec.DoubleValue ROYAL_BOSS_BITE_DAMAGE_MULTIPLIER; private static final ModConfigSpec.IntValue ROYAL_BOSS_BITE_COOLDOWN_TICKS; private static final ModConfigSpec.DoubleValue QUEEN_BEAM_DAMAGE, QUEEN_BEAM_RANGE, QUEEN_BEAM_TRACKING, QUEEN_BEAM_TERRAIN_RADIUS; - private static final ModConfigSpec.IntValue QUEEN_BEAM_DURATION_TICKS, QUEEN_BEAM_COOLDOWN_TICKS, QUEEN_BEAM_TERRAIN_CAP; + private static final ModConfigSpec.IntValue QUEEN_BEAM_DURATION_TICKS, QUEEN_BEAM_WINDUP_TICKS, QUEEN_BEAM_TRAVEL_TICKS, QUEEN_BEAM_COOLDOWN_TICKS, QUEEN_BEAM_TERRAIN_CAP; private static final ModConfigSpec.DoubleValue KING_BEAM_DAMAGE, KING_BEAM_RANGE, KING_BEAM_TRACKING, KING_BEAM_TERRAIN_RADIUS; - private static final ModConfigSpec.IntValue KING_BEAM_DURATION_TICKS, KING_BEAM_COOLDOWN_TICKS, KING_BEAM_TERRAIN_CAP; + private static final ModConfigSpec.IntValue KING_BEAM_DURATION_TICKS, KING_BEAM_WINDUP_TICKS, KING_BEAM_TRAVEL_TICKS, KING_BEAM_COOLDOWN_TICKS, KING_BEAM_TERRAIN_CAP; private static final ModConfigSpec.IntValue ROYAL_DECREE_COOLDOWN_TICKS; + private static final ModConfigSpec.DoubleValue QUEEN_BLACK_HOLE_RADIUS, QUEEN_BLACK_HOLE_PULL_STRENGTH, + QUEEN_FINAL_TIME_FIELD_RADIUS, QUEEN_FINAL_TIME_FIELD_RATE; + private static final ModConfigSpec.IntValue QUEEN_BLACK_HOLE_ACTIVE_TICKS, + QUEEN_FINAL_TIME_FIELD_DURATION_TICKS, QUEEN_FINAL_TIME_FIELD_COOLDOWN_TICKS; + private static final ModConfigSpec.DoubleValue ROYAL_BOSS_SOUND_VOLUME; + private static final ModConfigSpec.DoubleValue KING_FIREBALL_DAMAGE, KING_FIREBALL_RADIUS, KING_ICEBALL_DAMAGE, KING_ICEBALL_RADIUS, KING_ICE_SPIKE_DAMAGE; + private static final ModConfigSpec.IntValue KING_FIREBALL_COOLDOWN_TICKS, KING_ICEBALL_COOLDOWN_TICKS, KING_ICE_SPIKE_COOLDOWN_TICKS, KING_ELEMENTAL_TERRAIN_CAP; // Royal mounts @@ -579,6 +586,8 @@ public final class AntarchyMobsConfig { QUEEN_BEAM_DAMAGE = b.defineInRange("queenBeamDamage", 45.0D, 0.0D, 1024.0D); QUEEN_BEAM_RANGE = b.defineInRange("queenBeamRange", 100.0D, 1.0D, 256.0D); QUEEN_BEAM_DURATION_TICKS = b.defineInRange("queenBeamDurationTicks", 30, 1, 1200); + QUEEN_BEAM_WINDUP_TICKS = b.comment("Charge time before the Queen beam actually fires.").defineInRange("queenBeamWindupTicks", 20, 0, 1200); + QUEEN_BEAM_TRAVEL_TICKS = b.comment("Time for the Queen beam to extend from its head to its committed range.").defineInRange("queenBeamTravelTicks", 12, 1, 1200); QUEEN_BEAM_COOLDOWN_TICKS = b.defineInRange("queenBeamCooldownTicks", 90, 1, 2400); QUEEN_BEAM_TRACKING = b.defineInRange("queenBeamTracking", 0.1D, 0.0D, 1.0D); QUEEN_BEAM_TERRAIN_RADIUS = b.defineInRange("queenBeamTerrainRadius", 5.0D, 0.0D, 32.0D); @@ -586,11 +595,30 @@ public final class AntarchyMobsConfig { KING_BEAM_DAMAGE = b.defineInRange("kingBeamDamage", 50.0D, 0.0D, 1024.0D); KING_BEAM_RANGE = b.defineInRange("kingBeamRange", 100.0D, 1.0D, 256.0D); KING_BEAM_DURATION_TICKS = b.defineInRange("kingBeamDurationTicks", 30, 1, 1200); + KING_BEAM_WINDUP_TICKS = b.comment("Charge time before the King beam actually fires.").defineInRange("kingBeamWindupTicks", 20, 0, 1200); + KING_BEAM_TRAVEL_TICKS = b.comment("Time for the King beam to extend from its head to its committed range.").defineInRange("kingBeamTravelTicks", 12, 1, 1200); KING_BEAM_COOLDOWN_TICKS = b.defineInRange("kingBeamCooldownTicks", 90, 1, 2400); KING_BEAM_TRACKING = b.defineInRange("kingBeamTracking", 0.1D, 0.0D, 1.0D); KING_BEAM_TERRAIN_RADIUS = b.defineInRange("kingBeamTerrainRadius", 5.0D, 0.0D, 32.0D); KING_BEAM_TERRAIN_CAP = b.defineInRange("kingBeamTerrainCap", 192, 0, 4096); ROYAL_DECREE_COOLDOWN_TICKS = b.comment("Cooldown in ticks between the end of one King decree and the next.").defineInRange("royalDecreeCooldownTicks", 1200, 1, 72000); + QUEEN_BLACK_HOLE_RADIUS = b.defineInRange("queenBlackHoleRadius", 14.0D, 1.0D, 64.0D); + QUEEN_BLACK_HOLE_ACTIVE_TICKS = b.defineInRange("queenBlackHoleActiveTicks", 120, 20, 1200); + QUEEN_BLACK_HOLE_PULL_STRENGTH = b.defineInRange("queenBlackHolePullStrength", 0.16D, 0.0D, 2.0D); + QUEEN_FINAL_TIME_FIELD_RADIUS = b.defineInRange("queenFinalTimeFieldRadius", 20.0D, 1.0D, 64.0D); + QUEEN_FINAL_TIME_FIELD_RATE = b.defineInRange("queenFinalTimeFieldRate", 0.05D, 0.05D, 1.0D); + QUEEN_FINAL_TIME_FIELD_DURATION_TICKS = b.defineInRange("queenFinalTimeFieldDurationTicks", 45, 1, 1200); + QUEEN_FINAL_TIME_FIELD_COOLDOWN_TICKS = b.defineInRange("queenFinalTimeFieldCooldownTicks", 80, 1, 2400); + KING_FIREBALL_DAMAGE = b.defineInRange("kingFireballDamage", 32.0D, 0.0D, 1024.0D); + KING_FIREBALL_RADIUS = b.defineInRange("kingFireballRadius", 4.5D, 0.5D, 32.0D); + KING_FIREBALL_COOLDOWN_TICKS = b.defineInRange("kingFireballCooldownTicks", 150, 1, 2400); + KING_ICEBALL_DAMAGE = b.defineInRange("kingIceballDamage", 18.0D, 0.0D, 1024.0D); + KING_ICEBALL_RADIUS = b.defineInRange("kingIceballRadius", 5.0D, 0.5D, 32.0D); + KING_ICEBALL_COOLDOWN_TICKS = b.defineInRange("kingIceballCooldownTicks", 190, 1, 2400); + KING_ICE_SPIKE_DAMAGE = b.defineInRange("kingIceSpikeDamage", 24.0D, 0.0D, 1024.0D); + KING_ICE_SPIKE_COOLDOWN_TICKS = b.defineInRange("kingIceSpikeCooldownTicks", 240, 1, 2400); + KING_ELEMENTAL_TERRAIN_CAP = b.defineInRange("kingElementalTerrainCap", 256, 0, 4096); + ROYAL_BOSS_SOUND_VOLUME = b.comment("Volume multiplier for large King and Queen presence, movement, and attack sounds.").defineInRange("royalBossSoundVolume", 4.5D, 0.5D, 16.0D); b.pop(); b.push("royalMounts"); @@ -726,8 +754,8 @@ public final class AntarchyMobsConfig { b.push("dimensionalTear"); DIMENSIONAL_TEAR_LIFETIME_TICKS = b.comment("Ticks before naturally generated linked Dimensional Tears collapse.").defineInRange("lifetimeTicks", 24000, 1200, 240000); DIMENSIONAL_TEAR_INVERTED_DURATION_TICKS = b.comment("Ticks of Inverted applied to living entities exiting a Dimensional Tear.").defineInRange("invertedDurationTicks", 2400, 0, 240000); - DIMENSIONAL_TEAR_EMERGENCE_MIN_INTERVAL_TICKS = b.comment("Minimum ticks between Nightmare/Lucid emergence events per tear.").defineInRange("emergenceMinIntervalTicks", 2400, 20, 240000); - DIMENSIONAL_TEAR_EMERGENCE_MAX_INTERVAL_TICKS = b.comment("Maximum ticks between Nightmare/Lucid emergence events per tear.").defineInRange("emergenceMaxIntervalTicks", 7200, 20, 240000); + DIMENSIONAL_TEAR_EMERGENCE_MIN_INTERVAL_TICKS = b.comment("Minimum ticks between Nightmare/Lucid emergence events per tear.").defineInRange("emergenceMinIntervalTicks", 400, 20, 240000); + DIMENSIONAL_TEAR_EMERGENCE_MAX_INTERVAL_TICKS = b.comment("Maximum ticks between Nightmare/Lucid emergence events per tear.").defineInRange("emergenceMaxIntervalTicks", 1200, 20, 240000); DIMENSIONAL_TEAR_LUCID_EVENT_CHANCE = b.comment("Chance that an emergence event spawns a Lucid instead of a Nightmare.").defineInRange("lucidEventChance", 0.65D, 0.0D, 1.0D); b.pop(); @@ -787,7 +815,7 @@ public final class AntarchyMobsConfig { VORTEX_MOVEMENT_SPEED = b.comment("Base movement speed.").defineInRange("movementSpeed", 0.22D, 0.0D, 10.0D); VORTEX_FLYING_SPEED = b.comment("Base flying speed.").defineInRange("flyingSpeed", 0.35D, 0.0D, 10.0D); VORTEX_MAX_ACTIVE_VORTEXES = b.comment("Maximum damaging wind vortexes one Vortex mob can maintain at once.").defineInRange("maxActiveVortexes", 3, 0, 32); - WIND_VORTEX_DURATION_TICKS = b.comment("Lifetime in ticks for wind vortexes spawned by Vortex charges or Vortex mobs.").defineInRange("windVortexDurationTicks", 140, 1, 1200); + WIND_VORTEX_DURATION_TICKS = b.comment("Lifetime in ticks for wind vortexes spawned by Vortex charges or Vortex mobs.").defineInRange("windVortexDurationTicks", 240, 1, 1200); WIND_VORTEX_PULL_STRENGTH = b.comment("How strongly wind vortexes pull entities toward their spiral path.").defineInRange("windVortexPullStrength", 0.32D, 0.0D, 4.0D); WIND_VORTEX_LAUNCH_STRENGTH = b.comment("Launch velocity multiplier applied when entities exit the top of a wind vortex.").defineInRange("windVortexLaunchStrength", 1.0D, 0.0D, 4.0D); VORTEX_LENS_MIN_RADIUS = b.comment("Top radius at signal strength 1 for Vortex Lens wind vortexes.").defineInRange("vortexLensMinRadius", 1.5D, 0.1D, 64.0D); @@ -995,6 +1023,8 @@ public final class AntarchyMobsConfig { static double queenBeamDamage() { return QUEEN_BEAM_DAMAGE.get(); } static double queenBeamRange() { return QUEEN_BEAM_RANGE.get(); } static int queenBeamDurationTicks() { return QUEEN_BEAM_DURATION_TICKS.get(); } + static int queenBeamWindupTicks() { return QUEEN_BEAM_WINDUP_TICKS.get(); } + static int queenBeamTravelTicks() { return QUEEN_BEAM_TRAVEL_TICKS.get(); } static int queenBeamCooldownTicks() { return QUEEN_BEAM_COOLDOWN_TICKS.get(); } static double queenBeamTracking() { return QUEEN_BEAM_TRACKING.get(); } static double queenBeamTerrainRadius() { return QUEEN_BEAM_TERRAIN_RADIUS.get(); } @@ -1002,11 +1032,30 @@ public final class AntarchyMobsConfig { static double kingBeamDamage() { return KING_BEAM_DAMAGE.get(); } static double kingBeamRange() { return KING_BEAM_RANGE.get(); } static int kingBeamDurationTicks() { return KING_BEAM_DURATION_TICKS.get(); } + static int kingBeamWindupTicks() { return KING_BEAM_WINDUP_TICKS.get(); } + static int kingBeamTravelTicks() { return KING_BEAM_TRAVEL_TICKS.get(); } static int kingBeamCooldownTicks() { return KING_BEAM_COOLDOWN_TICKS.get(); } static double kingBeamTracking() { return KING_BEAM_TRACKING.get(); } static double kingBeamTerrainRadius() { return KING_BEAM_TERRAIN_RADIUS.get(); } static int kingBeamTerrainCap() { return KING_BEAM_TERRAIN_CAP.get(); } static int royalDecreeCooldownTicks() { return ROYAL_DECREE_COOLDOWN_TICKS.get(); } + static double queenBlackHoleRadius() { return QUEEN_BLACK_HOLE_RADIUS.get(); } + static int queenBlackHoleActiveTicks() { return QUEEN_BLACK_HOLE_ACTIVE_TICKS.get(); } + static double queenBlackHolePullStrength() { return QUEEN_BLACK_HOLE_PULL_STRENGTH.get(); } + static double queenFinalTimeFieldRadius() { return QUEEN_FINAL_TIME_FIELD_RADIUS.get(); } + static double queenFinalTimeFieldRate() { return QUEEN_FINAL_TIME_FIELD_RATE.get(); } + static int queenFinalTimeFieldDurationTicks() { return QUEEN_FINAL_TIME_FIELD_DURATION_TICKS.get(); } + static int queenFinalTimeFieldCooldownTicks() { return QUEEN_FINAL_TIME_FIELD_COOLDOWN_TICKS.get(); } + static double kingFireballDamage() { return KING_FIREBALL_DAMAGE.get(); } + static double kingFireballRadius() { return KING_FIREBALL_RADIUS.get(); } + static int kingFireballCooldownTicks() { return KING_FIREBALL_COOLDOWN_TICKS.get(); } + static double kingIceballDamage() { return KING_ICEBALL_DAMAGE.get(); } + static double kingIceballRadius() { return KING_ICEBALL_RADIUS.get(); } + static int kingIceballCooldownTicks() { return KING_ICEBALL_COOLDOWN_TICKS.get(); } + static double kingIceSpikeDamage() { return KING_ICE_SPIKE_DAMAGE.get(); } + static int kingIceSpikeCooldownTicks() { return KING_ICE_SPIKE_COOLDOWN_TICKS.get(); } + static int kingElementalTerrainCap() { return KING_ELEMENTAL_TERRAIN_CAP.get(); } + static double royalBossSoundVolume() { return ROYAL_BOSS_SOUND_VOLUME.get(); } static int royalEggHatchChance() { return ROYAL_EGG_HATCH_CHANCE.get(); } static double royalBoltDamage() { return ROYAL_BOLT_DAMAGE.get(); } diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java index d9c1df83..36cb3404 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java @@ -221,6 +221,7 @@ public class AntarchyNeoforge { AntarchyNeoforgeSounds.KING_ROAR, AntarchyNeoforgeSounds.KING_WING_FLAP, AntarchyNeoforgeSounds.KING_FLY_LOOP, + AntarchyNeoforgeSounds.QUEEN_FLY_LOOP, AntarchyNeoforgeSounds.PRINCE_IDLE, AntarchyNeoforgeSounds.PRINCE_BITE, AntarchyNeoforgeSounds.PRINCE_SHOOT, @@ -436,6 +437,8 @@ public class AntarchyNeoforge { AntarchyObjects.setQueen(() -> AntarchyNeoforgeEntites.QUEEN.get()); AntarchyObjects.setManticore(() -> AntarchyNeoforgeEntites.MANTICORE.get()); AntarchyObjects.setRoyalBolt(() -> AntarchyNeoforgeEntites.ROYAL_BOLT.get()); + AntarchyObjects.setRoyalElementalProjectile(() -> AntarchyNeoforgeEntites.ROYAL_ELEMENTAL_PROJECTILE.get()); + AntarchyObjects.setRoyalIceSpike(() -> AntarchyNeoforgeEntites.ROYAL_ICE_SPIKE.get()); AntarchyObjects.setPrinceEgg(() -> AntarchyNeoforgeBlocks.PRINCE_EGG.get()); AntarchyObjects.setPrincessEgg(() -> AntarchyNeoforgeBlocks.PRINCESS_EGG.get()); AntarchyObjects.setRoyalEggBlockEntity(() -> AntarchyNeoforgeBlocks.ROYAL_EGG_BLOCK_ENTITY.get()); diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java index 727afd62..c7c19106 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java @@ -150,7 +150,7 @@ public final class AntarchyNeoForgeClient { event.registerEntityRenderer(AntarchyNeoforgeEntites.VORTEX_CHARGE_PROJECTILE.get(), ThrownItemRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.WIND_VORTEX.get(), WindVortexRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.TIME_DILATION_FIELD.get(), TimeDilationFieldRenderer::new); - event.registerEntityRenderer(AntarchyNeoforgeEntites.ROYAL_BLACK_HOLE.get(), net.minecraft.client.renderer.entity.NoopRenderer::new); + event.registerEntityRenderer(AntarchyNeoforgeEntites.ROYAL_BLACK_HOLE.get(), com.craisinlord.antarchy.content.client.renderer.RoyalBlackHoleRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.CRITTER_CAGE_PROJECTILE.get(), ThrownItemRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.WORM_HOOK_PROJECTILE.get(), ThrownItemRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.HUSH_PROJECTILE.get(), HushProjectileRenderer::new); @@ -176,6 +176,8 @@ public final class AntarchyNeoForgeClient { event.registerEntityRenderer(AntarchyNeoforgeEntites.KING.get(), com.craisinlord.antarchy.content.client.renderer.RoyalBossRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.QUEEN.get(), com.craisinlord.antarchy.content.client.renderer.RoyalBossRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.ROYAL_BOLT.get(), com.craisinlord.antarchy.content.client.renderer.RoyalBoltRenderer::new); + event.registerEntityRenderer(AntarchyNeoforgeEntites.ROYAL_ELEMENTAL_PROJECTILE.get(), com.craisinlord.antarchy.content.client.renderer.RoyalElementalProjectileRenderer::new); + event.registerEntityRenderer(AntarchyNeoforgeEntites.ROYAL_ICE_SPIKE.get(), com.craisinlord.antarchy.content.client.renderer.RoyalIceSpikeRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.JERRY.get(), context -> withParalyzedGeoLayer(new com.craisinlord.antarchy.content.client.renderer.JerryRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.JUMPY_BUG.get(), context -> withParalyzedGeoLayer(new com.craisinlord.antarchy.content.client.renderer.JumpyBugRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.SPIT_BUG.get(), context -> withParalyzedGeoLayer(new com.craisinlord.antarchy.content.client.renderer.SpitBugRenderer(context))); diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoForgeEvents.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoForgeEvents.java index 4bc728f2..cf1d4f20 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoForgeEvents.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoForgeEvents.java @@ -83,10 +83,24 @@ import net.neoforged.neoforge.fluids.FluidInteractionRegistry; import net.neoforged.neoforge.network.PacketDistributor; public final class AntarchyNeoForgeEvents { + private static final long SERVER_HANG_WARN_NANOS = 5_000_000_000L; + private static final long SERVER_IDLE_BUSY_WARN_NANOS = 30_000_000_000L; + private static final long SERVER_HANG_REPEAT_NANOS = 30_000_000_000L; + private static final double OVERHEAD_INVERSION_WARN_MS = 10.0D; + private static final long OVERHEAD_INVERSION_WARN_INTERVAL_TICKS = 100L; + private static volatile boolean serverHangWatchdogStarted; + private static volatile long serverTickStartNanos; + private static volatile long serverTickEndNanos; + private static volatile long serverHangLastDumpNanos; + private static volatile Thread serverTickThread; + private static long lastOverheadInversionWarnTick = Long.MIN_VALUE / 2L; + private AntarchyNeoForgeEvents() {} public static void register(IEventBus modEventBus) { modEventBus.addListener(AntarchyNeoForgeEvents::onCommonSetup); + NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::beginServerTickWatchdog); + NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::endServerTickWatchdog); NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::onMissileSquidDeath); NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::onPermanentPortalSacrifice); NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::onLivingBreathe); @@ -151,6 +165,79 @@ public final class AntarchyNeoForgeEvents { NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::onWandererTrades); } + static void beginServerTickWatchdog(ServerTickEvent.Pre event) { + ensureServerHangWatchdogStarted(); + serverTickThread = Thread.currentThread(); + serverTickStartNanos = System.nanoTime(); + } + + static void endServerTickWatchdog(ServerTickEvent.Post event) { + serverTickEndNanos = System.nanoTime(); + serverTickStartNanos = 0L; + } + + private static synchronized void ensureServerHangWatchdogStarted() { + if (serverHangWatchdogStarted) { + return; + } + serverHangWatchdogStarted = true; + Thread watchdog = new Thread(() -> { + while (true) { + try { + Thread.sleep(2_000L); + } catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); + return; + } + + long tickStart = serverTickStartNanos; + long tickEnd = serverTickEndNanos; + Thread tickThread = serverTickThread; + long now = System.nanoTime(); + if (tickThread == null || now - serverHangLastDumpNanos < SERVER_HANG_REPEAT_NANOS) { + continue; + } + + if (tickStart > 0L && now - tickStart >= SERVER_HANG_WARN_NANOS) { + antarchy$dumpServerThreadWatchdog( + "server thread appears hung", + (now - tickStart) / 1_000_000.0D, + tickThread + ); + serverHangLastDumpNanos = now; + continue; + } + + Thread.State state = tickThread.getState(); + boolean idleBusy = tickStart <= 0L + && tickEnd > 0L + && now - tickEnd >= SERVER_IDLE_BUSY_WARN_NANOS + && state != Thread.State.WAITING + && state != Thread.State.TIMED_WAITING; + if (idleBusy) { + antarchy$dumpServerThreadWatchdog( + "server thread busy outside active tick", + (now - tickEnd) / 1_000_000.0D, + tickThread + ); + serverHangLastDumpNanos = now; + } + } + }, "Antarchy Server Hang Watchdog"); + watchdog.setDaemon(true); + watchdog.start(); + } + + private static void antarchy$dumpServerThreadWatchdog(String message, double elapsedMs, Thread tickThread) { + Antarchy.LOGGER.error( + "[antarchy-watchdog] {} elapsedMs={} thread={} state={}", + message, elapsedMs, tickThread.getName(), tickThread.getState() + ); + for (StackTraceElement element : tickThread.getStackTrace()) { + Antarchy.LOGGER.error("[antarchy-watchdog] at {}", element); + } + } + static void onVillagerTrades(VillagerTradesEvent event) { if (event.getType() == VillagerProfession.FARMER) { event.getTrades().get(1).add(emeraldForItems(AntarchyObjects.CORN.get(), 20, 16, 2)); @@ -430,6 +517,9 @@ public final class AntarchyNeoForgeEvents { } private static final int ANTIMETAL_INVERTED_REFRESH_TICKS = 20; + private static final int ANTIMETAL_INVERTED_REFRESH_THRESHOLD_TICKS = 12; + private static final int ANTIMETAL_PLAYER_SCAN_INTERVAL_TICKS = 2; + private static final int ANTIMETAL_MOB_SCAN_INTERVAL_TICKS = 10; static void tickOverheadInversion(EntityTickEvent.Post event) { if (!(event.getEntity() instanceof LivingEntity livingEntity)) { @@ -441,17 +531,56 @@ public final class AntarchyNeoForgeEvents { if (livingEntity instanceof Player player && player.isSpectator()) { return; } - if (!isDirectlyBelowAntimetal(livingEntity)) { + + MobEffectInstance existingInverted = livingEntity.getEffect(AntarchyNeoforgeMisc.INVERTED); + long gameTime = livingEntity.level().getGameTime(); + if (!shouldScanOverheadAntimetal(livingEntity, existingInverted, gameTime)) { return; } - MobEffectInstance existingInverted = livingEntity.getEffect(AntarchyNeoforgeMisc.INVERTED); - if (existingInverted == null || existingInverted.getDuration() <= 5) { + long startNanos = System.nanoTime(); + boolean directlyBelowAntimetal = isDirectlyBelowAntimetal(livingEntity); + double elapsedMs = (System.nanoTime() - startNanos) / 1_000_000.0D; + if (elapsedMs >= OVERHEAD_INVERSION_WARN_MS + && gameTime - lastOverheadInversionWarnTick >= OVERHEAD_INVERSION_WARN_INTERVAL_TICKS) { + lastOverheadInversionWarnTick = gameTime; + Antarchy.LOGGER.warn( + "[antarchy-gravity] slow overhead antimetal scan targetType={} uuid={} pos=({}, {}, {}) dim={} elapsedMs={} inverted={} forced={} gameTime={}", + livingEntity.getType(), livingEntity.getUUID(), livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), + livingEntity.level().dimension().location(), elapsedMs, + com.craisinlord.antarchy.content.gravity.AntarchyGravityApi.isGravityInverted(livingEntity), + com.craisinlord.antarchy.content.gravity.AntarchyGravityApi.isGravityForced(livingEntity), + gameTime + ); + } + if (!directlyBelowAntimetal) { + return; + } + + if (existingInverted == null || existingInverted.getDuration() <= ANTIMETAL_INVERTED_REFRESH_THRESHOLD_TICKS) { + if (livingEntity instanceof Player || livingEntity.level().dimension().location().toString().equals("antarchy:thoraxis")) { + Antarchy.LOGGER.info( + "[antarchy-gravity] overhead antimetal applying inverted effect targetType={} uuid={} pos=({}, {}, {}) dim={} existingDuration={} gameTime={}", + livingEntity.getType(), livingEntity.getUUID(), livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), + livingEntity.level().dimension().location(), + existingInverted != null ? existingInverted.getDuration() : -1, + gameTime + ); + } livingEntity.addEffect(new MobEffectInstance(AntarchyNeoforgeMisc.INVERTED, ANTIMETAL_INVERTED_REFRESH_TICKS, 0, false, false, false)); spawnAntimetalInversionParticles(livingEntity); } } + private static boolean shouldScanOverheadAntimetal(LivingEntity entity, MobEffectInstance existingInverted, long gameTime) { + if (existingInverted != null && existingInverted.getDuration() <= ANTIMETAL_INVERTED_REFRESH_THRESHOLD_TICKS) { + return true; + } + int interval = entity instanceof Player ? ANTIMETAL_PLAYER_SCAN_INTERVAL_TICKS : ANTIMETAL_MOB_SCAN_INTERVAL_TICKS; + long phase = (long) entity.getUUID().hashCode() + gameTime; + return Math.floorMod(phase, interval) == 0L; + } + private static boolean isInOrBelowAntimetalScaffolding(LivingEntity entity) { AABB bounds = entity.getBoundingBox().deflate(1.0E-3D); int minX = net.minecraft.util.Mth.floor(bounds.minX); @@ -484,18 +613,16 @@ public final class AntarchyNeoForgeEvents { int minX = net.minecraft.util.Mth.floor(bounds.minX); int maxX = net.minecraft.util.Mth.floor(bounds.maxX); - int minY = net.minecraft.util.Mth.floor(bounds.minY); int maxY = net.minecraft.util.Mth.floor(bounds.maxY); int minZ = net.minecraft.util.Mth.floor(bounds.minZ); int maxZ = net.minecraft.util.Mth.floor(bounds.maxZ); + net.minecraft.core.BlockPos.MutableBlockPos crystalPos = new net.minecraft.core.BlockPos.MutableBlockPos(); for (int x = minX; x <= maxX; x++) { - for (int y = minY; y <= maxY; y++) { - for (int z = minZ; z <= maxZ; z++) { - net.minecraft.core.BlockPos crystalPos = new net.minecraft.core.BlockPos(x, y + 1, z); - if (entity.level().getBlockState(crystalPos).is(com.craisinlord.antarchy.content.AntarchyTags.Blocks.ANTIMETAL_INVERSION_BLOCKS)) { - return true; - } + for (int z = minZ; z <= maxZ; z++) { + crystalPos.set(x, maxY + 1, z); + if (entity.level().getBlockState(crystalPos).is(com.craisinlord.antarchy.content.AntarchyTags.Blocks.ANTIMETAL_INVERSION_BLOCKS)) { + return true; } } } @@ -1146,6 +1273,10 @@ public final class AntarchyNeoForgeEvents { event.getBuilder().addMix(Potions.AWKWARD, AntarchyNeoforgeItems.TITANIUM_NUGGET.get(), AntarchyNeoforgeMisc.GROWING); event.getBuilder().addMix(AntarchyNeoforgeMisc.GROWING, Items.GLOWSTONE_DUST, AntarchyNeoforgeMisc.STRONG_GROWING); event.getBuilder().addMix(AntarchyNeoforgeMisc.STRONG_GROWING, Items.GLOWSTONE_DUST, AntarchyNeoforgeMisc.EXTREME_GROWING); + event.getBuilder().addMix(Potions.AWKWARD, AntarchyNeoforgeItems.KING_SCALE.get(), AntarchyNeoforgeMisc.COMMAND); + event.getBuilder().addMix(AntarchyNeoforgeMisc.COMMAND, Items.REDSTONE, AntarchyNeoforgeMisc.LONG_COMMAND); + event.getBuilder().addMix(Potions.AWKWARD, AntarchyNeoforgeItems.QUEEN_SCALE.get(), AntarchyNeoforgeMisc.TIME_DILATION); + event.getBuilder().addMix(AntarchyNeoforgeMisc.TIME_DILATION, Items.REDSTONE, AntarchyNeoforgeMisc.LONG_TIME_DILATION); } diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java index 51ceef5f..39ecf4b2 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java @@ -425,6 +425,7 @@ public final class AntarchyNeoforgeEntites { () -> EntityType.Builder.of(ScorpionEntity::new, MobCategory.MONSTER) .sized(1.5F, 1.0F) .clientTrackingRange(8) + .fireImmune() .build("scorpion")); public static final DeferredHolder, EntityType> BASILISK = ENTITY_TYPES.register("basilisk", () -> EntityType.Builder.of(BasiliskEntity::new, MobCategory.MONSTER) @@ -435,6 +436,7 @@ public final class AntarchyNeoforgeEntites { () -> EntityType.Builder.of(EmperorScorpionEntity::new, MobCategory.MONSTER) .sized(6.0F, 3.0F) .clientTrackingRange(12) + .fireImmune() .build("emperor_scorpion")); public static final DeferredHolder, EntityType> LUCID_PEARL_PROJECTILE = ENTITY_TYPES.register("lucid_pearl_projectile", () -> EntityType.Builder.of(LucidEyeProjectileEntity::new, MobCategory.MISC) @@ -497,6 +499,7 @@ public final class AntarchyNeoforgeEntites { () -> EntityType.Builder.of(ManticoreEntity::new, MobCategory.MONSTER) .sized(1.95F, 2.0F) .clientTrackingRange(10) + .fireImmune() .build("manticore")); public static final DeferredHolder, EntityType> JERRY = ENTITY_TYPES.register("jerry", () -> EntityType.Builder.of(JerryEntity::new, MobCategory.MONSTER) @@ -541,6 +544,12 @@ public final class AntarchyNeoforgeEntites { public static final DeferredHolder, EntityType> ROYAL_BOLT = ENTITY_TYPES.register("royal_bolt", () -> EntityType.Builder.of(com.craisinlord.antarchy.content.entity.royal.RoyalBoltEntity::new, MobCategory.MISC) .sized(0.4F, 0.4F).clientTrackingRange(8).updateInterval(1).fireImmune().build("royal_bolt")); + public static final DeferredHolder, EntityType> ROYAL_ELEMENTAL_PROJECTILE = ENTITY_TYPES.register("royal_elemental_projectile", + () -> EntityType.Builder.of(com.craisinlord.antarchy.content.entity.royal.RoyalElementalProjectileEntity::new, MobCategory.MISC) + .sized(1.0F, 1.0F).clientTrackingRange(16).updateInterval(1).fireImmune().build("royal_elemental_projectile")); + public static final DeferredHolder, EntityType> ROYAL_ICE_SPIKE = ENTITY_TYPES.register("royal_ice_spike", + () -> EntityType.Builder.of(com.craisinlord.antarchy.content.entity.royal.RoyalIceSpikeEntity::new, MobCategory.MISC) + .sized(2.0F, 4.0F).clientTrackingRange(16).updateInterval(1).fireImmune().build("royal_ice_spike")); public static final DeferredHolder, EntityType> OURANWOOD_DEER = ENTITY_TYPES.register("ouranwood_deer", () -> EntityType.Builder.of(OuranwoodDeerEntity::new, MobCategory.CREATURE) .sized(1.125F, 1.75F) diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java index 86302673..cd05a4ec 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java @@ -7,6 +7,8 @@ import com.craisinlord.antarchy.content.effect.DreadMobEffect; import com.craisinlord.antarchy.content.effect.GoopedMobEffect; import com.craisinlord.antarchy.content.effect.GrowthMobEffect; import com.craisinlord.antarchy.content.effect.InvertedMobEffect; +import com.craisinlord.antarchy.content.effect.CommandedMobEffect; +import com.craisinlord.antarchy.content.effect.DilatedMobEffect; import com.craisinlord.antarchy.content.effect.ParalyzedMobEffect; import com.craisinlord.antarchy.content.effect.ShrinkMobEffect; import com.craisinlord.antarchy.content.effect.StinkyMobEffect; @@ -127,6 +129,8 @@ public final class AntarchyNeoforgeMisc { public static final DeferredHolder DREAD = MOB_EFFECTS.register("dread", DreadMobEffect::new); public static final DeferredHolder PARALYZED = MOB_EFFECTS.register("paralyzed", ParalyzedMobEffect::new); public static final DeferredHolder INVERTED = MOB_EFFECTS.register("inverted", InvertedMobEffect::new); + public static final DeferredHolder COMMANDED = MOB_EFFECTS.register("commanded", CommandedMobEffect::new); + public static final DeferredHolder DILATED = MOB_EFFECTS.register("dilated", DilatedMobEffect::new); public static final DeferredHolder STINKY = MOB_EFFECTS.register("stinky", StinkyMobEffect::new); public static final DeferredHolder GOOPED = MOB_EFFECTS.register("gooped", GoopedMobEffect::new); public static final DeferredHolder BLOODGLASS_WARD = MOB_EFFECTS.register("bloodglass_ward", com.craisinlord.antarchy.content.effect.BloodglassWardEffect::new); @@ -140,6 +144,14 @@ public final class AntarchyNeoforgeMisc { () -> new Potion(new MobEffectInstance(INVERTED, 600))); public static final DeferredHolder LONG_INVERSION = POTIONS.register("long_inversion", () -> new Potion("inversion", new MobEffectInstance(INVERTED, 2400))); + public static final DeferredHolder COMMAND = POTIONS.register("command", + () -> new Potion(new MobEffectInstance(COMMANDED, 600))); + public static final DeferredHolder LONG_COMMAND = POTIONS.register("long_command", + () -> new Potion("command", new MobEffectInstance(COMMANDED, 1200))); + public static final DeferredHolder TIME_DILATION = POTIONS.register("time_dilation", + () -> new Potion(new MobEffectInstance(DILATED, 300))); + public static final DeferredHolder LONG_TIME_DILATION = POTIONS.register("long_time_dilation", + () -> new Potion("time_dilation", new MobEffectInstance(DILATED, 600))); public static final DeferredHolder STINKY_POTION = POTIONS.register("stinky", () -> new Potion(new MobEffectInstance(STINKY, 1200))); public static final DeferredHolder LONG_STINKY = POTIONS.register("long_stinky", @@ -375,6 +387,9 @@ public final class AntarchyNeoforgeMisc { public static final DeferredHolder, DimensionalTearFeature> DIMENSIONAL_TEAR = FEATURES.register("dimensional_tear", () -> new DimensionalTearFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, ThoraxisIchorLakeFeature> THORAXIS_ICHOR_LAKE = FEATURES.register("thoraxis_ichor_lake", + () -> new ThoraxisIchorLakeFeature(NoneFeatureConfiguration.CODEC)); + // Biome sources public static final DeferredHolder, MapCodec> ELYTHIA_BIOME_SOURCE = BIOME_SOURCES.register("elythia_biome_source", () -> ElythiaBiomeSource.CODEC);