apple cow orchard

royal shrines
new advancements
portals deleting on relog if portal gun is gone
This commit is contained in:
craisinlord committed 2026-10-09 11:48:56 -05:00
1 parent db3cd02059
commit b0fa0fc5bd
47 files changed
+2236 -2

No files matched your search

@@ -0,0 +1,92 @@
package com.craisinlord.antarchy.content.advancement;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.Optional;
import java.util.function.BiConsumer;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.advancements.CriterionTrigger;
import net.minecraft.advancements.critereon.ContextAwarePredicate;
import net.minecraft.advancements.critereon.SimpleCriterionTrigger;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
public final class AntarchyAdvancementTriggers {
private static final EventInstance EMPTY = new EventInstance(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty());
private static final Codec<EventInstance> CODEC = RecordCodecBuilder.create(instance -> instance.group(
ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(EventInstance::player),
Codec.STRING.optionalFieldOf("direction").forGetter(EventInstance::direction),
Codec.STRING.optionalFieldOf("phase").forGetter(EventInstance::phase),
Codec.STRING.optionalFieldOf("variant").forGetter(EventInstance::variant)
).apply(instance, EventInstance::new));
private static final CrossedGravityThroat CROSSING = new CrossedGravityThroat();
private static final HordePhaseChanged HORDE_PHASE = new HordePhaseChanged();
private static final TamedGlimmer TAMED_GLIMMER = new TamedGlimmer();
private AntarchyAdvancementTriggers() {
}
public static void register() {
register((id, trigger) -> CriteriaTriggers.register(id.toString(), trigger));
}
/**
* Registers these triggers through the active loader's lifecycle hook.
* NeoForge calls this from its trigger-type RegisterEvent; Fabric can call
* the no-argument overload during its initializer.
*/
public static void register(BiConsumer<ResourceLocation, CriterionTrigger<?>> registrar) {
registrar.accept(ResourceLocation.fromNamespaceAndPath("antarchy", "crossed_gravity_throat"), CROSSING);
registrar.accept(ResourceLocation.fromNamespaceAndPath("antarchy", "horde_phase_changed"), HORDE_PHASE);
registrar.accept(ResourceLocation.fromNamespaceAndPath("antarchy", "tamed_glimmer"), TAMED_GLIMMER);
}
public static void crossedGravityThroat(ServerPlayer player, String direction) {
CROSSING.fire(player, direction);
}
public static void hordePhaseChanged(ServerPlayer player, String phase) {
HORDE_PHASE.fire(player, phase);
}
public static void tamedGlimmer(ServerPlayer player, String variant) {
TAMED_GLIMMER.fire(player, variant);
}
private record EventInstance(Optional<ContextAwarePredicate> player, Optional<String> direction, Optional<String> phase, Optional<String> variant)
implements SimpleCriterionTrigger.SimpleInstance {
}
private static final class CrossedGravityThroat extends SimpleCriterionTrigger<EventInstance> {
private void fire(ServerPlayer player, String direction) {
trigger(player, instance -> instance.direction().map(direction::equals).orElse(true));
}
@Override
public Codec<EventInstance> codec() {
return CODEC;
}
}
private static final class HordePhaseChanged extends SimpleCriterionTrigger<EventInstance> {
private void fire(ServerPlayer player, String phase) {
trigger(player, instance -> instance.phase().map(phase::equals).orElse(true));
}
@Override
public Codec<EventInstance> codec() {
return CODEC;
}
}
private static final class TamedGlimmer extends SimpleCriterionTrigger<EventInstance> {
private void fire(ServerPlayer player, String variant) {
trigger(player, instance -> instance.variant().map(variant::equals).orElse(true));
}
@Override
public Codec<EventInstance> codec() {
return CODEC;
}
}
}
@@ -3,6 +3,7 @@ package com.craisinlord.antarchy.content.entity.glimmer;
import com.craisinlord.antarchy.config.AntarchySettings;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.advancement.AntarchyAdvancements;
import com.craisinlord.antarchy.content.advancement.AntarchyAdvancementTriggers;
import com.craisinlord.antarchy.content.client.particle.GlimmerParticles;
import com.craisinlord.antarchy.content.entity.ConfiguredMobSpawnUtil;
import com.craisinlord.antarchy.Antarchy;
@@ -435,6 +436,7 @@ public class GlimmerEntity extends TamableAnimal implements GeoEntity {
if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
AntarchyAdvancements.award(serverPlayer, this.getVariant().tameAdvancementId());
AntarchyAdvancementTriggers.tamedGlimmer(serverPlayer, this.getVariant().name().toLowerCase(java.util.Locale.ROOT));
}
return InteractionResult.SUCCESS;
@@ -4,6 +4,7 @@ import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.AntarchyGameRules;
import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.AntarchyTags;
import com.craisinlord.antarchy.content.advancement.AntarchyAdvancementTriggers;
import com.craisinlord.antarchy.content.entity.JerryEntity;
import com.craisinlord.antarchy.content.network.HerculesBeetleImpactShakeSync;
import com.craisinlord.antarchy.content.network.HordeIntensitySync;
@@ -340,6 +341,11 @@ public final class CavarynHordeManager {
data.setDirty();
}
if (encounter.phase == Phase.HERCULES && herculesCleared(level, encounter, gameTime)) {
if (herculesDefeated(level, encounter)) {
for (ServerPlayer player : targetsFor(level, encounter)) {
AntarchyAdvancementTriggers.hordePhaseChanged(player, "completed");
}
}
encounter.phase = Phase.RECOVERY;
encounter.recoveryEndsAt = gameTime + RECOVERY_TICKS;
data.setDirty();
@@ -387,6 +393,19 @@ public final class CavarynHordeManager {
return true;
}
private static boolean herculesDefeated(ServerLevel level, Encounter encounter) {
if (encounter.herculesIds.isEmpty()) {
return false;
}
for (UUID uuid : encounter.herculesIds) {
Entity entity = level.getEntity(uuid);
if (entity instanceof LivingEntity living && living.isAlive() && !living.isRemoved()) {
return false;
}
}
return true;
}
private static void addAttention(ServerLevel level, ServerPlayer player, int amount) {
HordeData data = get(level);
PlayerAttention attention = data.players.computeIfAbsent(player.getUUID(), ignored -> new PlayerAttention());
@@ -429,6 +448,9 @@ public final class CavarynHordeManager {
}
data.encounters.add(encounter);
data.setDirty();
for (ServerPlayer player : targetsFor(level, encounter)) {
AntarchyAdvancementTriggers.hordePhaseChanged(player, "awakening");
}
}
private static List<TargetedSpawnChoice> buildTargetedSpawnList(ServerLevel level, ResourceLocation horde, List<ServerPlayer> targets, int players, boolean highAttention) {
@@ -2,6 +2,7 @@ package com.craisinlord.antarchy.content.item;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.advancement.AntarchyAdvancements;
import com.craisinlord.antarchy.content.advancement.AntarchyAdvancementTriggers;
import com.craisinlord.antarchy.content.client.particle.GlimmerParticles;
import com.craisinlord.antarchy.content.entity.glimmer.GlimmerCompanionSavedData;
import com.craisinlord.antarchy.content.entity.glimmer.GlimmerEntity;
@@ -99,6 +100,7 @@ public class GlimmerBottleItem extends Item {
if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
AntarchyAdvancements.award(serverPlayer, variant.tameAdvancementId());
AntarchyAdvancementTriggers.tamedGlimmer(serverPlayer, variant.name().toLowerCase(java.util.Locale.ROOT));
}
ItemStack result = ItemUtils.createFilledResult(stack, player, new ItemStack(Items.GLASS_BOTTLE));
@@ -1,5 +1,6 @@
package com.craisinlord.antarchy.content.portalgun;
import com.craisinlord.antarchy.content.item.PortalGunItem;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -12,7 +13,9 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.resources.ResourceLocation;
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.item.ItemStack;
import net.minecraft.world.level.saveddata.SavedData;
public final class PortalGunSavedData extends SavedData {
@@ -167,6 +170,50 @@ public final class PortalGunSavedData extends SavedData {
return clearMatching(server, record -> record.ownerId() != null && ownerIds.contains(record.ownerId()));
}
/** Clears portal pairs for guns that an owner no longer has in their player inventory. */
public static int clearMissingGuns(ServerPlayer player) {
PortalGunSavedData data = get(player.serverLevel().getServer());
if (data.pairs.isEmpty()) {
return 0;
}
Set<UUID> heldGunIds = new HashSet<>();
collectGunIds(player.getInventory().items, heldGunIds);
collectGunIds(player.getInventory().armor, heldGunIds);
collectGunIds(player.getInventory().offhand, heldGunIds);
UUID ownerId = player.getUUID();
Set<UUID> removedPortalIds = new HashSet<>();
Set<UUID> missingGunIds = new HashSet<>();
boolean removed = data.pairs.entrySet().removeIf(entry -> {
PairRecord record = entry.getValue();
if (!ownerId.equals(record.ownerId()) || heldGunIds.contains(entry.getKey().gunId())) {
return false;
}
missingGunIds.add(entry.getKey().gunId());
addPortalIds(removedPortalIds, record);
return true;
});
if (removed) {
data.setDirty();
}
for (UUID portalId : removedPortalIds) {
discardIfLoaded(player.serverLevel().getServer(), portalId);
}
return missingGunIds.size();
}
private static void collectGunIds(Iterable<ItemStack> stacks, Set<UUID> gunIds) {
for (ItemStack stack : stacks) {
if (stack.getItem() instanceof PortalGunItem) {
UUID gunId = PortalGunItem.getGunId(stack);
if (gunId != null) {
gunIds.add(gunId);
}
}
}
}
public static int clearEverything(MinecraftServer server) {
return clearMatching(server, record -> true);
}
@@ -2,6 +2,7 @@ package com.craisinlord.antarchy.content.worldgen.thoraxis;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.advancement.AntarchyAdvancementTriggers;
import com.craisinlord.antarchy.content.block.DreamSandBlock;
import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi;
import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection;
@@ -288,6 +289,7 @@ public final class ThoraxisUndersideManager {
tracking.lastFlipTick.put(player.getUUID(), now);
if (crossing.toUnderside) {
refreshInvertedEffect(player);
AntarchyAdvancementTriggers.crossedGravityThroat(player, "down");
} else {
player.removeEffect(AntarchyObjects.INVERTED_EFFECT.get());
tracking.lastUndersideExitTick.put(player.getUUID(), now);