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 546569ed..d6bac2a9 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 @@ -5,6 +5,7 @@ import com.craisinlord.antarchy.content.entity.portal.DimensionalTearEntity; import java.util.function.Supplier; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; +import net.minecraft.core.SectionPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.Mth; @@ -12,6 +13,7 @@ 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.level.chunk.LevelChunk; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; @@ -139,14 +141,21 @@ public class DimensionalTearMarkerBlockEntity extends BlockEntity { if (pos.getY() < minY || pos.getY() > maxY) { return false; } + BlockPos.MutableBlockPos checkPos = new BlockPos.MutableBlockPos(); + LevelChunk chunk = null; for (int dx = -2; dx <= 2; dx++) { - for (int dy = -2; dy <= 3; dy++) { - for (int dz = -4; dz <= 4; dz++) { - BlockPos checkPos = pos.offset(dx, dy, dz); - if (!level.isLoaded(checkPos)) { + for (int dz = -4; dz <= 4; dz++) { + int chunkX = SectionPos.blockToSectionCoord(pos.getX() + dx); + int chunkZ = SectionPos.blockToSectionCoord(pos.getZ() + dz); + if (chunk == null || chunk.getPos().x != chunkX || chunk.getPos().z != chunkZ) { + chunk = level.getChunkSource().getChunkNow(chunkX, chunkZ); + if (chunk == null) { return false; } - if (!level.getBlockState(checkPos).getCollisionShape(level, checkPos).isEmpty()) { + } + for (int dy = -2; dy <= 3; dy++) { + checkPos.set(pos.getX() + dx, pos.getY() + dy, pos.getZ() + dz); + if (!chunk.getBlockState(checkPos).getCollisionShape(level, checkPos).isEmpty()) { return false; } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/PortalGunPortalMasterBlockEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/PortalGunPortalMasterBlockEntity.java index 04fb2dd9..c3a229a4 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/PortalGunPortalMasterBlockEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/PortalGunPortalMasterBlockEntity.java @@ -275,7 +275,7 @@ public class PortalGunPortalMasterBlockEntity extends BlockEntity implements Por Vec3 center = placement.center(); restored.moveTo(center.x, center.y, center.z, placement.yaw(), 0.0F); level.addFreshEntity(restored); - PortalGunSavedData.setPortal(level, this.gunId, this.side, restored.getUUID()); + PortalGunSavedData.setPortal(level, this.gunId, this.ownerId, this.side, restored.getUUID()); return restored; } @@ -300,7 +300,7 @@ public class PortalGunPortalMasterBlockEntity extends BlockEntity implements Por Vec3 center = placement.center(); restored.moveTo(center.x, center.y, center.z, placement.yaw(), 0.0F); level.addFreshEntity(restored); - PortalGunSavedData.setPortal(level, record.gunId(), record.side(), restored.getUUID()); + PortalGunSavedData.setPortal(level, record.gunId(), record.ownerId(), record.side(), restored.getUUID()); PortalGunPortalEntity linked = PortalGunSavedData.findLoadedPortal(level, record.gunId(), record.side() == PortalGunPortalEntity.PortalSide.BLUE ? PortalGunPortalEntity.PortalSide.ORANGE : PortalGunPortalEntity.PortalSide.BLUE); if (linked != null && linked != restored && !linked.isRemoved()) { restored.linkTo(linked); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/command/PortalGunCommand.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/command/PortalGunCommand.java new file mode 100644 index 00000000..38112c5b --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/command/PortalGunCommand.java @@ -0,0 +1,49 @@ +package com.craisinlord.antarchy.content.command; + +import com.craisinlord.antarchy.content.portalgun.PortalGunSavedData; +import com.mojang.authlib.GameProfile; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.GameProfileArgument; +import net.minecraft.network.chat.Component; + +public final class PortalGunCommand { + private PortalGunCommand() { + } + + public static void register(CommandDispatcher dispatcher) { + dispatcher.register( + Commands.literal("portalgun") + .requires(source -> source.hasPermission(2)) + .then(Commands.literal("clear") + .then(Commands.literal("all") + .executes(PortalGunCommand::clearAll)) + .then(Commands.argument("owners", GameProfileArgument.gameProfile()) + .executes(PortalGunCommand::clearOwners))) + ); + } + + private static int clearAll(CommandContext context) { + int cleared = PortalGunSavedData.clearEverything(context.getSource().getServer()); + context.getSource().sendSuccess(() -> Component.translatable("commands.antarchy.portalgun.clear.all", cleared), true); + return cleared; + } + + private static int clearOwners(CommandContext context) throws CommandSyntaxException { + Collection profiles = GameProfileArgument.getGameProfiles(context, "owners"); + Set ownerIds = new HashSet<>(); + for (GameProfile profile : profiles) { + ownerIds.add(profile.getId()); + } + int cleared = PortalGunSavedData.clearOwnedBy(context.getSource().getServer(), ownerIds); + context.getSource().sendSuccess(() -> Component.translatable("commands.antarchy.portalgun.clear.owners", cleared, profiles.size()), true); + return cleared; + } +} 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 daa82d41..cfbaa08f 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 @@ -428,6 +428,7 @@ public final class CreativeTabContents { entry("portal_gun", "combat"), entry("portal_gun_atlas", "combat"), entry("portal_gun_p_body", "combat"), + entry("portal_gun_craisin", "combat"), entry("eye_of_the_storm", "combat"), entry("water_cannon", "combat"), entry("attitude_adjuster", "combat"), 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 0358f4a8..114e1a1b 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 @@ -128,6 +128,11 @@ public class BedBugEntity extends Animal implements GeoEntity { && Animal.checkAnimalSpawnRules(entityType, level, spawnReason, pos, random); } + @Override + public boolean removeWhenFarAway(double distanceToClosestPlayer) { + return true; + } + @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntArrivalScheduler.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntArrivalScheduler.java new file mode 100644 index 00000000..17d67704 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntArrivalScheduler.java @@ -0,0 +1,94 @@ +package com.craisinlord.antarchy.content.entity.ant; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import net.minecraft.core.BlockPos; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.level.TicketType; +import net.minecraft.world.level.ChunkPos; + +public final class AntArrivalScheduler { + private static final TicketType ARRIVAL_TICKET = TicketType.create("antarchy_ant_arrival", Comparator.comparingLong(ChunkPos::toLong), 300); + private static final int MAX_WAIT_TICKS = 200; + private static final Map PENDING = new LinkedHashMap<>(); + + private AntArrivalScheduler() { + } + + static void request(ServerPlayer player, ServerLevel destination, BlockPos center, int searchRadius, Runnable onLoaded) { + ChunkPos centerChunk = new ChunkPos(center); + int chunkRadius = (searchRadius >> 4) + 1; + destination.getChunkSource().addRegionTicket(ARRIVAL_TICKET, centerChunk, chunkRadius + 1, centerChunk); + PendingArrival arrival = new PendingArrival(player, destination, centerChunk, chunkRadius, onLoaded); + if (arrival.isLoaded()) { + PENDING.remove(player.getUUID()); + onLoaded.run(); + return; + } + PENDING.put(player.getUUID(), arrival); + } + + public static void tick(MinecraftServer server) { + if (PENDING.isEmpty()) { + return; + } + List ready = new ArrayList<>(); + Iterator iterator = PENDING.values().iterator(); + while (iterator.hasNext()) { + PendingArrival arrival = iterator.next(); + if (arrival.destination.getServer() != server || arrival.player.hasDisconnected() || arrival.player.isRemoved()) { + iterator.remove(); + continue; + } + arrival.waitedTicks++; + if (arrival.waitedTicks >= MAX_WAIT_TICKS || arrival.isLoaded()) { + iterator.remove(); + ready.add(arrival); + } + } + for (PendingArrival arrival : ready) { + arrival.onLoaded.run(); + } + } + + public static void clear() { + PENDING.clear(); + } + + private static final class PendingArrival { + private final ServerPlayer player; + private final ServerLevel destination; + private final ChunkPos center; + private final int chunkRadius; + private final Runnable onLoaded; + private int waitedTicks; + + private PendingArrival(ServerPlayer player, ServerLevel destination, ChunkPos center, int chunkRadius, Runnable onLoaded) { + this.player = player; + this.destination = destination; + this.center = center; + this.chunkRadius = chunkRadius; + this.onLoaded = onLoaded; + } + + private boolean isLoaded() { + ServerChunkCache chunks = this.destination.getChunkSource(); + for (int chunkX = this.center.x - this.chunkRadius; chunkX <= this.center.x + this.chunkRadius; chunkX++) { + for (int chunkZ = this.center.z - this.chunkRadius; chunkZ <= this.center.z + this.chunkRadius; chunkZ++) { + if (chunks.getChunkNow(chunkX, chunkZ) == null) { + return false; + } + } + } + return true; + } + } +} 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 9b852e6e..3b074c6f 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 @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import java.util.function.Consumer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -114,23 +115,13 @@ public final class AntTeleportHelper { return InteractionResult.PASS; } - Vec3 destinationPos = getDestinationPosition(player, destination); - if (destinationPos == null) { - return failArrival(player); - } - teleportPlayerWithCompanions(player, destination, destinationPos); - player.playSound(SoundEvents.ENDERMAN_TELEPORT, 1.0F, 1.0F); + arriveWithCompanions(player, destination); return InteractionResult.CONSUME; } public static InteractionResult teleportPlayerToReturnDestination(ServerPlayer player) { ServerLevel destination = resolveReturnDestinationLevel(player); - Vec3 destinationPos = getDestinationPosition(player, destination); - if (destinationPos == null) { - return failArrival(player); - } - teleportPlayerWithCompanions(player, destination, destinationPos); - player.playSound(SoundEvents.ENDERMAN_TELEPORT, 1.0F, 1.0F); + arriveWithCompanions(player, destination); return InteractionResult.CONSUME; } @@ -167,12 +158,7 @@ public final class AntTeleportHelper { return InteractionResult.PASS; } - Vec3 destinationPos = getDestinationPosition(player, destination); - if (destinationPos == null) { - return failArrival(player); - } - teleportPlayerWithCompanions(player, destination, destinationPos); - player.playSound(SoundEvents.ENDERMAN_TELEPORT, 1.0F, 1.0F); + arriveWithCompanions(player, destination); return InteractionResult.CONSUME; } @@ -246,6 +232,42 @@ public final class AntTeleportHelper { return InteractionResult.CONSUME; } + private static void arriveWithCompanions(ServerPlayer player, ServerLevel destination) { + prepareArrival(player, destination, destinationPos -> { + if (destinationPos == null) { + failArrival(player); + return; + } + teleportPlayerWithCompanions(player, destination, destinationPos); + player.playSound(SoundEvents.ENDERMAN_TELEPORT, 1.0F, 1.0F); + }); + } + + public static void prepareArrival(ServerPlayer player, ServerLevel destination, Consumer onArrival) { + BlockPos preferredPos = preferredArrivalPos(player, destination); + AntArrivalScheduler.request(player, destination, preferredPos, ARRIVAL_SEARCH_RADIUS, () -> { + int[] yRange = getDimensionYRange(destination); + if (yRange == null) { + onArrival.accept(findSafeArrivalPositionAnywhere(player, destination, preferredPos)); + return; + } + Vec3 safePos = findSafeArrivalPositionInYRange( + player, destination, preferredPos, yRange[0], yRange[1], ARRIVAL_SEARCH_RADIUS, ARRIVAL_VERTICAL_SEARCH); + if (safePos != null) { + onArrival.accept(safePos); + return; + } + AntArrivalScheduler.request(player, destination, preferredPos, EXPANDED_ARRIVAL_SEARCH_RADIUS, () -> { + Vec3 expandedSafePos = findSafeArrivalPositionInYRange( + player, destination, preferredPos, yRange[0], yRange[1], + EXPANDED_ARRIVAL_SEARCH_RADIUS, EXPANDED_ARRIVAL_VERTICAL_SEARCH); + onArrival.accept(expandedSafePos != null + ? expandedSafePos + : createEmergencyArrivalPlatform(destination, preferredPos, yRange[0], yRange[1])); + }); + }); + } + public static ServerLevel resolveReturnDestinationLevel(ServerPlayer player) { ResourceKey respawnDimension = player.getRespawnDimension(); ServerLevel destination = player.server.getLevel(respawnDimension); @@ -258,16 +280,15 @@ public final class AntTeleportHelper { @Nullable public static Vec3 getDestinationPosition(ServerPlayer player, ServerLevel destination) { - BlockPos respawnPos = player.getRespawnPosition(); - BlockPos preferredPos; - if (respawnPos != null && destination.dimension() == player.getRespawnDimension()) { - preferredPos = respawnPos; - } else { - preferredPos = destination.dimension() == Level.END ? ServerLevel.END_SPAWN_POINT : destination.getSharedSpawnPos(); - } + return findSafeArrivalPosition(player, destination, preferredArrivalPos(player, destination)); + } - Vec3 safeArrivalPos = findSafeArrivalPosition(player, destination, preferredPos); - return safeArrivalPos; + private static BlockPos preferredArrivalPos(ServerPlayer player, ServerLevel destination) { + BlockPos respawnPos = player.getRespawnPosition(); + if (respawnPos != null && destination.dimension() == player.getRespawnDimension()) { + return respawnPos; + } + return destination.dimension() == Level.END ? ServerLevel.END_SPAWN_POINT : destination.getSharedSpawnPos(); } @Nullable @@ -290,6 +311,11 @@ public final class AntTeleportHelper { return expandedSafePos != null ? expandedSafePos : createEmergencyArrivalPlatform(destination, preferredPos, yRange[0], yRange[1]); } + return findSafeArrivalPositionAnywhere(player, destination, preferredPos); + } + + @Nullable + private static Vec3 findSafeArrivalPositionAnywhere(ServerPlayer player, ServerLevel destination, BlockPos preferredPos) { Set candidates = new LinkedHashSet<>(); BlockPos adjustedPreferredPos = player.adjustSpawnLocation(destination, preferredPos); addArrivalCandidate(candidates, preferredPos); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/RainbowAntEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/RainbowAntEntity.java index 8c368c31..0f9fd7a6 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/RainbowAntEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/RainbowAntEntity.java @@ -122,13 +122,14 @@ public class RainbowAntEntity extends BaseAntEntity implements GeoEntity { if (this.isInInfinityDimension(serverPlayer.serverLevel())) { ServerLevel returnLevel = this.resolveReturnDestinationLevel(serverPlayer); - Vec3 returnPos = this.getDestinationPosition(returnLevel, serverPlayer); - if (returnPos == null) { - serverPlayer.displayClientMessage(Component.translatable("message.antarchy.teleport_arrival_failed"), true); - return InteractionResult.CONSUME; - } - serverPlayer.teleportTo(returnLevel, returnPos.x, returnPos.y, returnPos.z, serverPlayer.getYRot(), serverPlayer.getXRot()); - serverPlayer.playSound(SoundEvents.ENDERMAN_TELEPORT, 1.0F, 1.0F); + AntTeleportHelper.prepareArrival(serverPlayer, returnLevel, returnPos -> { + if (returnPos == null) { + serverPlayer.displayClientMessage(Component.translatable("message.antarchy.teleport_arrival_failed"), true); + return; + } + serverPlayer.teleportTo(returnLevel, returnPos.x, returnPos.y, returnPos.z, serverPlayer.getYRot(), serverPlayer.getXRot()); + serverPlayer.playSound(SoundEvents.ENDERMAN_TELEPORT, 1.0F, 1.0F); + }); return InteractionResult.CONSUME; } 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 301882cd..1f483df6 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 @@ -118,6 +118,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private static final double BEAM_MUZZLE_CENTER_Y = 11.5D; private static final double BEAM_MUZZLE_SIDE_Y = 10.25D; private static final double BEAM_MUZZLE_LATERAL = 2.625D; + private static final int HEAVY_BLOCK_CHECK_INTERVAL_TICKS = 4; protected static final double FLYING_MIN_HOVER = 2.5D; protected static final double FLYING_PREFERRED_HOVER = 6.0D; @@ -464,6 +465,36 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } } + private final java.util.Map, CachedFluidCheck> cachedFluidChecks = new java.util.HashMap<>(2); + + public boolean shouldRunHeavyBlockChecks() { + return (this.tickCount + this.getId()) % HEAVY_BLOCK_CHECK_INTERVAL_TICKS == 0; + } + + @Override + protected void tryCheckInsideBlocks() { + if (this.shouldRunHeavyBlockChecks()) { + super.tryCheckInsideBlocks(); + } + } + + @Override + public boolean updateFluidHeightAndDoFluidPushing(net.minecraft.tags.TagKey fluidTag, double motionScale) { + CachedFluidCheck cached = this.cachedFluidChecks.get(fluidTag); + if (cached == null || this.shouldRunHeavyBlockChecks()) { + boolean inFluid = super.updateFluidHeightAndDoFluidPushing(fluidTag, motionScale); + this.cachedFluidChecks.put(fluidTag, new CachedFluidCheck(inFluid, this.getFluidHeight(fluidTag))); + return inFluid; + } + if (cached.height() > 0.0D) { + this.fluidHeight.put(fluidTag, cached.height()); + } + return cached.inFluid(); + } + + private record CachedFluidCheck(boolean inFluid, double height) { + } + @Override public void travel(Vec3 travelVector) { if (this.isRoyalFlying() && this.isEffectiveAi()) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/PortalGunItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/PortalGunItem.java index 78901055..7ed30953 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/PortalGunItem.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/PortalGunItem.java @@ -150,6 +150,24 @@ public class PortalGunItem extends Item implements GeoItem { player.serverLevel().playSound(null, player.getX(), player.getY(), player.getZ(), PortalGunPortalEntity.sound("portal_fizzle"), SoundSource.PLAYERS, 0.6F, 1.0F); } + private boolean damageGun(ServerLevel level, Player player, ItemStack stack, boolean offhand) { + UUID gunId = getGunId(stack); + EquipmentSlot slot = offhand ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND; + boolean[] broke = {false}; + stack.hurtAndBreak(1, level, player instanceof ServerPlayer serverPlayer ? serverPlayer : null, item -> { + broke[0] = true; + player.onEquippedItemBroken(item, slot); + PortalGunSavedData.clearAllPortals(level, gunId); + }); + return broke[0]; + } + + public static void clearPortalsOf(ServerLevel level, ItemStack stack) { + if (stack.getItem() instanceof PortalGunItem) { + PortalGunSavedData.clearAllPortals(level, getGunId(stack)); + } + } + public void fireMobPortal(ServerLevel level, LivingEntity shooter, ItemStack stack, PortalGunPortalEntity.PortalSide side) { this.ensureGunId(stack, shooter.getUUID()); String firePath = side == PortalGunPortalEntity.PortalSide.BLUE ? "portal_gun_fire_blue" : "portal_gun_fire_orange"; @@ -165,7 +183,9 @@ public class PortalGunItem extends Item implements GeoItem { } this.triggerFireAnimation(level, player, stack); this.ensureGunId(stack, player.getUUID()); - stack.hurtAndBreak(1, player, offhand ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND); + if (this.damageGun(level, player, stack, offhand)) { + return true; + } player.awardStat(Stats.ITEM_USED.get(this)); player.getCooldowns().addCooldown(this, 6); String firePath = side == PortalGunPortalEntity.PortalSide.BLUE ? "portal_gun_fire_blue" : "portal_gun_fire_orange"; @@ -211,7 +231,7 @@ public class PortalGunItem extends Item implements GeoItem { return; } level.addFreshEntity(portal); - PortalGunSavedData.setPortal(level, gunId, side, portal.getUUID()); + PortalGunSavedData.setPortal(level, gunId, portalOwnerId, side, portal.getUUID()); PortalGunPortalEntity other = this.findCounterpart(level, gunId, side); if (other != null) { portal.linkTo(other); @@ -267,7 +287,9 @@ public class PortalGunItem extends Item implements GeoItem { this.setMoonSide(stack, side); this.setLastSide(stack, side); this.triggerFireAnimation(level, player, stack); - stack.hurtAndBreak(1, player, offhand ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND); + if (this.damageGun(level, player, stack, offhand)) { + return true; + } player.awardStat(Stats.ITEM_USED.get(this)); player.getCooldowns().addCooldown(this, 6); level.playSound(null, player.getX(), player.getY(), player.getZ(), PortalGunPortalEntity.sound(side == PortalGunPortalEntity.PortalSide.BLUE ? "portal_gun_fire_blue" : "portal_gun_fire_orange"), SoundSource.PLAYERS, 0.65F, side == PortalGunPortalEntity.PortalSide.BLUE ? 1.15F : 0.88F); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RainbowSugarItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RainbowSugarItem.java index ed2d0d8d..9811f8c0 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RainbowSugarItem.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RainbowSugarItem.java @@ -33,13 +33,14 @@ public class RainbowSugarItem extends Item { if (!level.isClientSide && livingEntity instanceof ServerPlayer serverPlayer && isInInfinityDimension(serverPlayer.serverLevel())) { ServerLevel returnLevel = AntTeleportHelper.resolveReturnDestinationLevel(serverPlayer); - var returnPos = AntTeleportHelper.getDestinationPosition(serverPlayer, returnLevel); - if (returnPos == null) { - serverPlayer.displayClientMessage(Component.translatable("message.antarchy.teleport_arrival_failed"), true); - } else { - serverPlayer.teleportTo(returnLevel, returnPos.x, returnPos.y, returnPos.z, serverPlayer.getYRot(), serverPlayer.getXRot()); - serverPlayer.playSound(SoundEvents.ENDERMAN_TELEPORT, 1.0F, 1.0F); - } + AntTeleportHelper.prepareArrival(serverPlayer, returnLevel, returnPos -> { + if (returnPos == null) { + serverPlayer.displayClientMessage(Component.translatable("message.antarchy.teleport_arrival_failed"), true); + } else { + serverPlayer.teleportTo(returnLevel, returnPos.x, returnPos.y, returnPos.z, serverPlayer.getYRot(), serverPlayer.getXRot()); + serverPlayer.playSound(SoundEvents.ENDERMAN_TELEPORT, 1.0F, 1.0F); + } + }); } return result; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunSavedData.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunSavedData.java index e48dbaf6..b94135f8 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunSavedData.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunSavedData.java @@ -22,6 +22,7 @@ public final class PortalGunSavedData extends SavedData { private static final String GUN_KEY = "Gun"; private static final String BLUE_KEY = "Blue"; private static final String ORANGE_KEY = "Orange"; + private static final String OWNER_KEY = "Owner"; private final Map pairs = new HashMap<>(); public static PortalGunSavedData create() { @@ -38,7 +39,8 @@ public final class PortalGunSavedData extends SavedData { } UUID blue = entryTag.hasUUID(BLUE_KEY) ? entryTag.getUUID(BLUE_KEY) : null; UUID orange = entryTag.hasUUID(ORANGE_KEY) ? entryTag.getUUID(ORANGE_KEY) : null; - data.pairs.put(new PairKey(dimension, entryTag.getUUID(GUN_KEY)), new PairRecord(blue, orange)); + UUID owner = entryTag.hasUUID(OWNER_KEY) ? entryTag.getUUID(OWNER_KEY) : null; + data.pairs.put(new PairKey(dimension, entryTag.getUUID(GUN_KEY)), new PairRecord(blue, orange, owner)); } return data; } @@ -56,6 +58,9 @@ public final class PortalGunSavedData extends SavedData { if (entry.getValue().orangePortalId() != null) { entryTag.putUUID(ORANGE_KEY, entry.getValue().orangePortalId()); } + if (entry.getValue().ownerId() != null) { + entryTag.putUUID(OWNER_KEY, entry.getValue().ownerId()); + } entries.add(entryTag); } tag.put(ENTRIES_KEY, entries); @@ -84,16 +89,17 @@ public final class PortalGunSavedData extends SavedData { return portalId != null && getPortalId(level.getServer(), gunId, side, level.dimension().location()).map(portalId::equals).orElse(false); } - public static void setPortal(ServerLevel level, UUID gunId, PortalGunPortalEntity.PortalSide side, UUID portalId) { + public static void setPortal(ServerLevel level, UUID gunId, UUID ownerId, PortalGunPortalEntity.PortalSide side, UUID portalId) { if (gunId == null) { return; } PortalGunSavedData data = get(level.getServer()); PairKey key = new PairKey(level.dimension().location(), gunId); - PairRecord current = data.pairs.getOrDefault(key, new PairRecord(null, null)); + PairRecord current = data.pairs.getOrDefault(key, new PairRecord(null, null, null)); + UUID owner = ownerId != null ? ownerId : current.ownerId(); data.put(key, side == PortalGunPortalEntity.PortalSide.BLUE - ? new PairRecord(portalId, current.orangePortalId()) - : new PairRecord(current.bluePortalId(), portalId)); + ? new PairRecord(portalId, current.orangePortalId(), owner) + : new PairRecord(current.bluePortalId(), portalId, owner)); } public static void clearPortal(MinecraftServer server, UUID gunId, PortalGunPortalEntity.PortalSide side, UUID portalId, ResourceLocation dimension) { @@ -108,7 +114,7 @@ public final class PortalGunSavedData extends SavedData { } UUID blue = side == PortalGunPortalEntity.PortalSide.BLUE && portalId.equals(current.bluePortalId()) ? null : current.bluePortalId(); UUID orange = side == PortalGunPortalEntity.PortalSide.ORANGE && portalId.equals(current.orangePortalId()) ? null : current.orangePortalId(); - data.put(key, new PairRecord(blue, orange)); + data.put(key, new PairRecord(blue, orange, current.ownerId())); } public static void clearAllPortals(ServerLevel level, UUID gunId) { @@ -149,14 +155,41 @@ public final class PortalGunSavedData extends SavedData { } portalIds.add(removed); data.put(entry.getKey(), side == PortalGunPortalEntity.PortalSide.BLUE - ? new PairRecord(null, pair.orangePortalId()) - : new PairRecord(pair.bluePortalId(), null)); + ? new PairRecord(null, pair.orangePortalId(), pair.ownerId()) + : new PairRecord(pair.bluePortalId(), null, pair.ownerId())); } for (UUID portalId : portalIds) { discardIfLoaded(server, portalId); } } + public static int clearOwnedBy(MinecraftServer server, Set ownerIds) { + return clearMatching(server, record -> record.ownerId() != null && ownerIds.contains(record.ownerId())); + } + + public static int clearEverything(MinecraftServer server) { + return clearMatching(server, record -> true); + } + + private static int clearMatching(MinecraftServer server, java.util.function.Predicate filter) { + PortalGunSavedData data = get(server); + Set portalIds = new HashSet<>(); + boolean removed = data.pairs.values().removeIf(record -> { + if (!filter.test(record)) { + return false; + } + addPortalIds(portalIds, record); + return true; + }); + if (removed) { + data.setDirty(); + } + for (UUID portalId : portalIds) { + discardIfLoaded(server, portalId); + } + return portalIds.size(); + } + public static PortalGunPortalEntity findLoadedPortal(ServerLevel level, UUID gunId, PortalGunPortalEntity.PortalSide side) { Optional portalId = getPortalId(level.getServer(), gunId, side, level.dimension().location()); if (portalId.isEmpty()) { @@ -196,6 +229,6 @@ public final class PortalGunSavedData extends SavedData { private record PairKey(ResourceLocation dimension, UUID gunId) { } - private record PairRecord(UUID bluePortalId, UUID orangePortalId) { + private record PairRecord(UUID bluePortalId, UUID orangePortalId, UUID ownerId) { } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunVariant.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunVariant.java index 2870d594..40d3c5ba 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunVariant.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portalgun/PortalGunVariant.java @@ -6,7 +6,8 @@ import net.minecraft.resources.ResourceLocation; public enum PortalGunVariant { DEFAULT("", 0x40A0FF, 0xFF961E, "blue", "orange"), ATLAS("atlas", 0x53A6D0, 0x6A2BE0, "blue", "purple"), - P_BODY("p_body", 0xF9D660, 0xC0282A, "yellow", "red"); + P_BODY("p_body", 0xF9D660, 0xC0282A, "yellow", "red"), + CRAISIN("craisin", 0x6A2BE0, 0xF9D660, "purple", "gold"); private final String key; private final int blueColor; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/recipe/PortalGunVariantRecipe.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/recipe/PortalGunVariantRecipe.java new file mode 100644 index 00000000..de0f3cda --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/recipe/PortalGunVariantRecipe.java @@ -0,0 +1,54 @@ +package com.craisinlord.antarchy.content.recipe; + +import com.craisinlord.antarchy.content.item.PortalGunItem; +import com.mojang.serialization.MapCodec; +import net.minecraft.core.HolderLookup; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingInput; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.item.crafting.ShapelessRecipe; + +public class PortalGunVariantRecipe extends ShapelessRecipe { + public static final RecipeSerializer SERIALIZER = new Serializer(); + + public PortalGunVariantRecipe(ShapelessRecipe recipe) { + super(recipe.getGroup(), recipe.category(), recipe.getResultItem(null), recipe.getIngredients()); + } + + @Override + public ItemStack assemble(CraftingInput input, HolderLookup.Provider registries) { + ItemStack result = super.assemble(input, registries); + for (int slot = 0; slot < input.size(); slot++) { + ItemStack ingredient = input.getItem(slot); + if (ingredient.getItem() instanceof PortalGunItem) { + result.applyComponents(ingredient.getComponentsPatch()); + break; + } + } + return result; + } + + @Override + public RecipeSerializer getSerializer() { + return SERIALIZER; + } + + private static final class Serializer implements RecipeSerializer { + private static final MapCodec CODEC = + RecipeSerializer.SHAPELESS_RECIPE.codec().xmap(PortalGunVariantRecipe::new, recipe -> recipe); + private static final StreamCodec STREAM_CODEC = + RecipeSerializer.SHAPELESS_RECIPE.streamCodec().map(PortalGunVariantRecipe::new, recipe -> recipe); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/BedBugSurfaceClusterFeature.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/BedBugSurfaceClusterFeature.java index e65207c8..4ba89150 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/BedBugSurfaceClusterFeature.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/BedBugSurfaceClusterFeature.java @@ -24,7 +24,7 @@ public final class BedBugSurfaceClusterFeature extends Feature codec) { super(codec); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/PortalGunItemEntityRemovalMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/PortalGunItemEntityRemovalMixin.java new file mode 100644 index 00000000..5a84852f --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/PortalGunItemEntityRemovalMixin.java @@ -0,0 +1,24 @@ +package com.craisinlord.antarchy.mixins; + +import com.craisinlord.antarchy.content.item.PortalGunItem; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.item.ItemEntity; +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(Entity.class) +public abstract class PortalGunItemEntityRemovalMixin { + @Inject(method = "setRemoved", at = @At("HEAD")) + private void antarchy$clearPortalsOfDestroyedGun(Entity.RemovalReason reason, CallbackInfo ci) { + if ((Object) this instanceof ItemEntity itemEntity + && (reason == Entity.RemovalReason.KILLED || reason == Entity.RemovalReason.DISCARDED) + && !itemEntity.isRemoved() + && itemEntity.level() instanceof ServerLevel level + && itemEntity.getItem().getItem() instanceof PortalGunItem) { + PortalGunItem.clearPortalsOf(level, itemEntity.getItem()); + } + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/RoyalBossMoveScanMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/RoyalBossMoveScanMixin.java new file mode 100644 index 00000000..f5cde2c8 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/RoyalBossMoveScanMixin.java @@ -0,0 +1,26 @@ +package com.craisinlord.antarchy.mixins; + +import com.craisinlord.antarchy.content.entity.royal.RoyalBossEntity; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import java.util.stream.Stream; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(Entity.class) +public abstract class RoyalBossMoveScanMixin { + @WrapOperation( + method = "move", + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;getBlockStatesIfLoaded(Lnet/minecraft/world/phys/AABB;)Ljava/util/stream/Stream;") + ) + private Stream antarchy$throttleRoyalFireScan(Level level, AABB bounds, Operation> original) { + if ((Object) this instanceof RoyalBossEntity royal && !royal.shouldRunHeavyBlockChecks()) { + return Stream.empty(); + } + return original.call(level, bounds); + } +} 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 03768287..4786b371 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 @@ -10,6 +10,8 @@ "PortalGunEntityInWallMixin", "PortalGunPlayerMovePacketMixin", "PortalGunProjectileHitMixin", + "PortalGunItemEntityRemovalMixin", + "RoyalBossMoveScanMixin", "ServerGamePacketListenerTeleportAccessor", "PortalGunZombieMixin", "FallingBlockEntityAccessor", 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 630557e6..cc51a746 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 @@ -673,6 +673,7 @@ "item.antarchy.portal_gun": "Portal Gun", "item.antarchy.portal_gun_atlas": "Atlas Portal Gun", "item.antarchy.portal_gun_p_body": "P-body Portal Gun", + "item.antarchy.portal_gun_craisin": "Craisin Portal Gun", "item.antarchy.diamond_minecart": "The Diamond Minecart", "item.antarchy.cogwheel_pet": "Cogwheel Pet", "item.antarchy.fire_dragon_pet": "Fire Dragon Pet", @@ -841,11 +842,14 @@ "tooltip.antarchy.gravity_gun.blacklist": "Does not affect blacklisted blocks or entities.", "tooltip.antarchy.portal_gun.primary": "Attack: fire a %s portal.", "tooltip.antarchy.portal_gun.secondary": "Use: fire a %s portal.", + "commands.antarchy.portalgun.clear.all": "Cleared %s portal gun portals", + "commands.antarchy.portalgun.clear.owners": "Cleared %s portal gun portals owned by %s players", "tooltip.antarchy.portal_gun.color.blue": "blue", "tooltip.antarchy.portal_gun.color.orange": "orange", "tooltip.antarchy.portal_gun.color.purple": "purple", "tooltip.antarchy.portal_gun.color.yellow": "yellow", "tooltip.antarchy.portal_gun.color.red": "red", + "tooltip.antarchy.portal_gun.color.gold": "gold", "tooltip.antarchy.portal_gun.reset": "Sneak + use: fizzle your active portals.", "tooltip.antarchy.antimetal_inversion": "Inverts entites directly below it", "tooltip.antarchy.diamond_minecart.forward": "Will be implemented later.", diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/item/portal_gun_craisin_gui.json b/common-1.21.1/src/main/resources/assets/antarchy/models/item/portal_gun_craisin_gui.json new file mode 100644 index 00000000..bb2d31f2 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/item/portal_gun_craisin_gui.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:item/generated", + "gui_light": "front", + "textures": { + "layer0": "antarchy:item/portal_gun/portal_gun_craisin_item" + } +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/portal_gun/portal_craisin_blue_vortex.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/portal_gun/portal_craisin_blue_vortex.png new file mode 100644 index 00000000..02ed58c2 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/portal_gun/portal_craisin_blue_vortex.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/portal_gun/portal_craisin_orange_vortex.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/portal_gun/portal_craisin_orange_vortex.png new file mode 100644 index 00000000..5f968f76 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/portal_gun/portal_craisin_orange_vortex.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/portal_gun_craisin_crosshair.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/portal_gun_craisin_crosshair.png new file mode 100644 index 00000000..a30b6fee Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/portal_gun_craisin_crosshair.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/item/portal_gun/portal_gun_craisin_item.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/portal_gun/portal_gun_craisin_item.png new file mode 100644 index 00000000..41a5c982 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/portal_gun/portal_gun_craisin_item.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/models/item/portal_gun_craisin.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/models/item/portal_gun_craisin.png new file mode 100644 index 00000000..e85406a0 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/models/item/portal_gun_craisin.png differ diff --git a/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_atlas.json b/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_atlas.json index 4b7e9e7d..454fccaa 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_atlas.json +++ b/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_atlas.json @@ -1,5 +1,5 @@ { - "type": "minecraft:crafting_shapeless", + "type": "antarchy:portal_gun_variant", "category": "equipment", "ingredients": [ { diff --git a/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_craisin.json b/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_craisin.json new file mode 100644 index 00000000..b84f8f28 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_craisin.json @@ -0,0 +1,19 @@ +{ + "type": "antarchy:portal_gun_variant", + "category": "equipment", + "ingredients": [ + { + "item": "antarchy:portal_gun" + }, + { + "item": "minecraft:purple_dye" + }, + { + "item": "minecraft:gold_ingot" + } + ], + "result": { + "id": "antarchy:portal_gun_craisin", + "count": 1 + } +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_p_body.json b/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_p_body.json index 873e1e67..f243d0e7 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_p_body.json +++ b/common-1.21.1/src/main/resources/data/antarchy/recipe/portal_gun_p_body.json @@ -1,5 +1,5 @@ { - "type": "minecraft:crafting_shapeless", + "type": "antarchy:portal_gun_variant", "category": "equipment", "ingredients": [ { diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricEvents.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricEvents.java index 5ee5d194..a9d2f39d 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricEvents.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricEvents.java @@ -77,6 +77,7 @@ public final class AntarchyFabricEvents { public static void register() { ServerLifecycleEvents.SERVER_STOPPING.register(server -> PortalGunProjectileEntity.releaseAllProjectileTickets()); ServerLifecycleEvents.SERVER_STOPPING.register(com.craisinlord.antarchy.content.portalgun.PortalGunResetManager::clear); + ServerLifecycleEvents.SERVER_STOPPING.register(server -> com.craisinlord.antarchy.content.entity.ant.AntArrivalScheduler.clear()); ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { ChronosphereManager.refresh(handler.player); TimeDilationManager.resyncPersistentEffects(handler.player); @@ -102,6 +103,7 @@ public final class AntarchyFabricEvents { QueenLocateCommand.register(dispatcher); TimeDilationCommand.register(dispatcher); RoyalCommand.register(dispatcher); + com.craisinlord.antarchy.content.command.PortalGunCommand.register(dispatcher); }); DispenserBlock.registerBehavior(AntarchyFabricItems.SQUIDZOOKA.get(), new SquidzookaDispenseBehavior()); @@ -221,6 +223,7 @@ public final class AntarchyFabricEvents { } } TimeDilationManager.tickServer(server); + com.craisinlord.antarchy.content.entity.ant.AntArrivalScheduler.tick(server); invertedPlayers.retainAll(activeThisTick); }); } diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/SeparateLargeItemModels.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/SeparateLargeItemModels.java index b50944f5..506e2835 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/SeparateLargeItemModels.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/SeparateLargeItemModels.java @@ -22,6 +22,7 @@ public final class SeparateLargeItemModels { entry(AntarchyFabricItems.PORTAL_GUN.get(), "portal_gun_gui"), entry(AntarchyFabricItems.PORTAL_GUN_ATLAS.get(), "portal_gun_atlas_gui"), entry(AntarchyFabricItems.PORTAL_GUN_P_BODY.get(), "portal_gun_p_body_gui"), + entry(AntarchyFabricItems.PORTAL_GUN_CRAISIN.get(), "portal_gun_craisin_gui"), entry(AntarchyFabricItems.ROYAL_ASSAILANT_BATTLEAXE.get(), "royal_assailant_battleaxe_gui"), entry(AntarchyFabricItems.ROYAL_ASSAILANT_STAFF.get(), "royal_assailant_staff_gui"), entry(AntarchyFabricItems.ROYAL_GUARDIAN_SWORD.get(), "royal_guardian_sword_gui"), diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java index 0ff44e48..f01e7b5c 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java @@ -1584,6 +1584,16 @@ public final class AntarchyFabricItems { AntarchyFabricBlocks.PORTAL_GUN_PORTAL_BASE, com.craisinlord.antarchy.content.portalgun.PortalGunVariant.P_BODY )); + public static final DeferredItem PORTAL_GUN_CRAISIN = ITEMS.register("portal_gun_craisin", + () -> new PortalGunItem( + new Item.Properties().stacksTo(1).durability(256).rarity(Rarity.RARE), + AntarchyFabricEntities.PORTAL_GUN_PORTAL, + AntarchyFabricEntities.PORTAL_GUN_BLACK_HOLE, + AntarchyFabricEntities.PORTAL_GUN_PROJECTILE, + AntarchyFabricBlocks.PORTAL_GUN_PORTAL_MASTER, + AntarchyFabricBlocks.PORTAL_GUN_PORTAL_BASE, + com.craisinlord.antarchy.content.portalgun.PortalGunVariant.CRAISIN + )); public static final DeferredItem EYE_OF_THE_STORM = ITEMS.register("eye_of_the_storm", () -> new EyeOfTheStormItem(new Item.Properties().stacksTo(1).durability(384).rarity(Rarity.EPIC))); 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 8551965c..0c5ade2d 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 @@ -266,6 +266,8 @@ public final class AntarchyFabricMisc { public static final DeferredHolder, net.minecraft.world.item.crafting.RecipeSerializer> AMERICANIZE_SERIALIZER = RECIPE_SERIALIZERS.register("americanize", () -> AmericanizeRecipe.SERIALIZER); + public static final DeferredHolder, net.minecraft.world.item.crafting.RecipeSerializer> PORTAL_GUN_VARIANT_SERIALIZER = + RECIPE_SERIALIZERS.register("portal_gun_variant", () -> com.craisinlord.antarchy.content.recipe.PortalGunVariantRecipe.SERIALIZER); public static final DeferredHolder ULTIMATE_ARMOR_MATERIAL = ARMOR_MATERIALS.register("ultimate", diff --git a/fabric-1.21.1/src/main/resources/assets/antarchy/models/item/portal_gun_craisin.json b/fabric-1.21.1/src/main/resources/assets/antarchy/models/item/portal_gun_craisin.json new file mode 100644 index 00000000..a3b81466 --- /dev/null +++ b/fabric-1.21.1/src/main/resources/assets/antarchy/models/item/portal_gun_craisin.json @@ -0,0 +1,3 @@ +{ + "parent": "antarchy:item/portal_gun_held_geo" +} diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforgeEvents.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforgeEvents.java index 3df0b55f..8543ae1c 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforgeEvents.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforgeEvents.java @@ -29,6 +29,7 @@ public final class AntarchyNeoforgeEvents { QueenLocateCommand.register(event.getDispatcher()); TimeDilationCommand.register(event.getDispatcher()); RoyalCommand.register(event.getDispatcher()); + com.craisinlord.antarchy.content.command.PortalGunCommand.register(event.getDispatcher()); } @SubscribeEvent 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 e57c4806..4979b459 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 @@ -633,6 +633,7 @@ public final class AntarchyNeoForgeClient { registerGeoItemExtension(event, AntarchyNeoforgeItems.PORTAL_GUN.get(), HumanoidModel.ArmPose.CROSSBOW_HOLD); registerGeoItemExtension(event, AntarchyNeoforgeItems.PORTAL_GUN_ATLAS.get(), HumanoidModel.ArmPose.CROSSBOW_HOLD); registerGeoItemExtension(event, AntarchyNeoforgeItems.PORTAL_GUN_P_BODY.get(), HumanoidModel.ArmPose.CROSSBOW_HOLD); + registerGeoItemExtension(event, AntarchyNeoforgeItems.PORTAL_GUN_CRAISIN.get(), HumanoidModel.ArmPose.CROSSBOW_HOLD); registerGeoItemExtension(event, AntarchyNeoforgeItems.SQUIDZOOKA.get(), HumanoidModel.ArmPose.CROSSBOW_HOLD); registerGeoItemExtension(event, AntarchyNeoforgeItems.RPO_LAUNCHER.get(), HumanoidModel.ArmPose.CROSSBOW_HOLD); registerGeoItemExtension(event, AntarchyNeoforgeItems.WATER_CANNON.get(), HumanoidModel.ArmPose.CROSSBOW_HOLD); 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 1a839e04..e37c1368 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 @@ -140,6 +140,7 @@ public final class AntarchyNeoForgeEvents { NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::handleBloodglassWardExpired); NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::tickBloodglassRecharge); NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::tickTimeDilation); + NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::tickAntArrivals); NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::handleBloodglassPlayerDeath); NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::handleBloodglassRespawn); NeoForge.EVENT_BUS.addListener(AntarchyNeoForgeEvents::handleBloodglassLogin); @@ -260,6 +261,10 @@ public final class AntarchyNeoForgeEvents { TimeDilationManager.tickServer(event.getServer()); } + static void tickAntArrivals(ServerTickEvent.Post event) { + com.craisinlord.antarchy.content.entity.ant.AntArrivalScheduler.tick(event.getServer()); + } + private static int badOmenLevel(Player player) { MobEffectInstance effect = player.getEffect(MobEffects.BAD_OMEN); return effect != null ? effect.getAmplifier() + 1 : 0; diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java index 707f6417..46cf2b49 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java @@ -1062,6 +1062,16 @@ public final class AntarchyNeoforgeItems { AntarchyNeoforgeBlocks.PORTAL_GUN_PORTAL_BASE, com.craisinlord.antarchy.content.portalgun.PortalGunVariant.P_BODY )); + public static final DeferredItem PORTAL_GUN_CRAISIN = ITEMS.register("portal_gun_craisin", + () -> new PortalGunItem( + new Item.Properties().stacksTo(1).durability(256).rarity(Rarity.RARE), + AntarchyNeoforgeEntites.PORTAL_GUN_PORTAL, + AntarchyNeoforgeEntites.PORTAL_GUN_BLACK_HOLE, + AntarchyNeoforgeEntites.PORTAL_GUN_PROJECTILE, + AntarchyNeoforgeBlocks.PORTAL_GUN_PORTAL_MASTER, + AntarchyNeoforgeBlocks.PORTAL_GUN_PORTAL_BASE, + com.craisinlord.antarchy.content.portalgun.PortalGunVariant.CRAISIN + )); public static final DeferredItem EYE_OF_THE_STORM = ITEMS.register("eye_of_the_storm", () -> new EyeOfTheStormItem(new Item.Properties().stacksTo(1).durability(384).rarity(Rarity.EPIC))); public static final DeferredItem SQUIDZOOKA = ITEMS.register("squidzooka", 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 b5e64d5e..0fa7fcdb 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 @@ -149,6 +149,8 @@ public final class AntarchyNeoforgeMisc { .build()); public static final DeferredHolder, net.minecraft.world.item.crafting.RecipeSerializer> AMERICANIZE_SERIALIZER = RECIPE_SERIALIZERS.register("americanize", () -> AmericanizeRecipe.SERIALIZER); + public static final DeferredHolder, net.minecraft.world.item.crafting.RecipeSerializer> PORTAL_GUN_VARIANT_SERIALIZER = + RECIPE_SERIALIZERS.register("portal_gun_variant", () -> com.craisinlord.antarchy.content.recipe.PortalGunVariantRecipe.SERIALIZER); public static final DeferredHolder DOUBLE_DAMAGE_CHANCE = ATTRIBUTES.register( "double_damage_chance", diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/PortalGunServerEvents.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/PortalGunServerEvents.java index 8e9fe421..5d63c255 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/PortalGunServerEvents.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/PortalGunServerEvents.java @@ -13,5 +13,6 @@ public final class PortalGunServerEvents { @SubscribeEvent public static void onServerStopping(ServerStoppingEvent event) { com.craisinlord.antarchy.content.portalgun.PortalGunResetManager.clear(event.getServer()); + com.craisinlord.antarchy.content.entity.ant.AntArrivalScheduler.clear(); } } diff --git a/neoforge-1.21.1/src/main/resources/assets/antarchy/models/item/portal_gun_craisin.json b/neoforge-1.21.1/src/main/resources/assets/antarchy/models/item/portal_gun_craisin.json new file mode 100644 index 00000000..1ebd8459 --- /dev/null +++ b/neoforge-1.21.1/src/main/resources/assets/antarchy/models/item/portal_gun_craisin.json @@ -0,0 +1,18 @@ +{ + "loader": "neoforge:separate_transforms", + "gui_light": "front", + "base": { + "parent": "antarchy:item/portal_gun_held_geo" + }, + "perspectives": { + "gui": { + "parent": "antarchy:item/portal_gun_craisin_gui" + }, + "ground": { + "parent": "antarchy:item/portal_gun_craisin_gui" + }, + "fixed": { + "parent": "antarchy:item/portal_gun_craisin_gui" + } + } +}