diff --git a/.gradle-codex/caches/9.4.1/fileContent/fileContent.lock b/.gradle-codex/caches/9.4.1/fileContent/fileContent.lock deleted file mode 100644 index 5179b480..00000000 Binary files a/.gradle-codex/caches/9.4.1/fileContent/fileContent.lock and /dev/null differ diff --git a/.gradle-codex/caches/9.4.1/fileHashes/fileHashes.bin b/.gradle-codex/caches/9.4.1/fileHashes/fileHashes.bin deleted file mode 100644 index 21dae325..00000000 Binary files a/.gradle-codex/caches/9.4.1/fileHashes/fileHashes.bin and /dev/null differ diff --git a/.gradle-codex/caches/9.4.1/fileHashes/fileHashes.lock b/.gradle-codex/caches/9.4.1/fileHashes/fileHashes.lock deleted file mode 100644 index 7feee322..00000000 Binary files a/.gradle-codex/caches/9.4.1/fileHashes/fileHashes.lock and /dev/null differ diff --git a/.gradle-codex/caches/9.4.1/fileHashes/resourceHashesCache.bin b/.gradle-codex/caches/9.4.1/fileHashes/resourceHashesCache.bin deleted file mode 100644 index 22063717..00000000 Binary files a/.gradle-codex/caches/9.4.1/fileHashes/resourceHashesCache.bin and /dev/null differ diff --git a/.gradle-codex/caches/9.4.1/gc.properties b/.gradle-codex/caches/9.4.1/gc.properties deleted file mode 100644 index e69de29b..00000000 diff --git a/.gradle-codex/caches/9.4.1/transforms/.internal/gc.properties b/.gradle-codex/caches/9.4.1/transforms/.internal/gc.properties deleted file mode 100644 index e69de29b..00000000 diff --git a/.gradle-codex/wrapper/dists/gradle-9.4.1-bin/arn2x92ynaizyzdaamcbpbhtj/gradle-9.4.1-bin.zip.lck b/.gradle-codex/wrapper/dists/gradle-9.4.1-bin/arn2x92ynaizyzdaamcbpbhtj/gradle-9.4.1-bin.zip.lck deleted file mode 100644 index e69de29b..00000000 diff --git a/.gradle-codex/wrapper/dists/gradle-9.4.1-bin/arn2x92ynaizyzdaamcbpbhtj/gradle-9.4.1-bin.zip.part b/.gradle-codex/wrapper/dists/gradle-9.4.1-bin/arn2x92ynaizyzdaamcbpbhtj/gradle-9.4.1-bin.zip.part deleted file mode 100644 index e69de29b..00000000 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 8a985ec1..35274045 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 @@ -17,6 +17,7 @@ public final class AntarchySettings { private static boolean rainbowAntRequiresReagent = true; private static boolean rainbowAntRightClickDimension = true; private static boolean termiteRequiresReagent = false; + private static boolean termitesFearBlockLight = true; private static boolean termiteRightClickDimension = true; private static boolean antsStealFromChests = true; private static boolean duplicatorTreeEnabled = true; @@ -261,14 +262,14 @@ public final class AntarchySettings { private static int royalGuardianBoundaryProjectileCap = 64; private static double royalBoltDamage = 6.0D; private static int royalEggHatchChance = 3; - private static double princeHealth = 120.0D; + private static double princeHealth = 360.0D; private static double princeAttackDamage = 14.0D; private static double princeMovementSpeed = 0.28D; private static double princeFlyingSpeed = 0.9D; private static double princeArmor = 10.0D; private static double princeKnockbackResistance = 0.6D; private static double princeFollowRange = 48.0D; - private static double princessHealth = 110.0D; + private static double princessHealth = 330.0D; private static double princessAttackDamage = 10.0D; private static double princessMovementSpeed = 0.28D; private static double princessFlyingSpeed = 0.95D; @@ -557,10 +558,10 @@ public final class AntarchySettings { private static int bloodCrystalLeggingsDefense = 6; private static int bloodCrystalBootsDefense = 3; private static double bloodCrystalArmorToughness = 2.0D; - private static int bloodCrystalHelmetDurability = 77; - private static int bloodCrystalChestplateDurability = 112; - private static int bloodCrystalLeggingsDurability = 105; - private static int bloodCrystalBootsDurability = 91; + private static int bloodCrystalHelmetDurability = 92; + private static int bloodCrystalChestplateDurability = 134; + private static int bloodCrystalLeggingsDurability = 126; + private static int bloodCrystalBootsDurability = 109; private static double toreterrorHealth = 450.0D; private static double toreterrorJumpAttackDamage = 14.0D; private static double toreterrorJumpAttackKnockback = 2.5D; @@ -705,6 +706,10 @@ public final class AntarchySettings { return termiteRequiresReagent; } + public static boolean termitesFearBlockLight() { + return termitesFearBlockLight; + } + public static boolean antsStealFromChests() { return antsStealFromChests; } @@ -1328,6 +1333,10 @@ public final class AntarchySettings { termiteRequiresReagent = value; } + public static void setTermitesFearBlockLight(boolean value) { + termitesFearBlockLight = value; + } + public static void setAntsStealFromChests(boolean value) { antsStealFromChests = value; } 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 817c76e2..c4c16d7f 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 @@ -206,16 +206,6 @@ public final class AntarchyObjects { public static Supplier> GLIMMER_VARIANT_COMPONENT = (Supplier>) UNBOUND; @SuppressWarnings("unchecked") - public static Supplier> FLOPPY_DISK_COMPONENT = - (Supplier>) UNBOUND; - @SuppressWarnings("unchecked") - public static Supplier FLOPPY_DISK = (Supplier) UNBOUND; - @SuppressWarnings("unchecked") - public static Supplier COMPUTER = (Supplier) UNBOUND; - @SuppressWarnings("unchecked") - public static Supplier> COMPUTER_BLOCK_ENTITY = - (Supplier>) UNBOUND; - @SuppressWarnings("unchecked") public static Supplier> DORRIE_INVENTORY_MENU = (Supplier>) UNBOUND; @SuppressWarnings("unchecked") public static Supplier> ROYAL_JUDGMENT_MENU = (Supplier>) UNBOUND; @@ -403,6 +393,8 @@ public final class AntarchyObjects { @SuppressWarnings("unchecked") public static Supplier STINKY_GAS = (Supplier) UNBOUND; @SuppressWarnings("unchecked") + public static Supplier BUG_SPRAY_PARTICLE = (Supplier) UNBOUND; + @SuppressWarnings("unchecked") public static Supplier NIGHTMARE_FIRE_FLAME = (Supplier) UNBOUND; @SuppressWarnings("unchecked") public static Supplier STINKY_FLY = (Supplier) UNBOUND; @@ -650,6 +642,10 @@ public final class AntarchyObjects { OCTOPUS_BOMB = supplier; } + public static void setBugSprayParticle(Supplier supplier) { + BUG_SPRAY_PARTICLE = supplier; + } + public static void setTentacle(Supplier> supplier) { TENTACLE = supplier; } @@ -912,22 +908,6 @@ public final class AntarchyObjects { GLIMMER_VARIANT_COMPONENT = supplier; } - public static void setFloppyDiskComponent(Supplier> supplier) { - FLOPPY_DISK_COMPONENT = supplier; - } - - public static void setFloppyDisk(Supplier supplier) { - FLOPPY_DISK = supplier; - } - - public static void setComputer(Supplier supplier) { - COMPUTER = supplier; - } - - public static void setComputerBlockEntity(Supplier> supplier) { - COMPUTER_BLOCK_ENTITY = supplier; - } - public static void setDorrieInventoryMenu(Supplier> supplier) { DORRIE_INVENTORY_MENU = 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 2a90521c..3dae94cd 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 @@ -221,6 +221,9 @@ public final class AntarchySoundEvents { public static Supplier KING_DECREE = (Supplier) UNBOUND; public static Supplier KING_SUCCESS = (Supplier) UNBOUND; public static Supplier KING_JUDGEMENT = (Supplier) UNBOUND; + public static Supplier HOVERBOARD_MOUNT = (Supplier) UNBOUND; + public static Supplier HOVERBOARD_DISMOUNT = (Supplier) UNBOUND; + public static Supplier HOVERBOARD_IDLE = (Supplier) UNBOUND; private AntarchySoundEvents() { } @@ -656,4 +659,10 @@ public final class AntarchySoundEvents { DIMENSIONAL_TEAR_CREATURE_LEAVES = dimensionalTearCreatureLeaves; DIMENSIONAL_TEAR_CLOSE = dimensionalTearClose; } + + public static void bindHoverboardSounds(Supplier mount, Supplier dismount, Supplier idle) { + HOVERBOARD_MOUNT = mount; + HOVERBOARD_DISMOUNT = dismount; + HOVERBOARD_IDLE = idle; + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailAddress.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailAddress.java deleted file mode 100644 index 26d6a820..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailAddress.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import java.util.Locale; -import java.util.Objects; -import java.util.regex.Pattern; - -public record AntmailAddress(String username) { - public static final String DOMAIN = "antmail.com"; - private static final Pattern USERNAME = Pattern.compile("[a-z0-9_]{3,16}"); - - public AntmailAddress { - username = normalizeUsername(username); - } - - public static AntmailAddress parse(String value) { - if (value == null) { - throw new IllegalArgumentException("Address is null"); - } - String normalized = value.trim().toLowerCase(Locale.ROOT); - String suffix = "@" + DOMAIN; - if (!normalized.endsWith(suffix)) { - throw new IllegalArgumentException("Invalid Antmail domain"); - } - return new AntmailAddress(normalized.substring(0, normalized.length() - suffix.length())); - } - - public static AntmailAddress ofUsername(String username) { - return new AntmailAddress(username); - } - - public String fullAddress() { - return username + "@" + DOMAIN; - } - - public static String normalizeUsername(String value) { - if (value == null) { - throw new IllegalArgumentException("Username is null"); - } - String normalized = value.trim().toLowerCase(Locale.ROOT); - if (!USERNAME.matcher(normalized).matches()) { - throw new IllegalArgumentException("Username must match [a-z0-9_]{3,16}"); - } - return normalized; - } - - public static boolean isValidUsername(String value) { - if (value == null) { - return false; - } - return USERNAME.matcher(value.trim().toLowerCase(Locale.ROOT)).matches(); - } - - public static boolean isValidAddress(String value) { - try { - parse(value); - return true; - } catch (IllegalArgumentException exception) { - return false; - } - } - - @Override - public String toString() { - return fullAddress(); - } - - @Override - public boolean equals(Object object) { - return object instanceof AntmailAddress other && username.equals(other.username); - } - - @Override - public int hashCode() { - return Objects.hash(username); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailAttachment.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailAttachment.java deleted file mode 100644 index e6efc7a9..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailAttachment.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import net.minecraft.nbt.CompoundTag; - -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Objects; - -public sealed interface AntmailAttachment permits AntmailAttachment.TextFile, AntmailAttachment.PaintImage { - String TYPE_TAG = "Type"; - String NAME_TAG = "Name"; - - String fileName(); - - int byteSize(); - - CompoundTag toTag(); - - static AntmailAttachment fromTag(CompoundTag tag) { - return switch (tag.getString(TYPE_TAG)) { - case "text_file" -> TextFile.fromTag(tag); - case "paint_image" -> PaintImage.fromTag(tag); - default -> throw new IllegalArgumentException("Unknown Antmail attachment type"); - }; - } - - record TextFile(String fileName, String contents) implements AntmailAttachment { - public TextFile { - fileName = validateFileName(fileName); - contents = Objects.requireNonNull(contents, "contents"); - if (contents.length() > AntmailValidation.MAX_TEXT_ATTACHMENT_CHARACTERS) { - throw new IllegalArgumentException("Text attachment is too large"); - } - } - - @Override - public int byteSize() { - return contents.getBytes(StandardCharsets.UTF_8).length; - } - - @Override - public CompoundTag toTag() { - CompoundTag tag = new CompoundTag(); - tag.putString(TYPE_TAG, "text_file"); - tag.putString(NAME_TAG, fileName); - tag.putString("Contents", contents); - return tag; - } - - static TextFile fromTag(CompoundTag tag) { - return new TextFile(tag.getString(NAME_TAG), tag.getString("Contents")); - } - } - - record PaintImage(String fileName, int width, int height, byte[] pixels) implements AntmailAttachment { - public PaintImage { - fileName = validateFileName(fileName); - if (width != AntmailValidation.MAX_PAINT_WIDTH || height != AntmailValidation.MAX_PAINT_HEIGHT) { - throw new IllegalArgumentException("Invalid Paint image dimensions"); - } - if (pixels == null || pixels.length != width * height) { - throw new IllegalArgumentException("Paint pixel data does not match dimensions"); - } - for (byte pixel : pixels) { - if (pixel != 0 && pixel != 1) throw new IllegalArgumentException("Paint pixel data must be monochrome"); - } - pixels = Arrays.copyOf(pixels, pixels.length); - } - - @Override - public byte[] pixels() { - return Arrays.copyOf(pixels, pixels.length); - } - - @Override - public int byteSize() { - return pixels.length; - } - - @Override - public CompoundTag toTag() { - CompoundTag tag = new CompoundTag(); - tag.putString(TYPE_TAG, "paint_image"); - tag.putString(NAME_TAG, fileName); - tag.putInt("Width", width); - tag.putInt("Height", height); - tag.putByteArray("Pixels", pixels); - return tag; - } - - static PaintImage fromTag(CompoundTag tag) { - return new PaintImage(tag.getString(NAME_TAG), tag.getInt("Width"), tag.getInt("Height"), tag.getByteArray("Pixels")); - } - } - - private static String validateFileName(String value) { - if (value == null || value.isBlank() || value.length() > AntmailValidation.MAX_FILE_NAME_LENGTH || value.contains("/") || value.contains("\\")) { - throw new IllegalArgumentException("Invalid attachment filename"); - } - return value; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailAttachmentFiles.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailAttachmentFiles.java deleted file mode 100644 index 05e2a268..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailAttachmentFiles.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import com.craisinlord.antarchy.content.computer.ComputerFileSystem; -import com.craisinlord.antarchy.content.computer.paint.AntPaintCanvas; -import com.craisinlord.antarchy.content.computer.paint.AntPaintFile; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -public final class AntmailAttachmentFiles { - private AntmailAttachmentFiles() { - } - - public static Optional fromComputerFile(ComputerFileSystem.ComputerFile file) { - if (file == null || file.type() != ComputerFileSystem.ComputerFile.Type.TEXT) return Optional.empty(); - try { - return Optional.of(new AntmailAttachment.TextFile(filename(file.path()), file.contents())); - } catch (IllegalArgumentException exception) { - return Optional.empty(); - } - } - - public static AntmailAttachment.TextFile fromTextFile(String path, String contents) { - return new AntmailAttachment.TextFile(filename(path), contents); - } - - public static AntmailAttachment.PaintImage fromPaintFile(AntPaintFile file) { - if (file == null) throw new IllegalArgumentException("Paint file cannot be null"); - AntPaintCanvas canvas = file.canvas(); - if (canvas == null || canvas.copyPixels().length != AntPaintCanvas.PIXEL_COUNT) { - throw new IllegalArgumentException("Invalid AntPaint canvas"); - } - boolean[] source = canvas.copyPixels(); - byte[] pixels = new byte[source.length]; - for (int index = 0; index < source.length; index++) pixels[index] = source[index] ? (byte) 1 : (byte) 0; - return new AntmailAttachment.PaintImage(file.filename(), AntPaintCanvas.WIDTH, AntPaintCanvas.HEIGHT, pixels); - } - - public static AntPaintFile toPaintFile(AntmailAttachment.PaintImage image, String fileId, long createdTime, long modifiedTime) { - if (image == null) throw new IllegalArgumentException("Paint attachment cannot be null"); - if (image.width() != AntPaintCanvas.WIDTH || image.height() != AntPaintCanvas.HEIGHT) { - throw new IllegalArgumentException("Unsupported AntPaint canvas size"); - } - byte[] source = image.pixels(); - boolean[] pixels = new boolean[source.length]; - for (int index = 0; index < source.length; index++) { - if (source[index] != 0 && source[index] != 1) throw new IllegalArgumentException("Invalid AntPaint pixel"); - pixels[index] = source[index] == 1; - } - AntPaintCanvas canvas = new AntPaintCanvas(); - for (int index = 0; index < pixels.length; index++) { - if (pixels[index]) canvas.set(index % AntPaintCanvas.WIDTH, index / AntPaintCanvas.WIDTH, true); - } - return new AntPaintFile(fileId, image.fileName(), canvas, createdTime, modifiedTime); - } - - public static ComputerFileSystem.ComputerFile toComputerTextFile(String path, AntmailAttachment.TextFile file) { - if (file == null) throw new IllegalArgumentException("Text attachment cannot be null"); - String normalized = ComputerFileSystem.normalize(path); - if (normalized.isEmpty() || normalized.equals(ComputerFileSystem.ROOT)) throw new IllegalArgumentException("Invalid text file path"); - return ComputerFileSystem.ComputerFile.text(normalized, file.contents()); - } - - public static List selectableTextFiles(Collection files) { - if (files == null) return List.of(); - List result = new ArrayList<>(); - for (ComputerFileSystem.ComputerFile file : files) { - if (fromComputerFile(file).isPresent()) result.add(file); - } - return List.copyOf(result); - } - - public static List selectablePaintFiles(Collection files) { - if (files == null) return List.of(); - List result = new ArrayList<>(); - for (AntPaintFile file : files) { - try { - result.add(fromPaintFile(file)); - } catch (IllegalArgumentException ignored) { - } - } - return List.copyOf(result); - } - - private static String filename(String path) { - String normalized = ComputerFileSystem.normalize(path); - if (normalized.isEmpty() || normalized.equals(ComputerFileSystem.ROOT)) throw new IllegalArgumentException("Invalid file path"); - int separator = normalized.lastIndexOf('/'); - return normalized.substring(separator + 1); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailDebug.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailDebug.java deleted file mode 100644 index cceeac19..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailDebug.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import com.craisinlord.antarchy.Antarchy; - -/** Opt-in diagnostics for AntMail networking and mailbox state transitions. */ -public final class AntmailDebug { - private static final String PROPERTY = "antarchy.antmail.debug"; - - private AntmailDebug() { - } - - public static void log(String message) { - if (Boolean.getBoolean(PROPERTY)) Antarchy.LOGGER.info("[AntMail debug] {}", message); - } - - public static void error(String message, Throwable throwable) { - Antarchy.LOGGER.error("[AntMail] {}", message, throwable); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailDeliveryResult.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailDeliveryResult.java deleted file mode 100644 index 7cba81c4..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailDeliveryResult.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import java.util.UUID; - -public record AntmailDeliveryResult(Status status, UUID messageId, AntmailAddress sender, AntmailAddress recipient, String detail) { - public enum Status { - DELIVERED, - QUEUED, - INVALID_ADDRESS, - ADDRESS_NOT_FOUND, - MAILBOX_FULL, - MESSAGE_INVALID, - DUPLICATE, - FAILED - } - - public static AntmailDeliveryResult delivered(AntmailMessage message) { - return new AntmailDeliveryResult(Status.DELIVERED, message.id(), message.sender(), message.recipient(), ""); - } - - public static AntmailDeliveryResult queued(AntmailMessage message) { - return new AntmailDeliveryResult(Status.QUEUED, message.id(), message.sender(), message.recipient(), ""); - } - - public static AntmailDeliveryResult failed(Status status, AntmailMessage message, String detail) { - return new AntmailDeliveryResult(status, message == null ? null : message.id(), message == null ? null : message.sender(), message == null ? null : message.recipient(), detail); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailDraft.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailDraft.java deleted file mode 100644 index 4fe498ab..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailDraft.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -public record AntmailDraft(UUID id, AntmailAddress sender, AntmailAddress recipient, String subject, String body, List attachments) { - public AntmailDraft { - id = id == null ? UUID.randomUUID() : id; - subject = subject == null ? "" : subject; - body = body == null ? "" : body; - attachments = attachments == null ? List.of() : List.copyOf(attachments); - if (subject.length() > AntmailValidation.MAX_SUBJECT_LENGTH || body.length() > AntmailValidation.MAX_BODY_LENGTH || attachments.size() > AntmailValidation.MAX_ATTACHMENTS) { - throw new IllegalArgumentException("Draft exceeds Antmail limits"); - } - } - - public CompoundTag toTag() { - CompoundTag tag = new CompoundTag(); - tag.putString("Id", id.toString()); - if (sender != null) tag.putString("From", sender.fullAddress()); - if (recipient != null) tag.putString("To", recipient.fullAddress()); - tag.putString("Subject", subject); - tag.putString("Body", body); - ListTag attachmentTags = new ListTag(); - for (AntmailAttachment attachment : attachments) attachmentTags.add(attachment.toTag()); - tag.put("Attachments", attachmentTags); - return tag; - } - - public static AntmailDraft fromTag(CompoundTag tag) { - List attachments = new ArrayList<>(); - ListTag attachmentTags = tag.getList("Attachments", 10); - for (int index = 0; index < attachmentTags.size(); index++) attachments.add(AntmailAttachment.fromTag(attachmentTags.getCompound(index))); - UUID id = UUID.fromString(tag.getString("Id")); - AntmailAddress sender = tag.contains("From") ? AntmailAddress.parse(tag.getString("From")) : null; - AntmailAddress recipient = tag.contains("To") ? AntmailAddress.parse(tag.getString("To")) : null; - return new AntmailDraft(id, sender, recipient, tag.getString("Subject"), tag.getString("Body"), attachments); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailEventData.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailEventData.java deleted file mode 100644 index 688605c9..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailEventData.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.server.packs.resources.SimplePreparableReloadListener; -import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.advancements.AdvancementHolder; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public final class AntmailEventData extends SimplePreparableReloadListener> { - private static final AntmailEventData INSTANCE = new AntmailEventData(); - private static volatile Map definitions = Map.of(); - private AntmailEventData() { - } - - public static AntmailEventData instance() { - return INSTANCE; - } - - public static void onTick(MinecraftServer server) { - long dayTime = server.overworld().getDayTime(); - long day = dayTime / 24000L; - if (dayTime % 24000L >= 20L) return; - AntmailServerData data = AntmailServerData.access(server); - if (!data.beginRandomMailDay(day)) return; - for (AntmailAddress address : data.registeredAddresses()) { - for (Map.Entry entry : definitions.entrySet()) { - Definition definition = entry.getValue(); - if (definition.trigger().type().equals("random") && server.overworld().random.nextDouble() < definition.trigger().chance()) deliver(server, address, entry.getKey(), definition, false); - } - } - } - - public static void onAdvancement(ServerPlayer player, AdvancementHolder advancement) { - AntmailServerData data = AntmailServerData.access(player.server); - AntmailAddress address = data.lastUsedAddress(player); - if (address == null) return; - for (Map.Entry entry : definitions.entrySet()) { - Trigger trigger = entry.getValue().trigger(); - if (trigger.type().equals("advancement") && trigger.value().equals(advancement.id().toString())) deliver(player.server, address, entry.getKey(), entry.getValue(), true); - } - } - - private static void deliver(MinecraftServer server, AntmailAddress recipient, ResourceLocation id, Definition definition, boolean permanentClaim) { - AntmailServerData data = AntmailServerData.access(server); - try { - AntmailAddress sender = AntmailAddress.parse(definition.sender()); - AntmailMessage message = AntmailMessage.create(sender, recipient, definition.subject(), definition.body(), server.overworld().getGameTime(), List.of()); - AntmailDeliveryResult result = data.deliver(server, message); - if (permanentClaim && result.status() != AntmailDeliveryResult.Status.MAILBOX_FULL - && result.status() != AntmailDeliveryResult.Status.FAILED - && result.status() != AntmailDeliveryResult.Status.ADDRESS_NOT_FOUND) { - data.claimTrigger(recipient, id); - } - } catch (IllegalArgumentException ignored) { - } - } - - @Override - protected Map prepare(ResourceManager manager, ProfilerFiller profiler) { - Map loaded = new HashMap<>(); - for (Map.Entry resource : manager.listResources("antmail/message", path -> path.getPath().endsWith(".json")).entrySet()) { - try { - JsonElement element = JsonParser.parseReader(resource.getValue().openAsReader()); - if (!element.isJsonObject()) continue; - var object = element.getAsJsonObject(); - var trigger = object.getAsJsonObject("trigger"); - String type = trigger.get("type").getAsString(); - String value = trigger.has("value") ? trigger.get("value").getAsString() : String.valueOf(trigger.get("day").getAsInt()); - ResourceLocation id = ResourceLocation.fromNamespaceAndPath(resource.getKey().getNamespace(), resource.getKey().getPath().substring("antmail/message/".length(), resource.getKey().getPath().length() - 5)); - loaded.put(id, new Definition(object.get("sender").getAsString(), object.get("subject").getAsString(), object.get("body").getAsString(), new Trigger(type, value))); - } catch (Exception ignored) { - } - } - return Map.copyOf(loaded); - } - - @Override - protected void apply(Map loaded, ResourceManager manager, ProfilerFiller profiler) { - definitions = loaded; - } - - public record Definition(String sender, String subject, String body, Trigger trigger) { - } - - public record Trigger(String type, String value) { - double chance() { - try { - return Math.max(0.0D, Math.min(1.0D, Double.parseDouble(value))); - } catch (NumberFormatException ignored) { - return 0.0D; - } - } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailMailbox.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailMailbox.java deleted file mode 100644 index af60e400..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailMailbox.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -public final class AntmailMailbox { - public static final int PAGE_SIZE = 20; - private final AntmailAddress address; - private final List inbox = new ArrayList<>(); - private final List sent = new ArrayList<>(); - private final List drafts = new ArrayList<>(); - private int reportedUnreadCount = -1; - - public AntmailMailbox(AntmailAddress address) { - this.address = address; - } - - public AntmailAddress address() { return address; } - public List inbox() { return List.copyOf(inbox); } - public List sent() { return List.copyOf(sent); } - public List drafts() { return List.copyOf(drafts); } - public int unreadCount() { return reportedUnreadCount >= 0 ? reportedUnreadCount : (int) inbox.stream().filter(message -> !message.read()).count(); } - - public boolean addIncoming(AntmailMessage message) { - if (!address.equals(message.recipient()) || inbox.size() >= AntmailValidation.MAX_MAILBOX_MESSAGES || contains(inbox, message.id())) return false; - inbox.add(message); - return true; - } - - public boolean addSent(AntmailMessage message) { - if (!address.equals(message.sender()) || sent.size() >= AntmailValidation.MAX_MAILBOX_MESSAGES || contains(sent, message.id())) return false; - sent.add(message); - return true; - } - - public boolean saveDraft(AntmailDraft draft) { - if (!address.equals(draft.sender()) || drafts.size() >= AntmailValidation.MAX_DRAFTS && findDraft(draft.id()) == null) return false; - drafts.removeIf(existing -> existing.id().equals(draft.id())); - drafts.add(draft); - return true; - } - - public boolean removeDraft(UUID id) { return drafts.removeIf(draft -> draft.id().equals(id)); } - public boolean removeInbox(UUID id) { return inbox.removeIf(message -> message.id().equals(id)); } - public boolean removeSent(UUID id) { return sent.removeIf(message -> message.id().equals(id)); } - public AntmailMessage findSent(UUID id) { return sent.stream().filter(message -> message.id().equals(id)).findFirst().orElse(null); } - public AntmailMessage findInbox(UUID id) { return inbox.stream().filter(message -> message.id().equals(id)).findFirst().orElse(null); } - - public boolean markRead(UUID id) { - for (AntmailMessage message : inbox) if (message.id().equals(id)) { message.markRead(); return true; } - return false; - } - - public AntmailDraft findDraft(UUID id) { return drafts.stream().filter(draft -> draft.id().equals(id)).findFirst().orElse(null); } - - public CompoundTag toTag() { - return toTag(true); - } - - public CompoundTag toTag(boolean includeMessageAttachments) { - CompoundTag tag = new CompoundTag(); - tag.putString("Address", address.fullAddress()); - tag.put("Inbox", messagesToTag(inbox, includeMessageAttachments)); - tag.put("Sent", messagesToTag(sent, includeMessageAttachments)); - ListTag draftTags = new ListTag(); - for (AntmailDraft draft : drafts) draftTags.add(draft.toTag()); - tag.put("Drafts", draftTags); - return tag; - } - - public CompoundTag toPageTag(int folder, int page) { - int safePage = Math.max(0, page); - int start = safePage * PAGE_SIZE; - CompoundTag tag = new CompoundTag(); - tag.putString("Address", address.fullAddress()); - tag.putInt("Folder", folder); - tag.putInt("Page", safePage); - tag.putInt("PageSize", PAGE_SIZE); - tag.putInt("TotalInbox", inbox.size()); - tag.putInt("TotalSent", sent.size()); - tag.putInt("UnreadCount", (int) inbox.stream().filter(message -> !message.read()).count()); - tag.put("Inbox", folder == 0 ? messagesToTag(page(inbox, start), false) : new ListTag()); - tag.put("Sent", folder == 1 ? messagesToTag(page(sent, start), false) : new ListTag()); - ListTag draftTags = new ListTag(); - for (AntmailDraft draft : drafts) draftTags.add(draft.toTag()); - tag.put("Drafts", draftTags); - return tag; - } - - private static List page(List values, int start) { - if (start >= values.size()) return List.of(); - return values.subList(start, Math.min(start + PAGE_SIZE, values.size())); - } - - public static AntmailMailbox fromTag(CompoundTag tag) { - AntmailMailbox mailbox = new AntmailMailbox(AntmailAddress.parse(tag.getString("Address"))); - if (tag.contains("UnreadCount")) mailbox.reportedUnreadCount = Math.max(0, tag.getInt("UnreadCount")); - readMessages(tag.getList("Inbox", 10), mailbox.inbox); - readMessages(tag.getList("Sent", 10), mailbox.sent); - ListTag draftTags = tag.getList("Drafts", 10); - for (int index = 0; index < draftTags.size() && mailbox.drafts.size() < AntmailValidation.MAX_DRAFTS; index++) { - try { mailbox.drafts.add(AntmailDraft.fromTag(draftTags.getCompound(index))); } catch (RuntimeException ignored) { } - } - return mailbox; - } - - private static ListTag messagesToTag(List messages, boolean includeMessageAttachments) { - ListTag tags = new ListTag(); - for (AntmailMessage message : messages) tags.add(message.toTag(includeMessageAttachments)); - return tags; - } - - private static void readMessages(ListTag tags, List target) { - for (int index = 0; index < tags.size() && target.size() < AntmailValidation.MAX_MAILBOX_MESSAGES; index++) { - try { target.add(AntmailMessage.fromTag(tags.getCompound(index))); } catch (RuntimeException ignored) { } - } - } - - private static boolean contains(List messages, UUID id) { - return messages.stream().anyMatch(message -> message.id().equals(id)); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailMailboxStore.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailMailboxStore.java deleted file mode 100644 index 5fe98546..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailMailboxStore.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; - -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -public final class AntmailMailboxStore { - private final Map mailboxes = new LinkedHashMap<>(); - - public AntmailMailbox getOrCreate(AntmailAddress address) { - return mailboxes.computeIfAbsent(address, AntmailMailbox::new); - } - - public AntmailMailbox get(AntmailAddress address) { - return mailboxes.get(address); - } - - public boolean contains(AntmailAddress address) { - return mailboxes.containsKey(address); - } - - public void put(AntmailMailbox mailbox) { - mailboxes.put(mailbox.address(), mailbox); - } - - public Collection mailboxes() { - return List.copyOf(mailboxes.values()); - } - - public CompoundTag toTag() { - CompoundTag tag = new CompoundTag(); - ListTag mailboxTags = new ListTag(); - for (AntmailMailbox mailbox : mailboxes.values()) mailboxTags.add(mailbox.toTag()); - tag.put("Mailboxes", mailboxTags); - return tag; - } - - public static AntmailMailboxStore fromTag(CompoundTag tag) { - AntmailMailboxStore store = new AntmailMailboxStore(); - ListTag mailboxTags = tag.getList("Mailboxes", 10); - for (int index = 0; index < mailboxTags.size(); index++) { - try { - AntmailMailbox mailbox = AntmailMailbox.fromTag(mailboxTags.getCompound(index)); - store.mailboxes.put(mailbox.address(), mailbox); - } catch (RuntimeException ignored) { - } - } - return store; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailMessage.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailMessage.java deleted file mode 100644 index 74e9751b..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailMessage.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -public final class AntmailMessage { - private static final String ID_TAG = "Id"; - private static final String FROM_TAG = "From"; - private static final String TO_TAG = "To"; - private static final String SUBJECT_TAG = "Subject"; - private static final String BODY_TAG = "Body"; - private static final String CREATED_TAG = "Created"; - private static final String READ_TAG = "Read"; - private static final String ATTACHMENTS_TAG = "Attachments"; - private static final String DELIVERY_STATUS_TAG = "DeliveryStatus"; - - private final UUID id; - private final AntmailAddress sender; - private final AntmailAddress recipient; - private final String subject; - private final String body; - private final long createdAt; - private final List attachments; - private boolean read; - private String deliveryStatus = "DELIVERED"; - - public AntmailMessage(UUID id, AntmailAddress sender, AntmailAddress recipient, String subject, String body, long createdAt, List attachments, boolean read) { - AntmailValidation.Result result = AntmailValidation.validateMessage(sender, recipient, subject, body, attachments); - if (!result.valid()) { - throw new IllegalArgumentException(result.reason()); - } - this.id = id == null ? UUID.randomUUID() : id; - this.sender = sender; - this.recipient = recipient; - this.subject = subject; - this.body = body; - this.createdAt = createdAt; - this.attachments = List.copyOf(attachments); - this.read = read; - } - - public static AntmailMessage create(AntmailAddress sender, AntmailAddress recipient, String subject, String body, long createdAt, List attachments) { - return new AntmailMessage(UUID.randomUUID(), sender, recipient, subject, body, createdAt, attachments, false); - } - - public UUID id() { return id; } - public AntmailAddress sender() { return sender; } - public AntmailAddress recipient() { return recipient; } - public String subject() { return subject; } - public String body() { return body; } - public long createdAt() { return createdAt; } - public List attachments() { return attachments; } - public boolean read() { return read; } - public String deliveryStatus() { return deliveryStatus; } - public void setDeliveryStatus(String status) { deliveryStatus = status == null || status.isBlank() ? "DELIVERED" : status; } - public void markRead() { read = true; } - public void markUnread() { read = false; } - - public CompoundTag toTag() { - return toTag(true); - } - - public CompoundTag toTag(boolean includeAttachments) { - CompoundTag tag = new CompoundTag(); - tag.putString(ID_TAG, id.toString()); - tag.putString(FROM_TAG, sender.fullAddress()); - tag.putString(TO_TAG, recipient.fullAddress()); - tag.putString(SUBJECT_TAG, subject); - tag.putString(BODY_TAG, body); - tag.putLong(CREATED_TAG, createdAt); - tag.putBoolean(READ_TAG, read); - tag.putString(DELIVERY_STATUS_TAG, deliveryStatus); - if (includeAttachments) { - ListTag attachmentTags = new ListTag(); - for (AntmailAttachment attachment : attachments) attachmentTags.add(attachment.toTag()); - tag.put(ATTACHMENTS_TAG, attachmentTags); - } - return tag; - } - - public static AntmailMessage fromTag(CompoundTag tag) { - List attachments = new ArrayList<>(); - ListTag attachmentTags = tag.getList(ATTACHMENTS_TAG, 10); - for (int index = 0; index < attachmentTags.size(); index++) attachments.add(AntmailAttachment.fromTag(attachmentTags.getCompound(index))); - AntmailMessage message = new AntmailMessage(UUID.fromString(tag.getString(ID_TAG)), AntmailAddress.parse(tag.getString(FROM_TAG)), AntmailAddress.parse(tag.getString(TO_TAG)), tag.getString(SUBJECT_TAG), tag.getString(BODY_TAG), tag.getLong(CREATED_TAG), attachments, tag.getBoolean(READ_TAG)); - message.setDeliveryStatus(tag.getString(DELIVERY_STATUS_TAG)); - return message; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailServerData.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailServerData.java deleted file mode 100644 index 60686fe9..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailServerData.java +++ /dev/null @@ -1,339 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import net.minecraft.core.HolderLookup; -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -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 com.craisinlord.antarchy.content.block.entity.ComputerBlockEntity; -import net.minecraft.world.level.saveddata.SavedData; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -public final class AntmailServerData extends SavedData { - private static final String ID = "antarchy_antmail"; - private static final int MAX_PENDING_MESSAGES = AntmailValidation.MAX_MAILBOX_MESSAGES; - private final Map endpoints = new LinkedHashMap<>(); - private final AntmailMailboxStore mailboxes = new AntmailMailboxStore(); - private final List pending = new ArrayList<>(); - private final Map> triggered = new LinkedHashMap<>(); - private final Map mailboxVersions = new LinkedHashMap<>(); - private final Map lastUsedAddresses = new LinkedHashMap<>(); - private long randomMailDay = Long.MIN_VALUE; - private int retryTicks; - - public static AntmailServerData create() { - return new AntmailServerData(); - } - - public static AntmailServerData load(CompoundTag tag, HolderLookup.Provider registries) { - AntmailServerData data = new AntmailServerData(); - ListTag endpointTags = tag.getList("Endpoints", 10); - for (int i = 0; i < endpointTags.size(); i++) { - try { - CompoundTag endpoint = endpointTags.getCompound(i); - AntmailAddress address = AntmailAddress.parse(endpoint.getString("Address")); - data.endpoints.put(address, new Endpoint(endpoint.getString("Dimension"), endpoint.getLong("Position"))); - } catch (RuntimeException ignored) { - } - } - AntmailServerData loaded = data; - AntmailMailboxStore restored = AntmailMailboxStore.fromTag(tag.getCompound("Mailboxes")); - for (AntmailMailbox mailbox : restored.mailboxes()) { - loaded.mailboxes.put(mailbox); - } - ListTag pendingTags = tag.getList("Pending", 10); - for (int i = 0; i < pendingTags.size(); i++) { - try { - CompoundTag pendingTag = pendingTags.getCompound(i); - loaded.pending.add(new PendingMessage(AntmailAddress.parse(pendingTag.getString("Recipient")), AntmailMessage.fromTag(pendingTag.getCompound("Message")))); - } catch (RuntimeException ignored) { - } - } - ListTag triggeredTags = tag.getList("Triggered", 10); - for (int i = 0; i < triggeredTags.size(); i++) { - CompoundTag triggeredTag = triggeredTags.getCompound(i); - try { - AntmailAddress address = AntmailAddress.parse(triggeredTag.getString("Address")); - java.util.Set ids = new java.util.LinkedHashSet<>(); - ListTag idsTag = triggeredTag.getList("Ids", 8); - for (int j = 0; j < idsTag.size(); j++) ids.add(ResourceLocation.parse(idsTag.getString(j))); - data.triggered.put(address, ids); - } catch (RuntimeException ignored) { - } - } - ListTag lastUsedTags = tag.getList("LastUsedAddresses", 10); - for (int i = 0; i < lastUsedTags.size(); i++) { - try { - CompoundTag lastUsedTag = lastUsedTags.getCompound(i); - data.lastUsedAddresses.put(UUID.fromString(lastUsedTag.getString("Player")), AntmailAddress.parse(lastUsedTag.getString("Address"))); - } catch (RuntimeException ignored) { - } - } - data.randomMailDay = tag.contains("RandomMailDay") ? tag.getLong("RandomMailDay") : Long.MIN_VALUE; - ListTag versionTags = tag.getList("MailboxVersions", 10); - for (int i = 0; i < versionTags.size(); i++) { - try { - CompoundTag versionTag = versionTags.getCompound(i); - data.mailboxVersions.put(AntmailAddress.parse(versionTag.getString("Address")), Math.max(1L, versionTag.getLong("Version"))); - } catch (RuntimeException ignored) { - } - } - return loaded; - } - - @Override - public CompoundTag save(CompoundTag tag, HolderLookup.Provider registries) { - ListTag endpointTags = new ListTag(); - for (Map.Entry entry : endpoints.entrySet()) { - CompoundTag endpoint = new CompoundTag(); - endpoint.putString("Address", entry.getKey().fullAddress()); - endpoint.putString("Dimension", entry.getValue().dimension()); - endpoint.putLong("Position", entry.getValue().position()); - endpointTags.add(endpoint); - } - tag.put("Endpoints", endpointTags); - tag.put("Mailboxes", mailboxes.toTag()); - ListTag pendingTags = new ListTag(); - for (PendingMessage message : pending) { - CompoundTag pendingTag = new CompoundTag(); - pendingTag.putString("Recipient", message.recipient().fullAddress()); - pendingTag.put("Message", message.message().toTag()); - pendingTags.add(pendingTag); - } - tag.put("Pending", pendingTags); - ListTag triggeredTags = new ListTag(); - for (Map.Entry> entry : triggered.entrySet()) { - CompoundTag triggeredTag = new CompoundTag(); - triggeredTag.putString("Address", entry.getKey().fullAddress()); - ListTag idsTag = new ListTag(); - for (ResourceLocation id : entry.getValue()) idsTag.add(net.minecraft.nbt.StringTag.valueOf(id.toString())); - triggeredTag.put("Ids", idsTag); - triggeredTags.add(triggeredTag); - } - tag.put("Triggered", triggeredTags); - ListTag lastUsedTags = new ListTag(); - for (Map.Entry entry : lastUsedAddresses.entrySet()) { - CompoundTag lastUsedTag = new CompoundTag(); - lastUsedTag.putString("Player", entry.getKey().toString()); - lastUsedTag.putString("Address", entry.getValue().fullAddress()); - lastUsedTags.add(lastUsedTag); - } - tag.put("LastUsedAddresses", lastUsedTags); - tag.putLong("RandomMailDay", randomMailDay); - ListTag versionTags = new ListTag(); - for (Map.Entry entry : mailboxVersions.entrySet()) { - CompoundTag versionTag = new CompoundTag(); - versionTag.putString("Address", entry.getKey().fullAddress()); - versionTag.putLong("Version", entry.getValue()); - versionTags.add(versionTag); - } - tag.put("MailboxVersions", versionTags); - return tag; - } - - private static AntmailServerData get(MinecraftServer server) { - return server.overworld().getDataStorage().computeIfAbsent( - new SavedData.Factory<>(AntmailServerData::create, AntmailServerData::load, null), ID); - } - - public static AntmailServerData access(MinecraftServer server) { - return get(server); - } - - public synchronized Registration register(MinecraftServer server, ServerLevel level, BlockPos position, String username) { - final AntmailAddress address; - try { - address = AntmailAddress.ofUsername(username); - } catch (IllegalArgumentException exception) { - return Registration.invalid("invalid_username"); - } - AntmailAddress previous = addressAt(level.dimension().location(), position); - Endpoint existing = endpoints.get(address); - if (existing != null && (!existing.dimension().equals(level.dimension().location().toString()) || existing.position() != position.asLong())) { - return Registration.invalid("username_taken"); - } - if (previous != null && !previous.equals(address)) { - endpoints.remove(previous); - } - endpoints.put(address, new Endpoint(level.dimension().location().toString(), position.asLong())); - get(server).drain(server, address); - setDirty(); - return Registration.accepted(address); - } - - public synchronized AntmailAddress addressAt(ResourceLocation dimension, BlockPos position) { - for (Map.Entry entry : endpoints.entrySet()) { - if (entry.getValue().dimension().equals(dimension.toString()) && entry.getValue().position() == position.asLong()) return entry.getKey(); - } - return null; - } - - public synchronized boolean unregister(ResourceLocation dimension, BlockPos position) { - AntmailAddress address = addressAt(dimension, position); - if (address == null) return false; - endpoints.remove(address); - setDirty(); - return true; - } - - public synchronized Endpoint endpoint(AntmailAddress address) { - return endpoints.get(address); - } - - public synchronized List registeredAddresses() { - return List.copyOf(endpoints.keySet()); - } - - public synchronized AntmailAddress addressFor(ServerPlayer player) { - AntmailAddress address = lastUsedAddresses.get(player.getUUID()); - return address != null && endpoints.containsKey(address) ? address : null; - } - - public synchronized AntmailAddress lastUsedAddress(ServerPlayer player) { - AntmailAddress address = lastUsedAddresses.get(player.getUUID()); - return address != null && endpoints.containsKey(address) ? address : null; - } - - public synchronized void setLastUsedAddress(ServerPlayer player, AntmailAddress address) { - if (address == null) return; - lastUsedAddresses.put(player.getUUID(), address); - setDirty(); - } - - public synchronized boolean claimTrigger(AntmailAddress address, ResourceLocation triggerId) { - java.util.Set ids = triggered.computeIfAbsent(address, ignored -> new java.util.LinkedHashSet<>()); - if (!ids.add(triggerId)) return false; - setDirty(); - return true; - } - - public synchronized boolean beginRandomMailDay(long day) { - if (randomMailDay == day) return false; - randomMailDay = day; - setDirty(); - return true; - } - - public synchronized AntmailMailbox mailbox(AntmailAddress address) { - return mailboxes.get(address); - } - - public synchronized AntmailMailbox mailboxOrCreate(AntmailAddress address) { - AntmailMailbox mailbox = mailboxes.getOrCreate(address); - setDirty(); - return mailbox; - } - - public synchronized long mailboxVersion(AntmailAddress address) { - return mailboxVersions.getOrDefault(address, 1L); - } - - public synchronized void touchMailbox(AntmailAddress address) { - if (address == null) return; - mailboxVersions.put(address, mailboxVersion(address) + 1L); - setDirty(); - } - - public synchronized void drainAddress(MinecraftServer server, ServerLevel level, BlockPos position) { - AntmailAddress address = addressAt(level.dimension().location(), position); - if (address != null) drain(server, address); - } - - public synchronized void drainAvailable(MinecraftServer server) { - if (pending.isEmpty() || ++retryTicks < 20) return; - retryTicks = 0; - List available = new ArrayList<>(); - for (Map.Entry entry : endpoints.entrySet()) { - Endpoint endpoint = entry.getValue(); - ServerLevel level = server.getLevel(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.DIMENSION, ResourceLocation.parse(endpoint.dimension()))); - if (level != null && level.hasChunkAt(BlockPos.of(endpoint.position()))) available.add(entry.getKey()); - } - for (AntmailAddress address : available) drain(server, address); - } - - public synchronized AntmailDeliveryResult deliver(MinecraftServer server, AntmailMessage message) { - if (message == null) return AntmailDeliveryResult.failed(AntmailDeliveryResult.Status.MESSAGE_INVALID, null, "missing_message"); - if (endpoint(message.recipient()) == null) return failedAndRecorded(message, AntmailDeliveryResult.Status.ADDRESS_NOT_FOUND, "address_not_found"); - AntmailMailbox destination = mailboxes.getOrCreate(message.recipient()); - if (destination.inbox().size() >= AntmailValidation.MAX_MAILBOX_MESSAGES) return failedAndRecorded(message, AntmailDeliveryResult.Status.MAILBOX_FULL, "mailbox_full"); - Endpoint target = endpoint(message.recipient()); - ServerLevel level = server.getLevel(net.minecraft.resources.ResourceKey.create(net.minecraft.core.registries.Registries.DIMENSION, ResourceLocation.parse(target.dimension()))); - if (level == null || !level.hasChunkAt(BlockPos.of(target.position()))) { - if (pending.stream().anyMatch(item -> item.message().id().equals(message.id()))) { - return AntmailDeliveryResult.failed(AntmailDeliveryResult.Status.DUPLICATE, message, "already_pending"); - } - if (pending.size() >= MAX_PENDING_MESSAGES) { - return failedAndRecorded(message, AntmailDeliveryResult.Status.FAILED, "pending_queue_full"); - } - message.setDeliveryStatus("QUEUED"); - pending.add(new PendingMessage(message.recipient(), message)); - mailboxes.getOrCreate(message.sender()).addSent(message); - touchMailbox(message.recipient()); - touchMailbox(message.sender()); - setDirty(); - return AntmailDeliveryResult.queued(message); - } - message.setDeliveryStatus("DELIVERED"); - destination.addIncoming(message); - mailboxes.getOrCreate(message.sender()).addSent(message); - touchMailbox(message.recipient()); - touchMailbox(message.sender()); - setDirty(); - return AntmailDeliveryResult.delivered(message); - } - - private AntmailDeliveryResult failedAndRecorded(AntmailMessage message, AntmailDeliveryResult.Status status, String detail) { - message.setDeliveryStatus("FAILED // " + detail.toUpperCase()); - mailboxes.getOrCreate(message.sender()).addSent(message); - touchMailbox(message.sender()); - setDirty(); - return AntmailDeliveryResult.failed(status, message, detail); - } - - public synchronized void drain(MinecraftServer server, AntmailAddress address) { - AntmailMailbox mailbox = mailboxes.getOrCreate(address); - final boolean[] delivered = {false}; - Set deliveredSenders = new LinkedHashSet<>(); - pending.removeIf(pendingMessage -> { - if (!pendingMessage.recipient().equals(address) || mailbox.inbox().size() >= AntmailValidation.MAX_MAILBOX_MESSAGES) return false; - if (!mailbox.addIncoming(pendingMessage.message())) return false; - pendingMessage.message().setDeliveryStatus("DELIVERED"); - delivered[0] = true; - deliveredSenders.add(pendingMessage.message().sender()); - return true; - }); - if (delivered[0]) { - touchMailbox(address); - for (AntmailAddress sender : deliveredSenders) touchMailbox(sender); - setDirty(); - } - } - - public synchronized AntmailDeliveryResult retry(MinecraftServer server, AntmailAddress sender, UUID messageId) { - AntmailMessage message = mailboxes.getOrCreate(sender).findSent(messageId); - if (message == null) return null; - pending.removeIf(item -> item.message().id().equals(messageId)); - return deliver(server, message); - } - - public record Endpoint(String dimension, long position) { - } - - public record Registration(boolean valid, AntmailAddress address, String reason) { - static Registration accepted(AntmailAddress address) { return new Registration(true, address, ""); } - static Registration invalid(String reason) { return new Registration(false, null, reason); } - } - - private record PendingMessage(AntmailAddress recipient, AntmailMessage message) { - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailValidation.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailValidation.java deleted file mode 100644 index a9676e10..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailValidation.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import java.nio.charset.StandardCharsets; -import java.util.List; - -public final class AntmailValidation { - public static final int MAX_SUBJECT_LENGTH = 64; - public static final int MAX_BODY_LENGTH = 4096; - public static final int MAX_FILE_NAME_LENGTH = 32; - public static final int MAX_ATTACHMENTS = 8; - public static final int MAX_TEXT_ATTACHMENT_CHARACTERS = 16384; - public static final int MAX_PAINT_WIDTH = 32; - public static final int MAX_PAINT_HEIGHT = 24; - public static final int MAX_MESSAGE_BYTES = 65536; - public static final int MAX_ATTACHMENT_WIRE_CHARS = 65536; - public static final int MAX_MAILBOX_MESSAGES = 100; - public static final int MAX_DRAFTS = 25; - - private AntmailValidation() { - } - - public static Result validateMessage(AntmailAddress sender, AntmailAddress recipient, String subject, String body, List attachments) { - if (sender == null || recipient == null) { - return Result.invalid("missing address"); - } - if (subject == null || subject.length() > MAX_SUBJECT_LENGTH) { - return Result.invalid("subject too long"); - } - if (body == null || body.length() > MAX_BODY_LENGTH) { - return Result.invalid("body too long"); - } - Result attachmentResult = validateAttachments(attachments); - if (!attachmentResult.valid()) return attachmentResult; - int bytes = subject.getBytes(StandardCharsets.UTF_8).length + body.getBytes(StandardCharsets.UTF_8).length; - for (AntmailAttachment attachment : attachments) bytes += attachment.byteSize(); - if (bytes > MAX_MESSAGE_BYTES) { - return Result.invalid("message too large"); - } - return Result.accepted(); - } - - public static Result validateAttachments(List attachments) { - if (attachments == null || attachments.size() > MAX_ATTACHMENTS) return Result.invalid("too many attachments"); - int textCharacters = 0; - for (AntmailAttachment attachment : attachments) { - if (attachment == null) return Result.invalid("null attachment"); - if (attachment instanceof AntmailAttachment.TextFile textFile) { - if (textFile.contents().length() > MAX_TEXT_ATTACHMENT_CHARACTERS) return Result.invalid("text attachment too large"); - textCharacters += textFile.contents().length(); - } else if (attachment instanceof AntmailAttachment.PaintImage paintImage) { - if (paintImage.width() != MAX_PAINT_WIDTH || paintImage.height() != MAX_PAINT_HEIGHT) return Result.invalid("unsupported paint size"); - } - } - if (textCharacters > MAX_TEXT_ATTACHMENT_CHARACTERS) return Result.invalid("text attachments too large"); - return Result.accepted(); - } - - public record Result(boolean valid, String reason) { - public static Result accepted() { - return new Result(true, ""); - } - - public static Result invalid(String reason) { - return new Result(false, reason); - } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailWire.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailWire.java deleted file mode 100644 index 07f6b92b..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/antmail/AntmailWire.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.craisinlord.antarchy.content.antmail; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.NbtAccounter; -import net.minecraft.nbt.NbtIo; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Base64; -import java.util.List; - -public final class AntmailWire { - private static final int MAX_COMPRESSED_BYTES = 1024 * 1024; - private static final long MAX_DECOMPRESSED_BYTES = 8L * 1024L * 1024L; - private AntmailWire() { - } - - public static String encodeAttachments(List attachments) { - AntmailValidation.Result validation = AntmailValidation.validateAttachments(attachments); - if (!validation.valid()) throw new IllegalArgumentException(validation.reason()); - CompoundTag root = new CompoundTag(); - ListTag list = new ListTag(); - for (AntmailAttachment attachment : attachments) list.add(attachment.toTag()); - root.put("Attachments", list); - String encoded = encodeTag(root); - if (encoded.length() > AntmailValidation.MAX_ATTACHMENT_WIRE_CHARS) throw new IllegalArgumentException("Attachment payload is too large"); - return encoded; - } - - public static String encodeTag(CompoundTag tag) { - if (tag == null) throw new IllegalArgumentException("Antmail tag cannot be null"); - try { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - NbtIo.writeCompressed(tag, output); - byte[] compressed = output.toByteArray(); - if (compressed.length > MAX_COMPRESSED_BYTES) throw new IllegalArgumentException("Antmail data is too large"); - return Base64.getEncoder().encodeToString(compressed); - } catch (IOException exception) { - throw new IllegalArgumentException("Could not encode Antmail data", exception); - } - } - - public static CompoundTag decodeTag(String encoded) { - try { - if (encoded == null || encoded.isBlank()) throw new IllegalArgumentException("Antmail data is empty"); - byte[] compressed = Base64.getDecoder().decode(encoded); - if (compressed.length > MAX_COMPRESSED_BYTES) throw new IllegalArgumentException("Antmail data is too large"); - return NbtIo.readCompressed(new ByteArrayInputStream(compressed), NbtAccounter.create(MAX_DECOMPRESSED_BYTES)); - } catch (Exception exception) { - throw new IllegalArgumentException("Invalid Antmail data", exception); - } - } - - public static List decodeAttachments(String encoded) { - if (encoded == null || encoded.isBlank()) return List.of(); - if (encoded.length() > AntmailValidation.MAX_ATTACHMENT_WIRE_CHARS) throw new IllegalArgumentException("Attachment payload is too large"); - try { - CompoundTag root = decodeTag(encoded); - ListTag list = root.getList("Attachments", 10); - List result = new ArrayList<>(); - for (int i = 0; i < list.size(); i++) result.add(AntmailAttachment.fromTag(list.getCompound(i))); - AntmailValidation.Result validation = AntmailValidation.validateAttachments(result); - if (!validation.valid()) throw new IllegalArgumentException(validation.reason()); - return List.copyOf(result); - } catch (Exception exception) { - throw new IllegalArgumentException("Invalid attachment data", exception); - } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/AntTrapBlock.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/AntTrapBlock.java new file mode 100644 index 00000000..7534f2b4 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/AntTrapBlock.java @@ -0,0 +1,52 @@ +package com.craisinlord.antarchy.content.block; + +import com.craisinlord.antarchy.content.block.entity.AntNestBlockEntity; +import com.craisinlord.antarchy.content.entity.ant.BaseAntEntity; +import java.util.List; +import java.util.function.Supplier; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +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.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import net.minecraft.world.level.BlockGetter; + +public final class AntTrapBlock extends AntNestBlock { + private static final VoxelShape SHAPE = Block.box(3.0D, 0.0D, 3.0D, 13.0D, 5.0D, 13.0D); + + public AntTrapBlock(Supplier>> antTypesSupplier, + Supplier> blockEntityTypeSupplier, + BlockBehaviour.Properties properties) { + super(antTypesSupplier, blockEntityTypeSupplier, 10, false, false, properties); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { + return SHAPE; + } + + @Override + public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) { + if (!state.is(newState.getBlock()) && level instanceof ServerLevel serverLevel + && level.getBlockEntity(pos) instanceof AntNestBlockEntity trap) { + trap.releaseAll(serverLevel); + } + super.onRemove(state, level, pos, newState, movedByPiston); + } + + @Override + public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, BlockEntity blockEntity, ItemStack stack) { + if (blockEntity instanceof AntNestBlockEntity trap && level instanceof ServerLevel serverLevel) { + trap.releaseAll(serverLevel); + } + super.playerDestroy(level, player, pos, state, blockEntity, stack); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/ComputerBlock.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/ComputerBlock.java deleted file mode 100644 index c69141b9..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/ComputerBlock.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.craisinlord.antarchy.content.block; - -import com.craisinlord.antarchy.content.AntarchyObjects; -import com.craisinlord.antarchy.content.block.entity.ComputerBlockEntity; -import com.craisinlord.antarchy.content.antmail.AntmailServerData; -import com.craisinlord.antarchy.content.client.AntarchyClientHooks; -import com.mojang.serialization.MapCodec; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.ItemInteractionResult; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.BaseEntityBlock; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.RenderShape; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityTicker; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; - -public final class ComputerBlock extends BaseEntityBlock { - public static final MapCodec CODEC = Block.simpleCodec(ComputerBlock::new); - public static final BooleanProperty ACTIVE = BooleanProperty.create("active"); - public static final DirectionProperty FACING = net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING; - private static final VoxelShape SHAPE = Block.box(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D); - - public ComputerBlock(BlockBehaviour.Properties properties) { - super(properties.lightLevel(state -> state.getValue(ACTIVE) ? 7 : 0)); - registerDefaultState(stateDefinition.any().setValue(ACTIVE, false).setValue(FACING, Direction.NORTH)); - } - - @Override - public MapCodec codec() { - return CODEC; - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(ACTIVE, FACING); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext context) { - return defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); - } - - @Override - protected BlockState rotate(BlockState state, Rotation rotation) { - return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); - } - - @Override - protected BlockState mirror(BlockState state, Mirror mirror) { - return state.rotate(mirror.getRotation(state.getValue(FACING))); - } - - @Override - protected RenderShape getRenderShape(BlockState state) { - return RenderShape.ENTITYBLOCK_ANIMATED; - } - - @Override - protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { - return SHAPE; - } - - @Override - public boolean isSignalSource(BlockState state) { - return true; - } - - @Override - protected int getSignal(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { - return isAuthenticated(level, pos) ? 15 : 0; - } - - @Override - protected int getDirectSignal(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { - return getSignal(state, level, pos, direction); - } - - private static boolean isAuthenticated(BlockGetter level, BlockPos pos) { - return level.getBlockEntity(pos) instanceof ComputerBlockEntity computer && computer.isAuthenticated(); - } - - @Override - protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) { - if (!state.is(newState.getBlock()) && level.getBlockEntity(pos) instanceof ComputerBlockEntity computer) { - computer.dropDisks(level, pos); - if (level instanceof net.minecraft.server.level.ServerLevel serverLevel) { - AntmailServerData.access(serverLevel.getServer()).unregister(serverLevel.dimension().location(), pos); - } - } - super.onRemove(state, level, pos, newState, movedByPiston); - } - - @Override - public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { - return new ComputerBlockEntity(pos, state, AntarchyObjects.COMPUTER_BLOCK_ENTITY); - } - - @Override - public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType blockEntityType) { - return createTickerHelper(blockEntityType, AntarchyObjects.COMPUTER_BLOCK_ENTITY.get(), ComputerBlockEntity::tick); - } - - @Override - protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, - InteractionHand hand, BlockHitResult hitResult) { - if (level.getBlockEntity(pos) instanceof ComputerBlockEntity computer) { - if (level.isClientSide) { - if (stack.is(AntarchyObjects.FLOPPY_DISK.get())) { - return ItemInteractionResult.SUCCESS; - } - } else if (computer.insert(stack, player)) { - return ItemInteractionResult.CONSUME; - } - } - return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; - } - - @Override - protected net.minecraft.world.InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, - BlockHitResult hitResult) { - if (level.getBlockEntity(pos) instanceof ComputerBlockEntity computer) { - computer.activate(); - if (level.isClientSide) { - AntarchyClientHooks.openComputer(pos); - } - return net.minecraft.world.InteractionResult.SUCCESS; - } - return net.minecraft.world.InteractionResult.PASS; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/UndertrialSpawnerBlock.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/UndertrialSpawnerBlock.java index e7dd0661..19ac93be 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/UndertrialSpawnerBlock.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/UndertrialSpawnerBlock.java @@ -6,6 +6,11 @@ import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.SpawnEggItem; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BaseEntityBlock; import net.minecraft.world.level.block.Block; @@ -62,6 +67,22 @@ public final class UndertrialSpawnerBlock extends BaseEntityBlock { return new UndertrialSpawnerBlockEntity(pos, state, blockEntityType); } + @Override + protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, + Player player, net.minecraft.world.InteractionHand hand, + BlockHitResult hitResult) { + if (!(stack.getItem() instanceof SpawnEggItem)) { + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + if (level.getBlockEntity(pos) instanceof UndertrialSpawnerBlockEntity spawner) { + if (!level.isClientSide) { + spawner.setSpawnEntity(((SpawnEggItem) stack.getItem()).getType(stack)); + } + return ItemInteractionResult.sidedSuccess(level.isClientSide); + } + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + @Override public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType blockEntityType) { if (level.isClientSide) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/AntNestBlockEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/AntNestBlockEntity.java index 76c68ee4..59a98938 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/AntNestBlockEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/AntNestBlockEntity.java @@ -40,6 +40,28 @@ public class AntNestBlockEntity extends BlockEntity { } public static void serverTick(ServerLevel level, BlockPos pos, BlockState state, AntNestBlockEntity nest) { + if (state.getBlock() instanceof com.craisinlord.antarchy.content.block.AntTrapBlock) { + if (level.getGameTime() % 20L == 0L && nest.storedAnts.size() < nest.maxOccupants()) { + net.minecraft.world.phys.AABB searchArea = new net.minecraft.world.phys.AABB(pos).inflate(15.0D); + for (BaseAntEntity ant : level.getEntitiesOfClass(BaseAntEntity.class, searchArea, BaseAntEntity::isAlive)) { + if (ant.distanceToSqr(net.minecraft.world.phys.Vec3.atCenterOf(pos)) > 225.0D) { + continue; + } + if (!nest.canAccept(ant.getType())) { + continue; + } + if (ant.distanceToSqr(net.minecraft.world.phys.Vec3.atCenterOf(pos)) <= 2.25D) { + nest.tryStoreAnt(ant); + if (nest.storedAnts.size() >= nest.maxOccupants()) { + break; + } + } else { + ant.getNavigation().moveTo(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, 1.05D); + } + } + } + return; + } boolean playerNearby = level.hasNearbyAlivePlayer( pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, PLAYER_ACTIVATION_RANGE); if (!playerNearby) { @@ -115,12 +137,17 @@ public class AntNestBlockEntity extends BlockEntity { } public void releaseAll(ServerLevel level) { - while (!this.storedAnts.isEmpty()) { - this.releaseOne(level); + int remaining = this.storedAnts.size(); + while (remaining-- > 0 && !this.storedAnts.isEmpty()) { + this.releaseOne(level, true); } } private void releaseOne(ServerLevel level) { + this.releaseOne(level, false); + } + + private void releaseOne(ServerLevel level, boolean forceRelease) { if (this.storedAnts.isEmpty()) { return; } @@ -132,20 +159,39 @@ public class AntNestBlockEntity extends BlockEntity { return; } - BlockPos spawnPos = this.getBlockPos().above(); - if (!level.getBlockState(spawnPos).canBeReplaced()) { + BlockPos origin = this.getBlockPos(); + java.util.List candidates = new java.util.ArrayList<>(); + for (int y = 1; y <= 3; y++) { + candidates.add(origin.above(y)); + for (int radius = 1; radius <= 2; radius++) { + candidates.add(origin.offset(radius, y, 0)); + candidates.add(origin.offset(-radius, y, 0)); + candidates.add(origin.offset(0, y, radius)); + candidates.add(origin.offset(0, y, -radius)); + } + } + BlockPos spawnPos = null; + for (BlockPos candidate : candidates) { + antEntity.moveTo(candidate.getX() + SPAWN_OFFSET_XZ, candidate.getY() + SPAWN_OFFSET_Y, candidate.getZ() + SPAWN_OFFSET_XZ, + level.random.nextFloat() * 360.0F, 0.0F); + if (level.noCollision(antEntity)) { + spawnPos = candidate; + break; + } + } + if (spawnPos == null && !forceRelease) { return; } - - antEntity.moveTo(spawnPos.getX() + SPAWN_OFFSET_XZ, spawnPos.getY() + SPAWN_OFFSET_Y, spawnPos.getZ() + SPAWN_OFFSET_XZ, level.random.nextFloat() * 360.0F, 0.0F); - if (!level.noCollision(antEntity)) { - return; + if (spawnPos == null) { + antEntity.moveTo(origin.getX() + SPAWN_OFFSET_XZ, origin.getY() + SPAWN_OFFSET_Y, origin.getZ() + SPAWN_OFFSET_XZ, + level.random.nextFloat() * 360.0F, 0.0F); } - - this.storedAnts.remove(0); - antEntity.setNestPos(this.getBlockPos()); + antEntity.setNestPos(origin); antEntity.onExitNest(); - level.addFreshEntity(antEntity); + if (!level.addFreshEntity(antEntity) && !forceRelease) { + return; + } + this.storedAnts.remove(0); this.setChanged(); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/ComputerBlockEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/ComputerBlockEntity.java deleted file mode 100644 index ed8b291d..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/ComputerBlockEntity.java +++ /dev/null @@ -1,458 +0,0 @@ -package com.craisinlord.antarchy.content.block.entity; - -import com.craisinlord.antarchy.content.AntarchyObjects; -import com.craisinlord.antarchy.content.block.ComputerBlock; -import com.craisinlord.antarchy.content.computer.ComputerFileSystem; -import com.craisinlord.antarchy.content.computer.ComputerDesktopState; -import com.craisinlord.antarchy.content.guide.ComputerGuideData; -import net.minecraft.core.BlockPos; -import net.minecraft.core.HolderLookup; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.StringTag; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.Containers; -import net.minecraft.world.entity.player.Player; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.block.state.BlockState; - -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Supplier; -import software.bernie.geckolib.animatable.GeoBlockEntity; -import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; -import software.bernie.geckolib.animation.AnimatableManager; -import software.bernie.geckolib.animation.AnimationController; -import software.bernie.geckolib.animation.RawAnimation; -import software.bernie.geckolib.animation.PlayState; -import software.bernie.geckolib.util.GeckoLibUtil; - -public final class ComputerBlockEntity extends BlockEntity implements GeoBlockEntity { - private static final ResourceLocation INTRODUCTION_DISK = ResourceLocation.fromNamespaceAndPath("antarchy", "introduction"); - private static final String DISKS_TAG = "Disks"; - private static final String ACTIVE_UNTIL_TAG = "ActiveUntil"; - private static final String PASSWORD_TAG = "Password"; - private static final String AUTHENTICATED_TAG = "Authenticated"; - private static final String AUTHENTICATED_UNTIL_TAG = "AuthenticatedUntil"; - private static final String DESKTOP_TAG = "Desktop"; - private static final String BASILISK_SCORE_TAG = "BasiliskScore"; - private static final String BASILISK_HIGH_SCORE_TAG = "BasiliskHighScore"; - private static final String ANTMAN_SCORE_TAG = "AntmanScore"; - private static final String ANTMAN_HIGH_SCORE_TAG = "AntmanHighScore"; - private static final String BLOCKLE_DAY_TAG = "BlockleDay"; - private static final String BLOCKLE_GUESSES_TAG = "BlockleGuesses"; - private static final long AUTHENTICATION_TIMEOUT = 6000L; - private final Set physicalDiskIds = new LinkedHashSet<>(); - private final ComputerFileSystem fileSystem = new ComputerFileSystem(); - private final ComputerDesktopState desktopState = new ComputerDesktopState(); - private final AnimatableInstanceCache animatableCache = GeckoLibUtil.createInstanceCache(this); - private static final RawAnimation ON = RawAnimation.begin().thenLoop("on_state"); - private static final RawAnimation OFF = RawAnimation.begin().thenLoop("off_state"); - private static final RawAnimation TURN_ON = RawAnimation.begin().thenPlay("turn_on"); - private static final RawAnimation TURN_OFF = RawAnimation.begin().thenPlay("turn_off"); - private long activeUntil; - private String password = ""; - private boolean authenticated; - private long authenticatedUntil; - private java.util.UUID activeUser; - private boolean lastActive; - private int basiliskScore; - private int basiliskHighScore; - private int antmanScore; - private int antmanHighScore; - private long blockleDay = -1L; - private final List blockleGuesses = new ArrayList<>(); - - public ComputerBlockEntity(BlockPos pos, BlockState state, Supplier> type) { - super(type.get(), pos, state); - } - - public static void tick(Level level, BlockPos pos, BlockState state, ComputerBlockEntity computer) { - boolean active = computer.isActive(); - if (!level.isClientSide && state.getValue(ComputerBlock.ACTIVE) != active) { - level.setBlock(pos, state.setValue(ComputerBlock.ACTIVE, active), 3); - } - if (active != computer.lastActive) { - computer.lastActive = active; - computer.triggerAnim("transitions", active ? "turn_on" : "turn_off"); - } - if (!level.isClientSide && computer.activeUntil > 0L && level.getGameTime() >= computer.activeUntil && !level.hasNeighborSignal(pos)) { - computer.activeUntil = 0L; - computer.setChanged(); - level.sendBlockUpdated(pos, state, state, 3); - } - if (!level.isClientSide && computer.authenticated && (level.getGameTime() >= computer.authenticatedUntil || computer.activeUser == null || - (level instanceof net.minecraft.server.level.ServerLevel serverLevel && serverLevel.getServer().getPlayerList().getPlayer(computer.activeUser) == null))) { - computer.clearAuthentication(); - level.sendBlockUpdated(pos, state, state, 3); - } - } - - public boolean insert(ItemStack stack, Player player) { - if (!stack.is(AntarchyObjects.FLOPPY_DISK.get())) { - return false; - } - ResourceLocation diskId = stack.get(AntarchyObjects.FLOPPY_DISK_COMPONENT.get()); - if (diskId == null || this.physicalDiskIds.contains(diskId)) { - stack.shrink(1); - activate(); - return true; - } - this.physicalDiskIds.add(diskId); - ComputerGuideData.Disk disk = ComputerGuideData.disk(diskId); - if (disk != null && !disk.wallpaper().isBlank()) { - try { - desktopState.unlockWallpaper(ResourceLocation.parse(disk.wallpaper())); - } catch (RuntimeException ignored) { - } - } - stack.shrink(1); - activate(); - setChanged(); - if (level != null) { - level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), 3); - } - return true; - } - - public void activate() { - if (level != null && !level.isClientSide) { - activeUntil = Math.max(activeUntil, level.getGameTime() + 40L); - if (!getBlockState().getValue(ComputerBlock.ACTIVE)) { - level.setBlock(worldPosition, getBlockState().setValue(ComputerBlock.ACTIVE, true), 3); - } - setChanged(); - level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), 3); - } - } - - public boolean isActive() { - return level != null && (level.hasNeighborSignal(worldPosition) || isAuthenticated()); - } - - @Override - public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { - controllers.add(new AnimationController<>(this, "state", state -> state.setAndContinue(isActive() ? ON : OFF))); - controllers.add(new AnimationController<>(this, "transitions", state -> PlayState.STOP) - .triggerableAnim("turn_on", TURN_ON) - .triggerableAnim("turn_off", TURN_OFF)); - } - - @Override - public AnimatableInstanceCache getAnimatableInstanceCache() { - return animatableCache; - } - - public List diskIds() { - List ids = new ArrayList<>(physicalDiskIds.size() + 1); - ids.add(INTRODUCTION_DISK); - ids.addAll(physicalDiskIds); - return List.copyOf(ids); - } - - public boolean ejectOne(Player player) { - if (physicalDiskIds.isEmpty() || !(player instanceof ServerPlayer serverPlayer)) { - return false; - } - return ejectOne(serverPlayer, physicalDiskIds.iterator().next()); - } - - public boolean ejectOne(ServerPlayer player, ResourceLocation diskId) { - if (level == null || level.isClientSide || diskId == null || !isAuthenticated() || !playerCanReach(player) || !physicalDiskIds.remove(diskId)) { - return false; - } - ItemStack disk = diskStack(diskId); - if (!player.addItem(disk)) { - player.drop(disk, false); - } - setChanged(); - level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), 3); - return true; - } - - public void dropDisks(Level level, BlockPos pos) { - if (level.isClientSide) { - return; - } - for (ResourceLocation diskId : physicalDiskIds) { - Containers.dropItemStack(level, pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, diskStack(diskId)); - } - physicalDiskIds.clear(); - } - - public boolean hasPassword() { - return !password.isEmpty(); - } - - public boolean setPassword(ServerPlayer player, String newPassword) { - if (newPassword == null || newPassword.isBlank() || !isAuthenticated()) { - return false; - } - password = newPassword; - setChanged(); - return true; - } - - public boolean initializePassword(ServerPlayer player, String newPassword) { - if (hasPassword() || newPassword == null || newPassword.isBlank() || !claimUser(player)) { - return false; - } - password = newPassword; - authenticated = true; - authenticatedUntil = level.getGameTime() + AUTHENTICATION_TIMEOUT; - setChanged(); - return true; - } - - public boolean initializePassword(String newPassword) { - return false; - } - - public boolean authenticate(ServerPlayer player, String attemptedPassword) { - if (!hasPassword() || !password.equals(attemptedPassword) || !claimUser(player)) { - return false; - } - authenticated = true; - authenticatedUntil = level == null ? 0L : level.getGameTime() + AUTHENTICATION_TIMEOUT; - setChanged(); - return true; - } - - public boolean authenticate(String attemptedPassword) { - return false; - } - - public boolean isAuthenticated() { - if (!authenticated) { - return false; - } - if (level != null && level.getGameTime() >= authenticatedUntil) { - authenticated = false; - authenticatedUntil = 0L; - setChanged(); - return false; - } - return true; - } - - public boolean isAuthenticatedBy(ServerPlayer player) { - return isAuthenticated() && activeUser != null && activeUser.equals(player.getUUID()); - } - - public boolean claimUser(ServerPlayer player) { - if (level == null || level.isClientSide || !playerCanReach(player)) { - return false; - } - if (activeUser != null && !activeUser.equals(player.getUUID()) && isAuthenticated()) { - return false; - } - activeUser = player.getUUID(); - return true; - } - - public boolean playerCanReach(ServerPlayer player) { - return player.level() == level && player.distanceToSqr(worldPosition.getX() + 0.5D, worldPosition.getY() + 0.5D, worldPosition.getZ() + 0.5D) <= 64.0D; - } - - public ComputerFileSystem fileSystem() { - return fileSystem; - } - - public ComputerDesktopState desktopState() { - return desktopState; - } - - public int basiliskScore() { - return basiliskScore; - } - - public int basiliskHighScore() { - return basiliskHighScore; - } - - public void setBasiliskScore(int score) { - basiliskScore = Math.max(0, score); - basiliskHighScore = Math.max(basiliskHighScore, basiliskScore); - setChanged(); - } - - public int antmanScore() { return antmanScore; } - public int antmanHighScore() { return antmanHighScore; } - public void setAntmanScore(int score) { - antmanScore = Math.max(0, score); - antmanHighScore = Math.max(antmanHighScore, antmanScore); - setChanged(); - } - - public long blockleDay() { - return blockleDay; - } - - public List blockleGuesses() { - return List.copyOf(blockleGuesses); - } - - public void resetBlockle(long day) { - if (blockleDay == day) return; - blockleDay = day; - blockleGuesses.clear(); - setChanged(); - } - - public boolean addBlockleGuess(String guess) { - if (blockleGuesses.size() >= 6) return false; - blockleGuesses.add(guess); - setChanged(); - return true; - } - - public boolean unlockWallpaper(ResourceLocation id) { - return serverDesktopMutation(() -> desktopState.unlockWallpaper(id)); - } - - public boolean installProgram(ResourceLocation id) { - return serverDesktopMutation(() -> desktopState.installProgram(id)); - } - - public boolean uninstallProgram(ResourceLocation id) { - return serverDesktopMutation(() -> desktopState.uninstallProgram(id)); - } - - public boolean selectWallpaper(ResourceLocation id) { - return serverDesktopMutation(() -> desktopState.selectWallpaper(id)); - } - - public boolean setIconPosition(ResourceLocation id, int x, int y) { - return serverDesktopMutation(() -> desktopState.setIconPosition(id, x, y)); - } - - public boolean removeIconPosition(ResourceLocation id) { - return serverDesktopMutation(() -> desktopState.removeIconPosition(id)); - } - - private boolean serverDesktopMutation(java.util.function.BooleanSupplier mutation) { - if (level == null || level.isClientSide) { - return false; - } - boolean changed = mutation.getAsBoolean(); - if (changed) { - setChanged(); - level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), 3); - } - return changed; - } - - public boolean canUseFileSystem(ServerPlayer player) { - return level != null && !level.isClientSide && isAuthenticated() && playerCanReach(player) && (activeUser == null || activeUser.equals(player.getUUID())); - } - - public void logout() { - clearAuthentication(); - } - - public void releaseUser(ServerPlayer player) { - if (activeUser != null && activeUser.equals(player.getUUID())) { - activeUser = null; - setChanged(); - } - } - - public void clearAuthentication() { - authenticated = false; - authenticatedUntil = 0L; - activeUser = null; - setChanged(); - } - - public long authenticationTimeout() { - return AUTHENTICATION_TIMEOUT; - } - - public boolean hasActiveUser() { - return activeUser != null && isAuthenticated(); - } - - private static ItemStack diskStack(ResourceLocation diskId) { - ItemStack stack = new ItemStack(AntarchyObjects.FLOPPY_DISK.get()); - stack.set(AntarchyObjects.FLOPPY_DISK_COMPONENT.get(), diskId); - return stack; - } - - @Override - protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.loadAdditional(tag, registries); - physicalDiskIds.clear(); - ListTag disks = tag.getList(DISKS_TAG, 8); - for (int index = 0; index < disks.size(); index++) { - try { - ResourceLocation diskId = ResourceLocation.parse(disks.getString(index)); - if (!INTRODUCTION_DISK.equals(diskId)) { - physicalDiskIds.add(diskId); - } - } catch (Exception ignored) { - } - } - activeUntil = tag.getLong(ACTIVE_UNTIL_TAG); - password = tag.getString(PASSWORD_TAG); - fileSystem.load(tag, registries); - desktopState.load(tag.getCompound(DESKTOP_TAG)); - basiliskScore = tag.getInt(BASILISK_SCORE_TAG); - basiliskHighScore = tag.getInt(BASILISK_HIGH_SCORE_TAG); - antmanScore = tag.getInt(ANTMAN_SCORE_TAG); - antmanHighScore = tag.getInt(ANTMAN_HIGH_SCORE_TAG); - blockleDay = tag.contains(BLOCKLE_DAY_TAG) ? tag.getLong(BLOCKLE_DAY_TAG) : -1L; - blockleGuesses.clear(); - ListTag blockle = tag.getList(BLOCKLE_GUESSES_TAG, 8); - for (int index = 0; index < blockle.size(); index++) { - String guess = blockle.getString(index); - if (guess.length() == 5 && !blockleGuesses.contains(guess) && blockleGuesses.size() < 6) blockleGuesses.add(guess); - } - authenticated = false; - authenticatedUntil = 0L; - activeUser = null; - } - - @Override - protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.saveAdditional(tag, registries); - ListTag disks = new ListTag(); - for (ResourceLocation diskId : physicalDiskIds) { - disks.add(StringTag.valueOf(diskId.toString())); - } - tag.put(DISKS_TAG, disks); - tag.putLong(ACTIVE_UNTIL_TAG, activeUntil); - tag.putString(PASSWORD_TAG, password); - fileSystem.save(tag, registries); - tag.put(DESKTOP_TAG, desktopState.save()); - tag.putInt(BASILISK_SCORE_TAG, basiliskScore); - tag.putInt(BASILISK_HIGH_SCORE_TAG, basiliskHighScore); - tag.putInt(ANTMAN_SCORE_TAG, antmanScore); - tag.putInt(ANTMAN_HIGH_SCORE_TAG, antmanHighScore); - tag.putLong(BLOCKLE_DAY_TAG, blockleDay); - ListTag blockle = new ListTag(); - for (String guess : blockleGuesses) blockle.add(StringTag.valueOf(guess)); - tag.put(BLOCKLE_GUESSES_TAG, blockle); - } - - @Override - public CompoundTag getUpdateTag(HolderLookup.Provider registries) { - CompoundTag tag = new CompoundTag(); - tag.putBoolean("HasPassword", hasPassword()); - tag.putBoolean(AUTHENTICATED_TAG, isAuthenticated()); - ListTag disks = new ListTag(); - for (ResourceLocation diskId : physicalDiskIds) disks.add(StringTag.valueOf(diskId.toString())); - tag.put(DISKS_TAG, disks); - return tag; - } - - @Override - public net.minecraft.network.protocol.Packet getUpdatePacket() { - return net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket.create(this); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UnderVaultBlockEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UnderVaultBlockEntity.java index 841b0871..83cf27eb 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UnderVaultBlockEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UnderVaultBlockEntity.java @@ -30,6 +30,7 @@ import java.util.function.Supplier; public final class UnderVaultBlockEntity extends BlockEntity { private final VaultBlockEntity vaultData; + private boolean playerWasNearby; public UnderVaultBlockEntity(BlockPos pos, BlockState state, Supplier> type) { super(type.get(), pos, state); @@ -49,11 +50,12 @@ public final class UnderVaultBlockEntity extends BlockEntity { // The vanilla vault detector can miss this ceiling-mounted wrapper because its // block state has a separate render-facing property. Keep the state synchronized // with the same four-block activation range before running vanilla's state machine. - if (state.getValue(UnderVaultBlock.STATE) == VaultState.INACTIVE - && !level.getEntitiesOfClass(Player.class, new AABB(pos).inflate(4.0D), player -> !player.isSpectator()).isEmpty()) { + boolean playerNearby = !level.getEntitiesOfClass(Player.class, new AABB(pos).inflate(4.0D), player -> !player.isSpectator()).isEmpty(); + if (state.getValue(UnderVaultBlock.STATE) == VaultState.INACTIVE && playerNearby && !blockEntity.playerWasNearby) { state = state.setValue(UnderVaultBlock.STATE, VaultState.ACTIVE); level.setBlockAndUpdate(pos, state); } + blockEntity.playerWasNearby = playerNearby; VaultBlockEntity.Server.tick(level, pos, state, blockEntity.vaultData.getConfig(), blockEntity.vaultData.getServerData(), blockEntity.vaultData.getSharedData()); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnerBlockEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnerBlockEntity.java index 3f893500..db0965e7 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnerBlockEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnerBlockEntity.java @@ -20,6 +20,7 @@ import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Mob; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.trialspawner.TrialSpawner; import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerConfig; @@ -182,6 +183,16 @@ public final class UndertrialSpawnerBlockEntity extends BlockEntity implements T return trialSpawner; } + public void setSpawnEntity(EntityType entityType) { + if (this.level == null) { + return; + } + // Match vanilla Trial Spawner interaction: override the next mob's entity id while + // preserving weighted potentials, ominous settings, and the trial's reward configuration. + this.trialSpawner.getData().setEntityId(this.trialSpawner, this.level.random, entityType); + this.markUpdated(); + } + public double getClientSpin(float partialTick) { return this.clientOldSpin + (this.clientSpin - this.clientOldSpin) * partialTick; } @@ -199,7 +210,7 @@ public final class UndertrialSpawnerBlockEntity extends BlockEntity implements T private TrialSpawner createRewardlessSpawner(TrialSpawner source) { TrialSpawner rewardless = new TrialSpawner(withoutLootTables(source.getNormalConfig()), withoutLootTables(source.getOminousConfig()), - source.getData(), source.getRequiredPlayerRange(), targetCooldownLength(source), this, + source.getData(), targetCooldownLength(source), source.getRequiredPlayerRange(), this, source.getPlayerDetector(), source.getEntitySelector()); rewardless.overridePeacefulAndMobSpawnRule(); return rewardless; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/AntarchyClientHooks.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/AntarchyClientHooks.java deleted file mode 100644 index 1b822b80..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/AntarchyClientHooks.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.craisinlord.antarchy.content.client; - -import net.minecraft.core.BlockPos; - -import java.util.function.Consumer; - -public final class AntarchyClientHooks { - private static Consumer computerOpener = pos -> { - }; - - private AntarchyClientHooks() { - } - - public static void setComputerOpener(Consumer opener) { - computerOpener = opener; - } - - public static void openComputer(BlockPos pos) { - computerOpener.accept(pos); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/AntarchyGameClientState.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/AntarchyGameClientState.java new file mode 100644 index 00000000..1b991feb --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/AntarchyGameClientState.java @@ -0,0 +1,32 @@ +package com.craisinlord.antarchy.content.client; + +import com.craisinlord.antarchy.content.network.AntarchyGamePayload; +import com.craisinlord.antarchy.content.network.AntarchyGameResultPayload; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import net.minecraft.core.BlockPos; + +/** Client state for Antarchy-owned games hosted by AntOS. */ +public final class AntarchyGameClientState { + private static final Map GAME_STATES = new ConcurrentHashMap<>(); + + private AntarchyGameClientState() { } + + public static void update(AntarchyGameResultPayload result) { + String[] envelope = result.data().split("\u0000", 3); + if (envelope.length < 3) return; + if (envelope[0].equals(Integer.toString(AntarchyGamePayload.BASILISK_STATE)) + || envelope[0].equals(Integer.toString(AntarchyGamePayload.ANTMAN_STATE))) { + GAME_STATES.put(key(result.pos(), envelope[0]), + result.success() ? envelope[2] : ""); + } else if (envelope[0].equals(Integer.toString(AntarchyGamePayload.BLOCKLE_STATE)) + || envelope[0].equals(Integer.toString(AntarchyGamePayload.BLOCKLE_GUESS))) { + if (!result.success()) return; + BlockleClientState.update(result); + } + } + + public static String getGameState(BlockPos pos, int action) { return GAME_STATES.get(key(pos, Integer.toString(action))); } + public static void clearGameState(BlockPos pos, int action) { GAME_STATES.remove(key(pos, Integer.toString(action))); } + private static String key(BlockPos pos, String action) { return pos.asLong() + "|" + action; } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/AntmailClientState.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/AntmailClientState.java deleted file mode 100644 index 6057fc03..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/AntmailClientState.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.craisinlord.antarchy.content.client; - -import com.craisinlord.antarchy.content.network.AntmailResultPayload; -import com.craisinlord.antarchy.content.antmail.AntmailDebug; -import com.craisinlord.antarchy.content.antmail.AntmailMessage; -import net.minecraft.core.BlockPos; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public final class AntmailClientState { - private static final int MAX_CACHED_DETAILS_PER_MAILBOX = 8; - private static final Map RESULTS = new ConcurrentHashMap<>(); - private static final Map MAILBOXES = new ConcurrentHashMap<>(); - private static final Map VERSIONS = new ConcurrentHashMap<>(); - private static final Map> DETAILS = new ConcurrentHashMap<>(); - - private AntmailClientState() { - } - - public static void update(AntmailResultPayload payload) { - AntmailDebug.log("S2C result pos=" + payload.pos() + " status=" + payload.status() + " detail=" + payload.detail() - + " addressPresent=" + !payload.address().isBlank() + " dataChars=" + payload.data().length() - + " version=" + payload.version()); - RESULTS.put(payload.pos(), payload); - if ("unchanged".equals(payload.detail())) { - if (MAILBOXES.containsKey(payload.pos())) { - VERSIONS.put(payload.pos(), payload.version()); - } else { - // An unchanged response cannot initialize a client that has no cached snapshot. - // Keep the next poll unconditional instead of getting stuck on "unchanged". - AntmailDebug.log("received unchanged without cached mailbox at " + payload.pos() + "; forcing full snapshot on next poll"); - VERSIONS.remove(payload.pos()); - } - return; - } else if ("message_detail".equals(payload.detail()) && !payload.data().isBlank()) { - try { - AntmailMessage message = AntmailMessage.fromTag(com.craisinlord.antarchy.content.antmail.AntmailWire.decodeTag(payload.data())); - Map details = DETAILS.computeIfAbsent(payload.pos(), ignored -> new ConcurrentHashMap<>()); - details.put(message.id(), message); - while (details.size() > MAX_CACHED_DETAILS_PER_MAILBOX) { - java.util.UUID oldest = details.keySet().iterator().next(); - details.remove(oldest); - } - } catch (RuntimeException ignored) { - } - } else if (!payload.data().isBlank()) { - MAILBOXES.put(payload.pos(), payload); - VERSIONS.put(payload.pos(), payload.version()); - } else { - // A failed or unconfigured response is authoritative; never show a - // mailbox from a previous address/computer at this position. - MAILBOXES.remove(payload.pos()); - VERSIONS.remove(payload.pos()); - } - } - - public static void clear(BlockPos pos) { - RESULTS.remove(pos); - MAILBOXES.remove(pos); - VERSIONS.remove(pos); - DETAILS.remove(pos); - } - - public static AntmailResultPayload get(BlockPos pos) { - return RESULTS.get(pos); - } - - public static AntmailResultPayload getMailbox(BlockPos pos) { - return MAILBOXES.get(pos); - } - - public static long getVersion(BlockPos pos) { - return VERSIONS.getOrDefault(pos, 0L); - } - - public static AntmailMessage getMessage(BlockPos pos, java.util.UUID id) { - Map details = DETAILS.get(pos); - return details == null ? null : details.get(id); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/BlockleClientState.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/BlockleClientState.java index a11c902a..34c663cb 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/BlockleClientState.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/BlockleClientState.java @@ -1,22 +1,22 @@ package com.craisinlord.antarchy.content.client; -import com.craisinlord.antarchy.content.network.ComputerAccessResultPayload; +import com.craisinlord.antarchy.content.network.AntarchyGameResultPayload; import net.minecraft.core.BlockPos; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public final class BlockleClientState { - private static final Map RESULTS = new ConcurrentHashMap<>(); + private static final Map RESULTS = new ConcurrentHashMap<>(); private BlockleClientState() { } - public static void update(ComputerAccessResultPayload result) { + public static void update(AntarchyGameResultPayload result) { RESULTS.put(result.pos(), result); } - public static ComputerAccessResultPayload get(BlockPos pos) { + public static AntarchyGameResultPayload get(BlockPos pos) { return RESULTS.get(pos); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ComputerAccessClientState.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ComputerAccessClientState.java deleted file mode 100644 index 18c550ad..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ComputerAccessClientState.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.craisinlord.antarchy.content.client; - -import com.craisinlord.antarchy.content.network.ComputerAccessResultPayload; -import net.minecraft.core.BlockPos; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public final class ComputerAccessClientState { - private static final Map RESULTS = new ConcurrentHashMap<>(); - - private ComputerAccessClientState() { - } - - public static void update(ComputerAccessResultPayload result) { - ComputerStructureLocatorClientState.update(result); - if (result.data().startsWith(com.craisinlord.antarchy.content.network.ComputerAccessPayload.ARCHIVE_STATE + "\0")) { - String[] envelope = result.data().split("\u0000", 3); - if (envelope.length == 3) { - com.craisinlord.antarchy.content.guide.ComputerGuideData.applyNetworkSnapshot(envelope[2]); - } - } - if (result.data().startsWith("18\u0000") || result.data().startsWith("19\u0000")) { - BlockleClientState.update(result); - } - // File, terminal, desktop, and wallpaper responses carry their own operation - // status. They must not replace the last authoritative login state. - if (result.data().isBlank()) RESULTS.put(result.pos(), result); - ComputerFileSystemClientState.update(result); - } - - public static void clear(BlockPos pos) { - RESULTS.remove(pos); - } - - public static ComputerAccessResultPayload get(BlockPos pos) { - return RESULTS.get(pos); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ComputerFileSystemClientState.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ComputerFileSystemClientState.java deleted file mode 100644 index 9442bb73..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ComputerFileSystemClientState.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.craisinlord.antarchy.content.client; - -import com.craisinlord.antarchy.content.network.ComputerAccessPayload; -import com.craisinlord.antarchy.content.network.ComputerAccessResultPayload; -import net.minecraft.core.BlockPos; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public final class ComputerFileSystemClientState { - private static final Map STATES = new ConcurrentHashMap<>(); - - private ComputerFileSystemClientState() { - } - - public static void update(ComputerAccessResultPayload payload) { - if (payload.data().isEmpty()) return; - String[] envelope = payload.data().split("\u0000", 3); - if (envelope.length < 3) return; - int action; - try { - action = Integer.parseInt(envelope[0]); - } catch (NumberFormatException ignored) { - return; - } - // Terminal, desktop, and game responses use the same payload envelope, - // but their status must not leak into the file explorer's shared state. - if (action != ComputerAccessPayload.FILE_LIST - && action != ComputerAccessPayload.FILE_OPEN - && action != ComputerAccessPayload.FILE_CREATE - && action != ComputerAccessPayload.FILE_SAVE - && action != ComputerAccessPayload.FILE_DELETE - && action != ComputerAccessPayload.FILE_MOVE) { - return; - } - State state = STATES.computeIfAbsent(payload.pos(), ignored -> new State()); - state.success = payload.result() == ComputerAccessResultPayload.SUCCESS; - state.error = envelope[1]; - if (state.success) state.error = ""; - if (action == ComputerAccessPayload.FILE_CREATE || action == ComputerAccessPayload.FILE_SAVE - || action == ComputerAccessPayload.FILE_DELETE || action == ComputerAccessPayload.FILE_MOVE) { - state.lastMutationAction = action; - state.lastMutationPath = envelope[2]; - state.lastMutationSuccess = state.success; - state.lastMutationError = envelope[1]; - } - if (action == ComputerAccessPayload.FILE_LIST) { - state.files = new ArrayList<>(); - if (state.success && !envelope[2].isEmpty()) state.files.addAll(List.of(envelope[2].split("\\n"))); - } else if (action == ComputerAccessPayload.FILE_OPEN) { - if (state.success) { - String[] file = envelope[2].split("\u0000", 2); - if (file.length == 2) { - state.openedPath = file[0]; - state.openedContents = file[1]; - } - } else { - state.openedPath = ""; - state.openedContents = ""; - } - } else if ((action == ComputerAccessPayload.FILE_DELETE || action == ComputerAccessPayload.FILE_MOVE) && state.success) { - state.openedPath = ""; - state.openedContents = ""; - } - } - - public static State get(BlockPos pos) { - return STATES.computeIfAbsent(pos, ignored -> new State()); - } - - public static final class State { - private List files = List.of(); - private String openedPath = ""; - private String openedContents = ""; - private String error = ""; - private boolean success; - private int lastMutationAction = -1; - private String lastMutationPath = ""; - private boolean lastMutationSuccess; - private String lastMutationError = ""; - - public List files() { return List.copyOf(files); } - public String openedPath() { return openedPath; } - public String openedContents() { return openedContents; } - public String error() { return error; } - public boolean success() { return success; } - public int lastMutationAction() { return lastMutationAction; } - public String lastMutationPath() { return lastMutationPath; } - public boolean lastMutationSuccess() { return lastMutationSuccess; } - public String lastMutationError() { return lastMutationError; } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ComputerStructureLocatorClientState.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ComputerStructureLocatorClientState.java deleted file mode 100644 index 03697861..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/ComputerStructureLocatorClientState.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.craisinlord.antarchy.content.client; - -import com.craisinlord.antarchy.content.network.ComputerAccessPayload; -import com.craisinlord.antarchy.content.network.ComputerAccessResultPayload; -import net.minecraft.core.BlockPos; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public final class ComputerStructureLocatorClientState { - private static final Map RESULTS = new ConcurrentHashMap<>(); - - private ComputerStructureLocatorClientState() { - } - - public static void searching(BlockPos pos, String dimensionId) { - String dimension = dimensionId == null || dimensionId.isBlank() ? "TARGET DIMENSION" : dimensionId.toUpperCase(java.util.Locale.ROOT); - RESULTS.put(pos, "SEARCHING IN " + dimension + "..."); - } - - public static void update(ComputerAccessResultPayload payload) { - String[] envelope = payload.data().split("\u0000", 3); - if (envelope.length != 3) return; - try { - if (Integer.parseInt(envelope[0]) != ComputerAccessPayload.LOCATE_STRUCTURE) return; - } catch (NumberFormatException ignored) { - return; - } - - String message = switch (envelope[1]) { - case "not_found" -> "NO STRUCTURE FOUND WITHIN RANGE"; - case "dimension_unavailable" -> "TARGET DIMENSION UNAVAILABLE"; - default -> "LOCATOR UNAVAILABLE"; - }; - RESULTS.put(payload.pos(), payload.result() == ComputerAccessResultPayload.SUCCESS - ? "STRUCTURE START // " + envelope[2] - : message); - } - - public static String get(BlockPos pos) { - return RESULTS.getOrDefault(pos, "COORDINATES // SEARCH WHEN SELECTED"); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/game/AntarchyComputerGames.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/game/AntarchyComputerGames.java new file mode 100644 index 00000000..4860aa62 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/game/AntarchyComputerGames.java @@ -0,0 +1,79 @@ +package com.craisinlord.antarchy.content.client.game; + +import com.craisinlord.antos.api.client.game.ComputerGame; +import com.craisinlord.antos.api.client.game.ComputerGameRegistry; +import com.craisinlord.antarchy.content.network.AntarchyGameNetworking; +import com.craisinlord.antarchy.content.network.AntarchyGamePayload; +import com.craisinlord.antarchy.content.client.AntarchyGameClientState; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import java.util.function.IntPredicate; +import java.util.function.Predicate; + +/** Registers Antarchy's native games with the AntOS Games app. */ +public final class AntarchyComputerGames { + private AntarchyComputerGames() {} + + public static void register() { + ComputerGameRegistry.register(game("basilisk", "BASILISK", pos -> { + BasiliskProgram program = new BasiliskProgram(true, 0, 0, score -> AntarchyGameNetworking.saveBasiliskScore(pos, score)); + var loaded = new java.util.concurrent.atomic.AtomicBoolean(); + AntarchyGameNetworking.requestBasiliskState(pos); + return new GameSession(() -> { if (!loaded.get()) loaded.set(loadScores(pos, AntarchyGamePayload.BASILISK_STATE, program::setStoredScores)); program.tick(); }, program::render, key -> loaded.get() && program.keyPressed(key), ignored -> false); + })); + ComputerGameRegistry.register(game("antman", "ANTMAN.EXE", pos -> { + AntmanProgram program = new AntmanProgram(true, 0, 0, score -> AntarchyGameNetworking.saveAntmanScore(pos, score)); + var loaded = new java.util.concurrent.atomic.AtomicBoolean(); + AntarchyGameNetworking.requestAntmanState(pos); + return new GameSession(() -> { if (!loaded.get()) loaded.set(loadScores(pos, AntarchyGamePayload.ANTMAN_STATE, program::setStoredScores)); program.tick(); }, program::render, key -> loaded.get() && program.keyPressed(key), ignored -> false); + })); + ComputerGameRegistry.register(game("blockle", "BLOCKLE", pos -> { + BlockleProgram program = new BlockleProgram(pos); + program.setInstalled(true); + return new GameSession(program::tick, program::render, program::keyPressed, program::charTyped); + })); + } + + private static boolean loadScores(BlockPos pos, int action, java.util.function.BiConsumer setter) { + String response = AntarchyGameClientState.getGameState(pos, action); + if (response == null) return false; + if (response.isBlank()) { AntarchyGameClientState.clearGameState(pos, action); return true; } + String[] scores = response.split("\0", 2); + if (scores.length != 2) return false; + try { setter.accept(Integer.parseInt(scores[0]), Integer.parseInt(scores[1])); } + catch (NumberFormatException ignored) { return false; } + AntarchyGameClientState.clearGameState(pos, action); + return true; + } + + private static ComputerGame game(String path, String title, ProgramFactory factory) { + ResourceLocation id = ResourceLocation.fromNamespaceAndPath("antarchy", path); + ResourceLocation disk = ResourceLocation.fromNamespaceAndPath("antarchy", path + "_game"); + return new ComputerGame() { + @Override public ResourceLocation id() { return id; } + @Override public ResourceLocation diskId() { return disk; } + @Override public String title() { return title; } + @Override public Session create(BlockPos position) { return factory.create(position); } + }; + } + + @FunctionalInterface + private interface ProgramFactory { ComputerGame.Session create(BlockPos position); } + + @FunctionalInterface private interface GameRenderer { void render(GuiGraphics graphics, Font font, int x, int y, int width, int height); } + private static final class GameSession implements ComputerGame.Session { + private final Runnable ticker; + private final GameRenderer renderer; + private final IntPredicate keyHandler; + private final Predicate charHandler; + private GameSession(Runnable ticker, GameRenderer renderer, IntPredicate keyHandler, Predicate charHandler) { + this.ticker = ticker; this.renderer = renderer; this.keyHandler = keyHandler; this.charHandler = charHandler; + } + @Override public void tick() { ticker.run(); } + @Override public void render(GuiGraphics graphics, Font font, int x, int y, int width, int height) { renderer.render(graphics, font, x, y, width, height); } + @Override public boolean keyPressed(int keyCode) { return keyHandler.test(keyCode); } + @Override public boolean charTyped(char codePoint) { return charHandler.test(codePoint); } + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/game/BlockleProgram.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/game/BlockleProgram.java index c2413431..61642d14 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/game/BlockleProgram.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/game/BlockleProgram.java @@ -1,8 +1,8 @@ package com.craisinlord.antarchy.content.client.game; import com.craisinlord.antarchy.content.client.BlockleClientState; -import com.craisinlord.antarchy.content.network.ComputerAccessResultPayload; -import com.craisinlord.antarchy.content.network.ComputerNetworking; +import com.craisinlord.antarchy.content.network.AntarchyGameResultPayload; +import com.craisinlord.antarchy.content.network.AntarchyGameNetworking; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.core.BlockPos; @@ -40,11 +40,11 @@ public final class BlockleProgram { } public void requestState() { - if (installed) ComputerNetworking.requestBlockleState(position); + if (installed) AntarchyGameNetworking.requestBlockleState(position); } public void tick() { - ComputerAccessResultPayload result = BlockleClientState.get(position); + AntarchyGameResultPayload result = BlockleClientState.get(position); if (result == null) return; if (result.data().equals(lastResponse)) return; lastResponse = result.data(); @@ -72,7 +72,7 @@ public final class BlockleProgram { if (keyCode == 257 || keyCode == 335) { if (!received) return true; if (input.length() == 5 && phase.equals("PLAYING") && !pending) { - ComputerNetworking.submitBlockleGuess(position, input); + AntarchyGameNetworking.submitBlockleGuess(position, input); pending = true; status = "SUBMITTING"; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/ComputerModel.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/ComputerModel.java deleted file mode 100644 index 87bdb90b..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/ComputerModel.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.craisinlord.antarchy.content.client.model; - -import com.craisinlord.antarchy.Antarchy; -import com.craisinlord.antarchy.content.block.entity.ComputerBlockEntity; -import net.minecraft.resources.ResourceLocation; -import software.bernie.geckolib.model.GeoModel; - -public final class ComputerModel extends GeoModel { - private static final ResourceLocation MODEL = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "geo/computer.geo.json"); - private static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/block/computer/computer.png"); - private static final ResourceLocation ANIMATION = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "animations/computer.animation.json"); - - @Override - public ResourceLocation getModelResource(ComputerBlockEntity animatable) { - return MODEL; - } - - @Override - public ResourceLocation getTextureResource(ComputerBlockEntity animatable) { - return TEXTURE; - } - - @Override - public ResourceLocation getAnimationResource(ComputerBlockEntity animatable) { - return ANIMATION; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/particle/BugSprayParticle.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/particle/BugSprayParticle.java new file mode 100644 index 00000000..917e4267 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/particle/BugSprayParticle.java @@ -0,0 +1,52 @@ +package com.craisinlord.antarchy.content.client.particle; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.ParticleRenderType; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.client.particle.TextureSheetParticle; +import net.minecraft.core.particles.SimpleParticleType; + +public final class BugSprayParticle extends TextureSheetParticle { + private final SpriteSet sprites; + + private BugSprayParticle(ClientLevel level, double x, double y, double z, double xd, double yd, double zd, SpriteSet sprites) { + super(level, x, y, z, xd, yd, zd); + this.sprites = sprites; + this.setSprite(sprites.get(level.random)); + this.lifetime = 14 + this.random.nextInt(8); + this.quadSize = 0.16F + this.random.nextFloat() * 0.14F; + this.friction = 0.88F; + this.gravity = -0.01F; + this.alpha = 0.9F; + } + + @Override + public void tick() { + super.tick(); + if (!this.removed) { + this.setSprite(this.sprites.get(Math.min(this.age, this.lifetime - 1), this.lifetime)); + this.alpha = 0.9F * (1.0F - (float) this.age / this.lifetime); + } + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; + } + + public static final class Provider implements ParticleProvider { + private final SpriteSet sprites; + + public Provider(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle(SimpleParticleType type, ClientLevel level, double x, double y, double z, + double xd, double yd, double zd) { + return new BugSprayParticle(level, x, y, z, xd, yd, zd, this.sprites); + } + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/ComputerRenderer.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/ComputerRenderer.java deleted file mode 100644 index 24dd5208..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/ComputerRenderer.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.craisinlord.antarchy.content.client.renderer; - -import com.craisinlord.antarchy.content.block.entity.ComputerBlockEntity; -import com.craisinlord.antarchy.content.client.model.ComputerModel; -import net.minecraft.core.Direction; -import software.bernie.geckolib.renderer.GeoBlockRenderer; - -public final class ComputerRenderer extends GeoBlockRenderer { - public ComputerRenderer(net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context context) { - super(new ComputerModel()); - } - - @Override - protected Direction getFacing(ComputerBlockEntity computer) { - return computer.getBlockState().getValue(com.craisinlord.antarchy.content.block.ComputerBlock.FACING); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalAssailantAxeAfterimageLayer.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalAssailantAxeAfterimageLayer.java deleted file mode 100644 index 47fb9cdb..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalAssailantAxeAfterimageLayer.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.craisinlord.antarchy.content.client.renderer; - -import com.craisinlord.antarchy.content.item.RoyalAssailantBattleAxeItem; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.math.Axis; -import net.minecraft.client.Minecraft; -import net.minecraft.client.model.PlayerModel; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.LivingEntityRenderer; -import net.minecraft.client.renderer.entity.RenderLayerParent; -import net.minecraft.client.renderer.entity.layers.RenderLayer; -import net.minecraft.world.entity.HumanoidArm; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; - -public final class RoyalAssailantAxeAfterimageLayer extends RenderLayer> { - private static final int[] TINTS = { - 0x66FFD966, - 0x4DFFC94D, - 0x33FFB52E, - 0x1FFF8C14 - }; - - public RoyalAssailantAxeAfterimageLayer(RenderLayerParent> renderer) { - super(renderer); - } - - @Override - public void render(PoseStack poseStack, MultiBufferSource buffer, int packedLight, AbstractClientPlayer player, - float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, - float headPitch) { - if (player.isSpectator() || player.isInvisible() || player.getAttackAnim(partialTick) <= 0.01F) { - return; - } - - ItemStack stack = player.getMainHandItem(); - HumanoidArm arm = player.getMainArm(); - if (!(stack.getItem() instanceof RoyalAssailantBattleAxeItem)) { - stack = player.getOffhandItem(); - arm = player.getMainArm() == HumanoidArm.RIGHT ? HumanoidArm.LEFT : HumanoidArm.RIGHT; - } - if (!(stack.getItem() instanceof RoyalAssailantBattleAxeItem)) { - return; - } - - VertexConsumer vertexConsumer = buffer.getBuffer(RenderType.entityTranslucent(this.getTextureLocation(player))); - float swing = player.getAttackAnim(partialTick); - for (int i = TINTS.length - 1; i >= 0; i--) { - poseStack.pushPose(); - float offset = (i + 1) * 0.08F; - poseStack.translate(0.0D, 0.0D, offset); - poseStack.mulPose(Axis.YP.rotation((i + 1) * 0.12F * (swing < 0.5F ? -1.0F : 1.0F))); - this.getParentModel().renderToBuffer( - poseStack, - vertexConsumer, - LightTexture.FULL_BRIGHT, - LivingEntityRenderer.getOverlayCoords(player, 0.0F), - TINTS[i] - ); - poseStack.popPose(); - } - - for (int i = TINTS.length - 1; i >= 0; i--) { - poseStack.pushPose(); - this.getParentModel().translateToHand(arm, poseStack); - poseStack.mulPose(Axis.YP.rotation((i + 1) * 0.12F * (swing < 0.5F ? -1.0F : 1.0F))); - Minecraft.getInstance().getItemRenderer().renderStatic( - player, - stack, - arm == HumanoidArm.RIGHT ? ItemDisplayContext.THIRD_PERSON_RIGHT_HAND : ItemDisplayContext.THIRD_PERSON_LEFT_HAND, - arm == HumanoidArm.LEFT, - poseStack, - buffer, - player.level(), - packedLight, - LivingEntityRenderer.getOverlayCoords(player, 0.0F), - player.getId() - ); - poseStack.popPose(); - } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalIndicatorRenderer.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalIndicatorRenderer.java index d8c45925..1d60e898 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalIndicatorRenderer.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/renderer/RoyalIndicatorRenderer.java @@ -49,11 +49,20 @@ public final class RoyalIndicatorRenderer { private static void crownPoints(VertexConsumer out, PoseStack.Pose pose, float radius, float rotation, float r, float g, float b, float a) { - for (int i = 0; i < 3; i++) { - double angle = rotation + Math.PI * 2.0D * i / 3.0D; - float x = (float) Math.cos(angle) * radius; - float z = (float) Math.sin(angle) * radius; - line(out, pose, x, 0.0F, z, x * 0.68F, 0.19F, z * 0.68F, r, g, b, a); + final int spikes = 5; + float innerRadius = radius * 0.72F; + for (int i = 0; i < spikes; i++) { + double outerAngle = rotation + Math.PI * 2.0D * i / spikes; + double innerAngle = rotation + Math.PI * 2.0D * (i + 0.5D) / spikes; + float outerX = (float) Math.cos(outerAngle) * radius; + float outerZ = (float) Math.sin(outerAngle) * radius; + float innerX = (float) Math.cos(innerAngle) * innerRadius; + float innerZ = (float) Math.sin(innerAngle) * innerRadius; + float nextOuterX = (float) Math.cos(rotation + Math.PI * 2.0D * (i + 1) / spikes) * radius; + float nextOuterZ = (float) Math.sin(rotation + Math.PI * 2.0D * (i + 1) / spikes) * radius; + line(out, pose, outerX, 0.0F, outerZ, innerX, 0.34F, innerZ, r, g, b, a); + line(out, pose, innerX, 0.34F, innerZ, nextOuterX, 0.0F, nextOuterZ, r, g, b, a); + line(out, pose, outerX, 0.0F, outerZ, nextOuterX, 0.0F, nextOuterZ, r, g, b, a); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/screen/ComputerScreen.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/screen/ComputerScreen.java deleted file mode 100644 index 60f3c40a..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/screen/ComputerScreen.java +++ /dev/null @@ -1,3029 +0,0 @@ -package com.craisinlord.antarchy.content.client.screen; - -import com.craisinlord.antarchy.Antarchy; -import com.craisinlord.antarchy.content.block.entity.ComputerBlockEntity; -import com.craisinlord.antarchy.content.client.ComputerAccessClientState; -import com.craisinlord.antarchy.content.client.BlockleClientState; -import com.craisinlord.antarchy.content.client.ComputerFileSystemClientState; -import com.craisinlord.antarchy.content.client.AntmailClientState; -import com.craisinlord.antarchy.content.antmail.AntmailAddress; -import com.craisinlord.antarchy.content.antmail.AntmailMailbox; -import com.craisinlord.antarchy.content.antmail.AntmailMessage; -import com.craisinlord.antarchy.content.antmail.AntmailWire; -import com.craisinlord.antarchy.content.antmail.AntmailAttachment; -import com.craisinlord.antarchy.content.antmail.AntmailAttachmentFiles; -import com.craisinlord.antarchy.content.antmail.AntmailDraft; -import com.craisinlord.antarchy.content.guide.ComputerGuideData; -import com.craisinlord.antarchy.content.network.ComputerAccessResultPayload; -import com.craisinlord.antarchy.content.network.AntmailResultPayload; -import com.craisinlord.antarchy.content.network.ComputerNetworking; -import com.craisinlord.antarchy.content.network.AntmailNetworking; -import com.craisinlord.antarchy.content.computer.paint.AntPaintCanvas; -import com.craisinlord.antarchy.content.computer.paint.AntPaintHistory; -import com.craisinlord.antarchy.content.computer.paint.AntPaintTool; -import com.craisinlord.antarchy.content.computer.paint.AntPaintFile; -import com.craisinlord.antarchy.content.computer.paint.AntPaintFileCodec; -import com.craisinlord.antarchy.content.computer.ComputerFileSystem; -import com.craisinlord.antarchy.content.computer.ComputerDesktopState; -import com.craisinlord.antarchy.content.client.game.BasiliskProgram; -import com.craisinlord.antarchy.content.client.game.AntmanProgram; -import com.craisinlord.antarchy.content.client.game.BlockleProgram; -import com.craisinlord.antarchy.content.computer.terminal.TerminalCommandParser; -import com.craisinlord.antarchy.content.computer.terminal.TerminalResult; -import com.craisinlord.antarchy.config.AntarchySettings; -import com.craisinlord.antarchy.content.entity.nightmare.NightmareEntity; -import org.lwjgl.glfw.GLFW; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.resources.ResourceKey; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.core.component.DataComponents; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.client.gui.screens.inventory.InventoryScreen; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.alchemy.Potion; -import net.minecraft.world.item.alchemy.PotionContents; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.RecipeHolder; -import net.minecraft.world.item.crafting.ShapedRecipe; -import net.minecraft.world.item.enchantment.Enchantment; -import net.minecraft.world.item.enchantment.ItemEnchantments; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Base64; -import java.util.HashSet; -import java.util.HashMap; -import java.util.Set; -import java.util.UUID; - -public final class ComputerScreen extends Screen { - private static final int WIDTH = 440; - private static final int HEIGHT = 286; - private static final int GREEN = 0xFF65FF65; - private static final int PALE_GREEN = 0xFFB8FFB8; - private static final int DARK_GREEN = 0xFF102010; - private static final int BLACK = 0xFF030603; - private static final int TITLE_BAR_HEIGHT = 20; - private static final int WINDOW_CONTROL_WIDTH = 18; - private static final int WINDOW_CONTROL_COUNT = 3; - private static final int TRASH_ICON_INDEX = 8; - private static final String[] BOOT_MESSAGES = {"ANTS MARCHING...", "COMPUTER COMPUTING...", "HCFS BREWING...", "WAKING THE QUEEN..."}; - private static final long SESSION_TIMEOUT = 300_000L; - private static final Map SESSIONS = new LinkedHashMap<>(); - private static final String[] ICONS = {"ARCHIVE", "FILES", "SETTINGS", "TERMINAL", "TEXT", "PAINT", "ANTMAIL", "GAMES", "TRASH"}; - private static final Map TITLES = Map.of("ARCHIVE", "ANTARCHIVE", "FILES", "FILE EXPLORER", "SETTINGS", "SYSTEM SETTINGS", "TERMINAL", "ANTINTOSH TERMINAL", "TEXT", "ANTTEXT EDITOR", "PAINT", "ANTPAINT", "ANTMAIL", "ANTMAIL", "GAMES", "INSTALLED GAMES", "TRASH", "RECYCLE BIN"); - private final net.minecraft.core.BlockPos position; - private final String sessionKey; - private final Session session; - private boolean loggedIn; - private String password = ""; - private String confirmation = ""; - private boolean confirmingPassword; - private String loginMessage = ""; - private int loginMessageTicks; - private ComputerAccessResultPayload accessResult; - private int observedResult = -1; - private Window dragging; - private boolean paintStrokeActive; - private int paintStrokeButton = -1; - private int lastPaintPixelX = -1; - private int lastPaintPixelY = -1; - private String draggedDisk; - private ResourceLocation selectedDisk; - private int dragX; - private int dragY; - private Window activeWindow; - private final BasiliskProgram basilisk; - private final AntmanProgram antman; - private final BlockleProgram blockle; - private final Set archiveRenderLog = new HashSet<>(); - private final Map archiveEntityPreviews = new HashMap<>(); - private final Set unavailableArchiveEntities = new HashSet<>(); - - public ComputerScreen(net.minecraft.core.BlockPos position) { - super(Component.translatable("screen.antarchy.computer")); - this.position = position; - this.basilisk = new BasiliskProgram(false, 0, 0, score -> ComputerNetworking.saveBasiliskScore(this.position, score)); - this.antman = new AntmanProgram(false, 0, 0, score -> ComputerNetworking.saveAntmanScore(this.position, score)); - this.blockle = new BlockleProgram(this.position); - String dimension = Minecraft.getInstance().level == null ? "" : Minecraft.getInstance().level.dimension().location().toString(); - this.sessionKey = dimension + ":" + position.asLong(); - this.session = SESSIONS.computeIfAbsent(sessionKey, ignored -> new Session()); - this.session.windows.removeIf(window -> window.type.equals("GAMES") && window.gameOpen); - if (this.session.bootTicks < 0) this.session.bootTicks = 80; - this.session.antmanStateRequested = false; - this.session.blockleStateRequested = false; - this.session.antmanResponse = ""; - ComputerAccessClientState.clear(position); - BlockleClientState.clear(position); - ComputerNetworking.open(position); - this.accessResult = ComputerAccessClientState.get(position); - this.loggedIn = accessResult != null && accessResult.authenticated() && session.lastUse + SESSION_TIMEOUT > System.currentTimeMillis(); - if (loggedIn) { - requestAntmailState(); - session.antmailRefreshTicks = 40; - } - if (!loggedIn) { - session.authenticated = false; - session.windows.clear(); - } - } - - @Override - public void tick() { - if (session.bootTicks > 0) session.bootTicks--; - if (loginMessageTicks > 0) loginMessageTicks--; - ComputerAccessResultPayload currentResult = ComputerAccessClientState.get(position); - if (currentResult != null) { - accessResult = currentResult; - if (currentResult.result() != observedResult) { - observedResult = currentResult.result(); - if (currentResult.result() == ComputerAccessResultPayload.SUCCESS) { - loginMessage = "ACCESS GRANTED // WELCOME"; - loginMessageTicks = 40; - } else if (currentResult.result() == ComputerAccessResultPayload.INVALID_PASSWORD) { - loginMessage = "ACCESS DENIED // PASSWORD REJECTED"; - loginMessageTicks = 100; - } else if (currentResult.result() == ComputerAccessResultPayload.BUSY) { - loginMessage = "TERMINAL BUSY // USER PRESENT"; - loginMessageTicks = 100; - } - } - } - AntmailResultPayload mailResult = AntmailClientState.get(position); - syncAntmailPaintAttachment(); - if (loggedIn && --session.antmailRefreshTicks <= 0) { - requestAntmailState(); - session.antmailRefreshTicks = 40; - } - if (loggedIn && AntmailClientState.getMailbox(position) == null) session.antmailStateWaitTicks++; - else session.antmailStateWaitTicks = 0; - if (session.antmailRegistrationPending && mailResult != null) { - String expectedAddress = session.antmailUsername + "@antmail.com"; - if (mailResult.address().equalsIgnoreCase(expectedAddress)) { - session.antmailStatus = "ADDRESS REGISTERED"; - session.antmailRegistrationPending = false; - requestAntmailState(); - } else if (mailResult.detail().startsWith("registration_failed:")) { - String reason = mailResult.detail().substring("registration_failed:".length()).trim(); - session.antmailStatus = "ADDRESS REGISTRATION FAILED // " + (reason.isBlank() ? "SERVER REJECTED" : reason.toUpperCase()); - session.antmailRegistrationPending = false; - } - } - if (!session.antmailRetryMessageId.isBlank() && mailResult != null - && mailResult != session.antmailRetryBaseline - && session.antmailRetryMessageId.equals(mailResult.messageId()) - && !"message_detail".equals(mailResult.detail())) { - session.antmailStatus = antmailStatus(mailResult); - session.antmailRetryMessageId = ""; - session.antmailRetryBaseline = null; - session.antmailRetryTicks = 0; - requestAntmailState(true); - } else if (!session.antmailRetryMessageId.isBlank() && --session.antmailRetryTicks <= 0) { - session.antmailStatus = "RETRY TIMED OUT // TRY AGAIN"; - session.antmailRetryMessageId = ""; - session.antmailRetryBaseline = null; - requestAntmailState(true); - } - if (!loggedIn && accessResult != null && accessResult.authenticated()) { - loggedIn = true; - session.authenticated = true; - session.lastUse = System.currentTimeMillis(); - session.antmailRefreshTicks = 40; - requestAntmailState(); - } - if (loggedIn && (session.lastUse + SESSION_TIMEOUT <= System.currentTimeMillis() || accessResult == null || !accessResult.authenticated())) { - loggedIn = false; - session.authenticated = false; - session.windows.clear(); - } - if (loggedIn && !session.desktopRequested) { - ComputerNetworking.requestDesktopState(position); - session.desktopRequested = true; - } - if (loggedIn && !session.basiliskStateRequested) { - ComputerNetworking.requestBasiliskState(position); - session.basiliskStateRequested = true; - } - if (loggedIn && !session.antmanStateRequested) { - ComputerNetworking.requestAntmanState(position); - session.antmanStateRequested = true; - } - if (loggedIn && !session.blockleStateRequested) { - ComputerNetworking.requestBlockleState(position); - session.blockleStateRequested = true; - } - if (currentResult != null && currentResult.data().startsWith("11\u0000")) { - String[] desktop = currentResult.data().split("\u0000", 3); - if (desktop.length == 3 && !desktop[2].isBlank()) { - try { - var state = new ComputerDesktopState(); - state.load(AntmailWire.decodeTag(desktop[2])); - session.wallpaperId = state.selectedWallpaper() == null ? ComputerDesktopState.DEFAULT_WALLPAPER.toString() : state.selectedWallpaper().toString(); - session.wallpapers = state.unlockedWallpaperIds().stream().map(ResourceLocation::toString).toList(); - } catch (RuntimeException ignored) { - } - } - } - if (currentResult != null && currentResult.data().startsWith("15\u0000") && !currentResult.data().equals(session.terminalResponse)) { - session.terminalResponse = currentResult.data(); - try { - var terminal = AntmailWire.decodeTag(currentResult.data().substring(3)); - session.terminalDirectory = terminal.getString("Directory"); - if (terminal.getBoolean("Clear")) session.terminalOutput.clear(); - var lines = terminal.getList("Lines", 8); - for (int index = 0; index < lines.size(); index++) session.terminalOutput.add(lines.getString(index)); - String openPath = terminal.getString("Open"); - if (!openPath.isBlank()) { - ComputerNetworking.openFile(position, openPath); - open(openPath.endsWith(".antpaint") ? "PAINT" : "TEXT"); - } - while (session.terminalOutput.size() > 40) session.terminalOutput.remove(0); - } catch (RuntimeException ignored) { - session.terminalOutput.add("ERROR: CORRUPTED SERVER RESPONSE"); - } - } - boolean unlockAllGames = AntarchySettings.unlockAllArchives(); - basilisk.setInstalled(unlockAllGames || physicalDisks().stream().anyMatch(id -> id.getPath().equals("basilisk_game"))); - antman.setInstalled(unlockAllGames || physicalDisks().stream().anyMatch(id -> id.getPath().equals("antman_game"))); - boolean blockleWasInstalled = blockle.installed(); - blockle.setInstalled(unlockAllGames || physicalDisks().stream().anyMatch(id -> id.getPath().equals("blockle_game"))); - if (loggedIn && blockle.installed() && !blockleWasInstalled) { - ComputerNetworking.requestBlockleState(position); - session.blockleStateRequested = true; - } - blockle.tick(); - if (currentResult != null && currentResult.data().startsWith("16\u0000") && !currentResult.data().equals(session.basiliskResponse)) { - session.basiliskResponse = currentResult.data(); - String[] scores = currentResult.data().split("\u0000", 3); - if (scores.length == 3) { - String[] values = scores[2].split("\u0000", 2); - if (values.length == 2) try { basilisk.setStoredScores(Integer.parseInt(values[0]), Integer.parseInt(values[1])); } catch (NumberFormatException ignored) { } - } - } - if (currentResult != null && currentResult.data().startsWith("17\u0000") && !currentResult.data().equals(session.antmanResponse)) { - session.antmanResponse = currentResult.data(); - String[] scores = currentResult.data().split("\u0000", 3); - if (scores.length == 3) { - String[] values = scores[2].split("\u0000", 2); - if (values.length == 2) try { antman.setStoredScores(Integer.parseInt(values[0]), Integer.parseInt(values[1])); } catch (NumberFormatException ignored) { } - } - } - if (activeWindow != null && activeWindow.type.equals("GAMES") && activeWindow.gameOpen) { - if (activeWindow.gameId.equals("antman")) antman.tick(); - else if (activeWindow.gameId.equals("basilisk")) basilisk.tick(); - } - } - - @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { - this.renderBackground(graphics, mouseX, mouseY, partialTick); - float scale = uiScale(); - graphics.pose().pushPose(); - graphics.pose().translate(width / 2.0F, height / 2.0F, 0.0F); - graphics.pose().scale(scale, scale, 1.0F); - int left = -WIDTH / 2; - int top = -HEIGHT / 2; - int localMouseX = (int) ((mouseX - width / 2.0F) / scale); - int localMouseY = (int) ((mouseY - height / 2.0F) / scale); - graphics.fill(left - 5, top - 5, left + WIDTH + 5, top + HEIGHT + 5, GREEN); - graphics.fill(left, top, left + WIDTH, top + HEIGHT, BLACK); - graphics.fill(left + 5, top + 5, left + WIDTH - 5, top + HEIGHT - 5, DARK_GREEN); - if (session.bootTicks > 0) renderBoot(graphics, left, top); else if (loggedIn) renderDesktop(graphics, left, top, localMouseX, localMouseY); else renderLogin(graphics, left, top); - graphics.pose().popPose(); - } - - private float uiScale() { - return Math.min(1.0F, Math.min((width - 24.0F) / WIDTH, (height - 24.0F) / HEIGHT)); - } - - private void renderBoot(GuiGraphics g, int l, int t) { - int progress = Math.min(100, (80 - session.bootTicks) * 100 / 80); - int message = Math.min(BOOT_MESSAGES.length - 1, progress * BOOT_MESSAGES.length / 101); - g.drawString(font, Component.literal("ANTINTOSH OS // v" + Antarchy.MOD_VERSION), l + 28, t + 78, GREEN, false); - g.drawString(font, Component.literal("INITIALIZING SYSTEM..."), l + 28, t + 105, PALE_GREEN, false); - g.fill(l + 28, t + 132, l + WIDTH - 28, t + 148, BLACK); - box(g, l + 28, t + 132, l + WIDTH - 28, t + 148, GREEN); - g.fill(l + 32, t + 136, l + 32 + (WIDTH - 64) * progress / 100, t + 144, GREEN); - g.drawString(font, Component.literal(progress + "%"), l + 28, t + 164, GREEN, false); - g.drawString(font, Component.literal(BOOT_MESSAGES[message]), l + 28, t + 190, PALE_GREEN, false); - } - - private void renderLogin(GuiGraphics g, int l, int t) { - g.drawString(font, Component.literal("ANTINTOSH OS // v" + Antarchy.MOD_VERSION), l + 28, t + 25, GREEN, false); - g.drawString(font, Component.literal("BOOT SEQUENCE COMPLETE"), l + 28, t + 43, PALE_GREEN, false); - g.fill(l + 28, t + 59, l + WIDTH - 28, t + 61, GREEN); - ComputerBlockEntity computer = computer(); - boolean setup = (accessResult != null && !accessResult.hasPassword()) || (computer != null && !computer.hasPassword()); - int formX = setup ? l + 110 : l + 242; - int formRight = setup ? l + 330 : l + WIDTH - 28; - g.drawString(font, Component.literal(setup ? "INITIALIZE COMPUTER" : "LOGIN REQUIRED"), formX, t + 105, GREEN, false); - g.drawString(font, Component.literal(setup ? (confirmingPassword ? "CONFIRM PASSWORD" : "CREATE PASSWORD") : "PASSWORD"), formX, t + 132, PALE_GREEN, false); - g.fill(formX, t + 150, formRight, t + 173, BLACK); - box(g, formX, t + 150, formRight, t + 173, GREEN); - g.drawString(font, Component.literal("*".repeat((confirmingPassword ? confirmation : password).length())), formX + 6, t + 157, GREEN, false); - g.drawString(font, Component.literal(setup ? (confirmingPassword ? "[ ENTER ] CONFIRM" : "[ ENTER ] CONTINUE") : "[ ENTER ] LOGIN"), formX, t + 187, GREEN, false); - g.drawString(font, Component.literal("[ ESC ] POWER DOWN"), formX, t + 205, PALE_GREEN, false); - if (loginMessageTicks > 0) wrapLimited(g, loginMessage, formX, t + 232, setup ? 220 : 165, t + HEIGHT - 8, PALE_GREEN); - } - - private void renderDesktop(GuiGraphics g, int l, int t, int mouseX, int mouseY) { - session.lastUse = System.currentTimeMillis(); - session.mouseX = mouseX; - session.mouseY = mouseY; - session.archiveMouseX = mouseX; - session.archiveMouseY = mouseY; - renderWallpaper(g, l, t); - g.fill(l + 9, t + 9, l + WIDTH - 9, t + 30, BLACK); - g.drawString(font, Component.literal("ANTINTOSH OS // v" + Antarchy.MOD_VERSION), l + 18, t + 15, GREEN, false); - long dayTime = Minecraft.getInstance().level == null ? 0L : Minecraft.getInstance().level.getDayTime(); - long dayTicks = Math.floorMod(dayTime, 24000L); - int hours = (int) ((dayTicks / 1000L + 6L) % 24L); - int minutes = (int) (dayTicks % 1000L * 60L / 1000L); - g.drawString(font, Component.literal(String.format("%02d:%02d", hours, minutes)), l + WIDTH - 48, t + 15, PALE_GREEN, false); - g.fill(l + 9, t + 31, l + WIDTH - 9, t + 33, GREEN); - for (int i = 0; i < ICONS.length; i++) { - int x = l + 24 + i % 4 * 94; - int y = t + 48 + i / 4 * 76; - boolean hover = inside(x - 6, y - 6, 76, 57, mouseX, mouseY); - if (hover) g.fill(x - 7, y - 7, x + 69, y + 51, 0xFF173817); - icon(g, ICONS[i], x + 25, y + 2); - if (ICONS[i].equals("ANTMAIL") && antmailHasUnreadMessages()) drawNotificationBadge(g, x + 35, y + 6); - g.drawString(font, Component.literal(ICONS[i]), x, y + 35, GREEN, false); - } - List disks = physicalDisks().stream().filter(id -> !id.getPath().equals("blockle_game")).toList(); - for (int i = 0; i < disks.size() && i < 3; i++) { - int x = l + 24 + (i + 1) * 94; - int y = t + 200 + i / 4 * 54; - icon(g, "DISK", x + 25, y + 2); - String name = disks.get(i).getPath(); - g.drawString(font, Component.literal(name.length() > 12 ? name.substring(0, 12) : name), x, y + 35, GREEN, false); - } - // Commit the desktop before compositing the independent window layers. - g.flush(); - if (activeWindow != null && !activeWindow.minimized && session.windows.remove(activeWindow)) { - session.windows.add(activeWindow); - } - int layer = 1; - for (Window window : session.windows) { - if (!window.minimized) renderWindow(g, window, l, t, mouseX, mouseY, layer++); - } - } - - private boolean antmailHasUnreadMessages() { - AntmailResultPayload result = AntmailClientState.getMailbox(position); - AntmailMailbox mailbox = mailbox(result); - return mailbox != null && mailbox.unreadCount() > 0; - } - - private void drawNotificationBadge(GuiGraphics g, int x, int y) { - String[] circle = { - "....#####....", - "..##+++++##..", - ".#+++++++++#.", - "#+++++++++++#", - "#+++++++++++#", - "#+++++++++++#", - "#+++++++++++#", - "#+++++++++++#", - "#+++++++++++#", - "#+++++++++++#", - ".#+++++++++#.", - "..##+++++##..", - "....#####...." - }; - int badgeFill = GREEN; - for (int row = 0; row < circle.length; row++) { - for (int column = 0; column < circle[row].length(); column++) { - char pixel = circle[row].charAt(column); - if (pixel == '#') g.fill(x - 6 + column, y - 6 + row, x - 5 + column, y - 5 + row, BLACK); - else if (pixel == '+') g.fill(x - 6 + column, y - 6 + row, x - 5 + column, y - 5 + row, badgeFill); - } - } - // Two-pixel stem and a centered two-pixel dot keep the exclamation bold and symmetrical. - g.fill(x - 1, y - 4, x + 1, y + 2, BLACK); - g.fill(x - 1, y + 3, x + 1, y + 5, BLACK); - } - - private void renderWallpaper(GuiGraphics g, int l, int t) { - int left = l + 9; - int top = t + 34; - int right = l + WIDTH - 9; - int bottom = t + HEIGHT - 8; - String wallpaperId = ComputerDesktopState.DEFAULT_WALLPAPER.toString(); - int hash = wallpaperId.hashCode(); - int green = 24 + Math.floorMod(hash, 40); - int blue = 12 + Math.floorMod(hash >>> 8, 24); - int base = 0xFF000000 | (green / 2 << 16) | (green << 8) | blue; - g.fill(left, top, right, bottom, base); - if (wallpaperId.endsWith("grid_ant")) { - for (int py = top + 2; py < bottom; py += 18) { - for (int px = left + 2; px < right; px += 36) { - g.fill(px, py, px + 2, py + 2, 0xFF173817); - } - } - return; - } - int accent = 0xFF000000 | (Math.min(120, green + 34) << 8) | Math.min(80, blue + 34); - int spacing = 18 + Math.floorMod(hash, 13); - int offset = Math.floorMod(hash >>> 16, spacing); - for (int y = top - spacing; y < bottom + spacing; y += spacing) { - int x = left - spacing + offset; - while (x < right) { - int size = 3 + Math.floorMod(x + y + hash, 7); - g.fill(x, y, Math.min(right, x + size), Math.min(bottom, y + 2), accent); - x += spacing * 2; - } - offset = spacing - offset; - } - } - - private String wallpaperName() { - int separator = session.wallpaperId.indexOf(':'); - String name = separator >= 0 ? session.wallpaperId.substring(separator + 1) : session.wallpaperId; - return name.toUpperCase(); - } - - private void icon(GuiGraphics g, String type, int x, int y) { - if (type.equals("ARCHIVE") || type.equals("DISK")) { - // Chunky drive/archive with an inset label window and lower status slot. - g.fill(x - 11, y - 2, x + 11, y + 20, BLACK); - g.fill(x - 8, y + 1, x + 8, y + 16, GREEN); - g.fill(x - 5, y + 3, x + 5, y + 8, BLACK); - g.fill(x - 4, y + 4, x + 4, y + 7, PALE_GREEN); - g.fill(x - 5, y + 11, x + 5, y + 13, BLACK); - g.fill(x + 5, y + 14, x + 7, y + 16, BLACK); - return; - } - if (type.equals("FILES")) { - // Folder silhouette with a clearly outlined tab and a second document peeking out. - g.fill(x - 8, y - 2, x + 9, y + 14, BLACK); - g.fill(x - 5, y + 1, x + 6, y + 11, PALE_GREEN); - g.fill(x - 10, y + 4, x + 11, y + 20, BLACK); - g.fill(x - 7, y + 7, x + 8, y + 17, GREEN); - g.fill(x - 8, y + 4, x - 2, y + 7, GREEN); - g.fill(x - 4, y + 10, x + 5, y + 12, BLACK); - g.fill(x - 4, y + 14, x + 3, y + 16, BLACK); - return; - } - if (type.equals("SETTINGS")) { - // One continuous cog silhouette, with broad square teeth and an open center. - g.fill(x - 4, y - 2, x + 4, y + 22, BLACK); - g.fill(x - 12, y + 6, x + 12, y + 14, BLACK); - g.fill(x - 10, y + 1, x - 5, y + 5, BLACK); - g.fill(x + 5, y + 1, x + 10, y + 5, BLACK); - g.fill(x - 10, y + 15, x - 5, y + 19, BLACK); - g.fill(x + 5, y + 15, x + 10, y + 19, BLACK); - g.fill(x - 2, y, x + 2, y + 20, GREEN); - g.fill(x - 10, y + 8, x + 10, y + 12, GREEN); - g.fill(x - 7, y + 3, x + 7, y + 17, GREEN); - g.fill(x - 3, y + 7, x + 3, y + 13, BLACK); - g.fill(x - 1, y + 9, x + 1, y + 11, PALE_GREEN); - return; - } - if (type.equals("TERMINAL")) { - g.fill(x - 12, y - 1, x + 12, y + 19, BLACK); - g.fill(x - 9, y + 2, x + 9, y + 14, GREEN); - g.fill(x - 6, y + 5, x - 3, y + 8, BLACK); - g.fill(x - 3, y + 8, x + 1, y + 11, BLACK); - g.fill(x - 6, y + 11, x - 3, y + 14, BLACK); - g.fill(x + 3, y + 11, x + 7, y + 13, BLACK); - g.fill(x - 5, y + 16, x + 5, y + 18, BLACK); - return; - } - if (type.equals("TEXT")) { - g.fill(x - 9, y - 2, x + 10, y + 20, BLACK); - g.fill(x - 6, y + 1, x + 7, y + 17, GREEN); - g.fill(x + 4, y + 1, x + 7, y + 4, BLACK); - g.fill(x - 3, y + 5, x + 4, y + 7, BLACK); - g.fill(x - 3, y + 9, x + 4, y + 11, BLACK); - g.fill(x - 3, y + 13, x + 2, y + 15, BLACK); - return; - } - if (type.equals("PAINT")) { - // Squared palette with a true thumb notch and a distinct, outlined brush. - g.fill(x - 11, y + 2, x + 8, y + 20, BLACK); - g.fill(x - 8, y + 5, x + 5, y + 17, GREEN); - g.fill(x - 11, y + 5, x - 8, y + 7, GREEN); - g.fill(x - 6, y + 8, x - 3, y + 11, BLACK); - g.fill(x, y + 7, x + 3, y + 10, BLACK); - g.fill(x - 1, y + 13, x + 2, y + 16, BLACK); - g.fill(x + 6, y - 3, x + 11, y + 1, BLACK); - g.fill(x + 4, y, x + 9, y + 6, BLACK); - g.fill(x + 2, y + 5, x + 7, y + 11, BLACK); - g.fill(x, y + 10, x + 5, y + 16, BLACK); - g.fill(x + 7, y - 1, x + 9, y + 2, PALE_GREEN); - g.fill(x + 5, y + 3, x + 7, y + 7, PALE_GREEN); - g.fill(x + 3, y + 8, x + 5, y + 11, PALE_GREEN); - return; - } - if (type.equals("ANTMAIL")) { - g.fill(x - 12, y + 1, x + 12, y + 18, BLACK); - g.fill(x - 9, y + 4, x + 9, y + 15, GREEN); - // Envelope flap and two symmetric folded corners remain legible at icon scale. - g.fill(x - 9, y + 4, x + 9, y + 6, BLACK); - g.fill(x - 7, y + 6, x - 4, y + 8, BLACK); - g.fill(x + 4, y + 6, x + 7, y + 8, BLACK); - g.fill(x - 4, y + 8, x + 4, y + 10, BLACK); - g.fill(x - 9, y + 11, x - 6, y + 13, BLACK); - g.fill(x + 6, y + 11, x + 9, y + 13, BLACK); - g.fill(x - 6, y + 13, x - 3, y + 15, BLACK); - g.fill(x + 3, y + 13, x + 6, y + 15, BLACK); - return; - } - if (type.equals("GAMES")) { - // Pixel controller with tapered grips, a bold D-pad and paired buttons. - g.fill(x - 7, y + 2, x + 7, y + 5, BLACK); - g.fill(x - 11, y + 5, x + 11, y + 15, BLACK); - g.fill(x - 9, y + 15, x - 5, y + 19, BLACK); - g.fill(x + 5, y + 15, x + 9, y + 19, BLACK); - g.fill(x - 8, y + 5, x + 8, y + 13, GREEN); - g.fill(x - 7, y + 8, x - 1, y + 10, BLACK); - g.fill(x - 5, y + 6, x - 3, y + 12, BLACK); - g.fill(x + 3, y + 7, x + 5, y + 9, BLACK); - g.fill(x + 6, y + 10, x + 8, y + 12, BLACK); - return; - } - if (type.equals("TRASH")) { - g.fill(x - 8, y + 3, x + 8, y + 20, BLACK); - g.fill(x - 11, y + 1, x + 11, y + 4, BLACK); - g.fill(x - 5, y - 1, x + 5, y + 1, BLACK); - g.fill(x - 6, y + 4, x + 6, y + 18, GREEN); - g.fill(x - 3, y + 7, x - 1, y + 16, BLACK); - g.fill(x + 2, y + 7, x + 4, y + 16, BLACK); - return; - } - g.fill(x - 10, y, x + 10, y + 18, BLACK); - g.fill(x - 8, y + 2, x + 8, y + 16, GREEN); - } - - private void renderWindow(GuiGraphics g, Window window, int l, int t, int mouseX, int mouseY, int layer) { - g.flush(); - g.pose().pushPose(); - g.pose().translate(0.0F, 0.0F, layer * 10.0F); - try { - renderWindowLayer(g, window, l, t, mouseX, mouseY); - } finally { - g.flush(); - g.pose().popPose(); - } - } - - private void renderWindowLayer(GuiGraphics g, Window window, int l, int t, int mouseX, int mouseY) { - if (!window.maximized) { - window.x = Math.max(12, Math.min(WIDTH - window.width - 12, window.x)); - window.y = Math.max(34, Math.min(HEIGHT - window.height - 12, window.y)); - } - int x = l + windowLocalX(window); - int y = t + windowLocalY(window); - int w = windowWidth(window); - int h = windowHeight(window); - window.renderWidth = w; - window.renderHeight = h; - g.fill(x - 2, y - 2, x + w + 2, y + h + 2, GREEN); - g.fill(x, y, x + w, y + h, BLACK); - g.fill(x, y, x + w, y + TITLE_BAR_HEIGHT, 0xFF173817); - int controlsLeft = x + w - WINDOW_CONTROL_WIDTH * WINDOW_CONTROL_COUNT; - g.drawString(font, Component.literal(trimToWidth(window.title, Math.max(1, controlsLeft - x - 12))), x + 7, y + 6, GREEN, false); - g.fill(controlsLeft, y, x + w, y + TITLE_BAR_HEIGHT, 0xFF173817); - g.fill(controlsLeft, y, controlsLeft + 1, y + TITLE_BAR_HEIGHT, GREEN); - g.fill(controlsLeft + WINDOW_CONTROL_WIDTH, y, controlsLeft + WINDOW_CONTROL_WIDTH + 1, y + TITLE_BAR_HEIGHT, GREEN); - g.fill(controlsLeft + WINDOW_CONTROL_WIDTH * 2, y, controlsLeft + WINDOW_CONTROL_WIDTH * 2 + 1, y + TITLE_BAR_HEIGHT, GREEN); - g.drawCenteredString(font, Component.literal("_"), controlsLeft + WINDOW_CONTROL_WIDTH / 2, y + 5, PALE_GREEN); - g.drawCenteredString(font, Component.literal(window.maximized ? "❐" : "□"), controlsLeft + WINDOW_CONTROL_WIDTH + WINDOW_CONTROL_WIDTH / 2, y + 5, PALE_GREEN); - g.drawCenteredString(font, Component.literal("X"), controlsLeft + WINDOW_CONTROL_WIDTH * 2 + WINDOW_CONTROL_WIDTH / 2, y + 6, GREEN); - int cx = x + 8; - int cy = y + 28; - enableComputerScissor(g, x + 1, y + TITLE_BAR_HEIGHT, x + w - 1, y + h - 1); - try { - if (window.type.equals("ARCHIVE")) renderArchive(g, cx, cy, w - 16, h - 34, window.maximized); - else if (window.type.equals("FILES")) renderFileExplorer(g, cx, cy, w - 16, h - 34); - else if (window.type.equals("SETTINGS")) renderSettings(g, cx, cy, h - 34); - else if (window.type.equals("TERMINAL")) renderTerminal(g, cx, cy, h - 34); - else if (window.type.equals("TEXT")) renderTextEditor(g, cx, cy, w - 16, h - 34); - else if (window.type.equals("PAINT")) renderPaint(g, cx, cy, w - 16, h - 34); - else if (window.type.equals("ANTMAIL")) renderAntmail(g, cx, cy, h - 34); - else if (window.type.equals("GAMES")) renderGames(g, window, cx, cy, mouseX, mouseY); - else renderTrash(g, cx, cy); - } finally { - g.disableScissor(); - } - } - - private void enableComputerScissor(GuiGraphics g, int left, int top, int right, int bottom) { - float scale = uiScale(); - int screenLeft = (int) Math.floor(width / 2.0F + left * scale); - int screenTop = (int) Math.floor(height / 2.0F + top * scale); - int screenRight = (int) Math.ceil(width / 2.0F + right * scale); - int screenBottom = (int) Math.ceil(height / 2.0F + bottom * scale); - g.enableScissor(screenLeft, screenTop, screenRight, screenBottom); - } - - private static int windowLocalX(Window window) { return window.maximized ? 14 : window.x; } - private static int windowLocalY(Window window) { return window.maximized ? 34 : window.y; } - private static int windowWidth(Window window) { return window.maximized ? WIDTH - 28 : window.width; } - private static int windowHeight(Window window) { return window.maximized ? HEIGHT - 48 : window.height; } - - private static void toggleMaximized(Window window) { - if (window.maximized) { - window.maximized = false; - window.x = window.restoreX; - window.y = window.restoreY; - } else { - window.restoreX = window.x; - window.restoreY = window.y; - window.maximized = true; - } - } - - private void renderArchive(GuiGraphics g, int x, int y, int w, int h, boolean maximized) { - List entries = List.of(); - if (Minecraft.getInstance().level != null && Minecraft.getInstance().level.getBlockEntity(position) instanceof ComputerBlockEntity computer) entries = ComputerGuideData.entriesFor(computer.diskIds()); - - ComputerGuideData.Entry selected = null; - if (session.archiveEntryId != null) { - selected = entries.stream().filter(entry -> entry.id().equals(session.archiveEntryId)).findFirst().orElse(null); - if (selected == null) session.archiveEntryId = null; - } - - if (selected != null) { - g.drawString(font, Component.literal("< BACK // RECOVERED FILES"), x, y, GREEN, false); - g.fill(x, y + 16, x + w, y + 18, GREEN); - g.drawString(font, Component.literal(trimToWidth(Component.translatable(selected.titleKey()).getString(), w)), x, y + 27, GREEN, false); - int contentBottom = y + h - 20; - enableComputerScissor(g, x, y + 36, x + w, contentBottom); - int line = y + 43 - session.archiveDetailScroll * 11; - line = wrap(g, selected.type().toUpperCase() + " // " + selected.category().toUpperCase(), x, line, w, PALE_GREEN) + 5; - if (!selected.entityId().isBlank()) line = renderArchivePreview(g, "", selected.entityId(), "", x, line, w, selected.rotation(), selected.renderScale()) + 2; - for (String descriptionPart : selected.descriptionKeys()) { - line = renderArchiveDescriptionPart(g, descriptionPart, x, line, w); - } - if (!selected.itemId().isBlank()) line = renderArchivePreview(g, selected.itemId(), "", "", x, line, w) + 2; - if (!selected.enchantmentId().isBlank()) line = renderArchivePreview(g, "", "", selected.enchantmentId(), x, line, w) + 2; - if (!selected.recipeId().isBlank()) line = renderArchiveRecipe(g, selected.recipeId(), x, line, w) + 2; - if (!selected.structureId().isBlank()) { - line = wrap(g, "STRUCTURE // " + selected.structureId(), x, line, w, PALE_GREEN) + 2; - line = wrap(g, com.craisinlord.antarchy.content.client.ComputerStructureLocatorClientState.get(position), x, line, w, GREEN) + 2; - } - if (!selected.dimensionId().isBlank()) line = wrap(g, "DIMENSION // " + selected.dimensionId(), x, line, w, PALE_GREEN); - g.disableScissor(); - session.archiveDetailMaxScroll = Math.max(0, (line + session.archiveDetailScroll * 11 - contentBottom + 10) / 11); - session.archiveDetailScroll = Math.min(session.archiveDetailScroll, session.archiveDetailMaxScroll); - if (session.archiveDetailMaxScroll > 0) g.drawString(font, Component.literal("SCROLL " + session.archiveDetailScroll + "/" + session.archiveDetailMaxScroll), x + w - 82, y + h - 12, PALE_GREEN, false); - g.drawString(font, Component.literal("[ ESC ] BACK"), x, y + h - 12, PALE_GREEN, false); - return; - } - - List filteredEntries = filterArchiveEntries(entries); - g.drawString(font, Component.literal("RECOVERED FILES // " + filteredEntries.size() + "/" + entries.size()), x, y, GREEN, false); - g.fill(x, y + 14, x + w - 8, y + 35, BLACK); - box(g, x, y + 14, x + w - 8, y + 35, session.archiveSearchFocused ? GREEN : PALE_GREEN); - String searchText = session.archiveSearch.isBlank() && !session.archiveSearchFocused ? "SEARCH TITLE" : session.archiveSearch; - g.drawString(font, Component.literal(trimToWidth(searchText + (session.archiveSearchFocused ? "_" : ""), w - 16)), x + 6, y + 20, - session.archiveSearch.isBlank() ? PALE_GREEN : GREEN, false); - if (entries.isEmpty()) { - g.drawString(font, Component.literal("NO ARCHIVE DATA"), x, y + 28, PALE_GREEN, false); - return; - } - if (filteredEntries.isEmpty()) { - g.drawString(font, Component.literal("NO MATCHING ENTRIES"), x, y + 52, PALE_GREEN, false); - return; - } - int columns = maximized ? 3 : 1; - int cellHeight = maximized ? 72 : 38; - int thumbnailSize = maximized ? 44 : 28; - int listTop = y + 40; - int visibleRows = Math.max(1, (h - 58) / cellHeight); - int totalRows = (filteredEntries.size() + columns - 1) / columns; - int startRow = Math.max(0, Math.min(session.archiveScroll, Math.max(0, totalRows - visibleRows))); - for (int rowIndex = startRow; rowIndex < totalRows && rowIndex < startRow + visibleRows; rowIndex++) { - int rowTop = listTop + (rowIndex - startRow) * cellHeight; - for (int column = 0; column < columns; column++) { - int index = rowIndex * columns + column; - if (index >= filteredEntries.size()) break; - ComputerGuideData.Entry entry = filteredEntries.get(index); - int cellWidth = (w - 8) / columns; - int cellX = x + column * cellWidth; - int thumbX = maximized ? cellX + (cellWidth - thumbnailSize) / 2 : cellX + 3; - int thumbY = maximized ? rowTop + 2 : rowTop + 4; - int textX = maximized ? cellX + 3 : cellX + thumbnailSize + 10; - int textY = maximized ? rowTop + thumbnailSize + 5 : rowTop + 7; - boolean hover = inside(cellX, rowTop, cellWidth - 2, cellHeight - 2, session.archiveMouseX, session.archiveMouseY); - if (hover) g.fill(cellX, rowTop, cellX + cellWidth - 2, rowTop + cellHeight - 2, 0xFF173817); - g.fill(thumbX, thumbY, thumbX + thumbnailSize, thumbY + thumbnailSize, BLACK); - renderThumbnail(g, entry, thumbX + thumbnailSize / 2, thumbY + thumbnailSize / 2, hover, thumbnailSize); - int textWidth = maximized ? cellWidth - 8 : cellWidth - thumbnailSize - 12; - g.drawString(font, Component.literal(trimToWidth(Component.translatable(entry.titleKey()).getString(), textWidth)), textX, textY, GREEN, false); - g.drawString(font, Component.literal(trimToWidth(entry.category().toUpperCase(), textWidth)), textX, textY + 12, PALE_GREEN, false); - } - } - int shownStart = startRow * columns; - int shownEnd = Math.min(filteredEntries.size(), (startRow + visibleRows) * columns); - if (totalRows > visibleRows) g.drawString(font, Component.literal("SCROLL " + (shownStart + 1) + "-" + shownEnd + " / " + filteredEntries.size()), x, y + h - 12, PALE_GREEN, false); - else g.drawString(font, Component.literal("[ CLICK ENTRY TO OPEN ]"), x, y + h - 12, PALE_GREEN, false); - } - - private List filterArchiveEntries(List entries) { - String query = session.archiveSearch.trim().toLowerCase(Locale.ROOT); - if (query.isEmpty()) return entries; - return entries.stream().filter(entry -> Component.translatable(entry.titleKey()).getString().toLowerCase(Locale.ROOT).contains(query)).toList(); - } - - private void renderThumbnail(GuiGraphics g, ComputerGuideData.Entry entry, int centerX, int centerY, boolean hover, int size) { - int background = hover ? 0xFF173817 : 0xFF102010; - g.fill(centerX - size / 2, centerY - size / 2, centerX + size / 2, centerY + size / 2, background); - if (!entry.recipeId().isBlank() && renderArchiveRecipe(g, entry.recipeId(), centerX - size / 2, centerY - size / 2 + size / 5, size, Math.max(6, size / 4))) return; - String itemId = entry.coverItemId().isBlank() ? entry.itemId() : entry.coverItemId(); - String entityId = entry.coverEntityId().isBlank() ? entry.entityId() : entry.coverEntityId(); - if (!renderArchiveAsset(g, itemId, entityId, entry.enchantmentId(), entry.coverPotionId(), centerX, centerY, size, entry.rotation(), entry.renderScale())) { - String fallback = !itemId.isBlank() ? itemId : !entry.enchantmentId().isBlank() ? entry.enchantmentId() : entityId; - g.drawString(font, Component.literal(trimToWidth(fallback.isBlank() ? "NO RENDER" : fallback, size - 4)), centerX - size / 2 + 2, centerY - 4, hover ? GREEN : PALE_GREEN, false); - } - } - - private int renderArchiveDescriptionPart(GuiGraphics g, String part, int x, int y, int w) { - if (part.startsWith("@item:")) return renderArchivePreview(g, part.substring(6), "", "", x, y, w) + 2; - if (part.startsWith("@entity:")) return renderArchivePreview(g, "", part.substring(8), "", x, y, w) + 2; - if (part.startsWith("@enchantment:")) return renderArchivePreview(g, "", "", part.substring(13), x, y, w) + 2; - if (part.startsWith("@recipe:")) return renderArchiveRecipe(g, part.substring(8), x, y, w) + 2; - return wrap(g, Component.translatable(part), x, y, w, GREEN) + 3; - } - - private int renderArchiveRecipe(GuiGraphics g, String recipeId, int x, int y, int w) { - int slot = 16; - int recipeWidth = slot * 3 + 24; - if (!renderArchiveRecipe(g, recipeId, x, y, Math.min(w, recipeWidth), slot)) { - return wrap(g, "RECIPE // " + recipeId, x, y, w, PALE_GREEN); - } - return y + slot * 3; - } - - private boolean renderArchiveRecipe(GuiGraphics g, String recipeId, int x, int y, int width, int slot) { - if (Minecraft.getInstance().level == null) return false; - try { - var recipeManager = Minecraft.getInstance().level.getRecipeManager(); - ResourceLocation requestedId = ResourceLocation.parse(recipeId); - RecipeHolder holder = recipeManager.byKey(requestedId).orElse(null); - if (holder == null) { - var requestedItem = BuiltInRegistries.ITEM.getOptional(requestedId).orElse(null); - if (requestedItem != null && requestedItem != Items.AIR) { - holder = recipeManager.getRecipes().stream() - .filter(candidate -> candidate.value().getResultItem(Minecraft.getInstance().level.registryAccess()).is(requestedItem)) - .findFirst().orElse(null); - } - } - if (holder == null) return false; - var recipe = holder.value(); - List ingredients = recipe.getIngredients(); - int actualSlot = Math.min(slot, Math.max(4, (width - 8) / 4)); - int gridWidth = actualSlot * 3; - int outputX = x + gridWidth + 8; - int outputY = y + actualSlot; - int shapedWidth = recipe instanceof ShapedRecipe shaped ? shaped.getWidth() : 3; - int shapedHeight = recipe instanceof ShapedRecipe shaped ? shaped.getHeight() : Math.min(3, (ingredients.size() + 2) / 3); - for (int index = 0; index < 9; index++) { - int column = index % 3; - int row = index / 3; - int cellX = x + column * actualSlot; - int cellY = y + row * actualSlot; - g.fill(cellX, cellY, cellX + actualSlot - 1, cellY + actualSlot - 1, 0xFF173817); - int ingredientIndex = recipe instanceof ShapedRecipe - ? (column < shapedWidth && row < shapedHeight ? row * shapedWidth + column : -1) - : index; - if (ingredientIndex >= 0 && ingredientIndex < ingredients.size()) { - ItemStack[] choices = ingredients.get(ingredientIndex).getItems(); - if (choices.length > 0) renderArchiveItem(g, choices[0], cellX, cellY, actualSlot); - } - } - g.fill(x + gridWidth + 2, y + actualSlot + actualSlot / 2 - 1, x + gridWidth + 6, y + actualSlot + actualSlot / 2 + 1, PALE_GREEN); - g.fill(x + gridWidth + 5, y + actualSlot + actualSlot / 2 - 3, x + gridWidth + 7, y + actualSlot + actualSlot / 2 + 3, PALE_GREEN); - ItemStack result = recipe.getResultItem(Minecraft.getInstance().level.registryAccess()); - if (!result.isEmpty()) { - g.fill(outputX, outputY, outputX + actualSlot - 1, outputY + actualSlot - 1, 0xFF173817); - renderArchiveItem(g, result, outputX, outputY, actualSlot); - } - return true; - } catch (RuntimeException exception) { - logArchivePreviewOnce("recipe.error." + recipeId, "Archive recipe preview failed id={} error={}", recipeId, exception.toString()); - return false; - } - } - - private int renderArchivePreview(GuiGraphics g, String itemId, String entityId, String enchantmentId, int x, int y, int w) { - return renderArchivePreview(g, itemId, entityId, enchantmentId, x, y, w, 0.0F, 1.0F); - } - - private int renderArchivePreview(GuiGraphics g, String itemId, String entityId, String enchantmentId, int x, int y, int w, float rotation) { - return renderArchivePreview(g, itemId, entityId, enchantmentId, x, y, w, rotation, 1.0F); - } - - private int renderArchivePreview(GuiGraphics g, String itemId, String entityId, String enchantmentId, int x, int y, int w, float rotation, float renderScale) { - int previewSize = entityId.isBlank() ? 48 : 96; - int boxWidth = Math.min(previewSize, w); - g.fill(x, y, x + boxWidth, y + previewSize, 0xFF102010); - int centerX = x + boxWidth / 2; - int centerY = y + previewSize / 2; - if (!renderArchiveAsset(g, itemId, entityId, enchantmentId, "", centerX, centerY, boxWidth, rotation, renderScale)) { - String fallback = !itemId.isBlank() ? itemId : !enchantmentId.isBlank() ? enchantmentId : entityId; - g.drawString(font, Component.literal(trimToWidth(fallback, Math.max(1, w - boxWidth - 6))), x + boxWidth + 6, y + previewSize / 2 - 4, PALE_GREEN, false); - } else if (!itemId.isBlank() || !entityId.isBlank() || !enchantmentId.isBlank()) { - String label = !itemId.isBlank() ? "ITEM // " + itemId - : !enchantmentId.isBlank() ? "ENCHANTMENT // " + enchantmentId : "MOB // " + archiveMobName(entityId); - g.drawString(font, Component.literal(trimToWidth(label, Math.max(1, w - boxWidth - 6))), x + boxWidth + 6, y + previewSize / 2 - 4, PALE_GREEN, false); - } - return y + previewSize; - } - - private String archiveMobName(String entityId) { - int separator = entityId.indexOf(':'); - return (separator >= 0 ? entityId.substring(separator + 1) : entityId).replace('_', ' ').toUpperCase(Locale.ROOT); - } - - private boolean renderArchiveAsset(GuiGraphics g, String itemId, String entityId, String enchantmentId, String potionId, int centerX, int centerY, int size, float rotation, float renderScale) { - if (!itemId.isBlank()) { - try { - ResourceLocation resourceId = ResourceLocation.parse(itemId); - var item = BuiltInRegistries.ITEM.getOptional(resourceId).orElse(null); - logArchivePreviewOnce("item.lookup." + itemId, "Archive item preview lookup id={} found={} registryName={}", itemId, item != null, item == null ? "" : BuiltInRegistries.ITEM.getKey(item)); - if (item != null && !item.equals(net.minecraft.world.item.Items.AIR)) { - ItemStack stack = new ItemStack(item); - int iconSize = Math.min(32, Math.max(16, size - 4)); - renderArchiveItem(g, stack, centerX - iconSize / 2, centerY - iconSize / 2, iconSize); - logArchivePreviewOnce("item.render." + itemId, "Archive item preview rendered id={} descriptionId={} center=({}, {})", itemId, stack.getDescriptionId(), centerX, centerY); - return true; - } - logArchivePreviewOnce("item.unrenderable." + itemId, "Archive item preview unavailable id={} (missing or AIR)", itemId); - } catch (RuntimeException exception) { - logArchivePreviewOnce("item.error." + itemId, "Archive item preview failed id={} error={}", itemId, exception.toString()); - } - } - if (!enchantmentId.isBlank()) { - ItemStack stack = createArchiveEnchantedBook(enchantmentId); - if (!stack.isEmpty()) { - int iconSize = Math.min(32, Math.max(16, size - 4)); - renderArchiveItem(g, stack, centerX - iconSize / 2, centerY - iconSize / 2, iconSize); - logArchivePreviewOnce("enchantment.render." + enchantmentId, "Archive enchantment preview rendered id={}", enchantmentId); - return true; - } - logArchivePreviewOnce("enchantment.unrenderable." + enchantmentId, "Archive enchantment preview unavailable id={}", enchantmentId); - } - if (!potionId.isBlank() && Minecraft.getInstance().level != null) { - try { - ResourceLocation potionLocation = ResourceLocation.parse(potionId); - ResourceKey potionKey = ResourceKey.create(Registries.POTION, potionLocation); - var potion = Minecraft.getInstance().level.registryAccess().lookupOrThrow(Registries.POTION).get(potionKey).orElse(null); - if (potion != null) { - int iconSize = Math.min(32, Math.max(16, size - 4)); - renderArchiveItem(g, PotionContents.createItemStack(Items.POTION, potion), centerX - iconSize / 2, centerY - iconSize / 2, iconSize); - return true; - } - } catch (RuntimeException exception) { - logArchivePreviewOnce("potion.error." + potionId, "Archive potion preview failed id={} error={}", potionId, exception.toString()); - } - } - if (!entityId.isBlank() && Minecraft.getInstance().level == null) { - logArchivePreviewOnce("entity.no_level." + entityId, "Archive mob preview skipped id={} because the client level is null", entityId); - } - if (!entityId.isBlank() && Minecraft.getInstance().level != null) { - try { - ResourceLocation resourceId = ResourceLocation.parse(entityId); - var entityType = BuiltInRegistries.ENTITY_TYPE.getOptional(resourceId).orElse(null); - logArchivePreviewOnce("entity.lookup." + entityId, "Archive mob preview lookup id={} found={} registryName={}", entityId, entityType != null, entityType == null ? "" : BuiltInRegistries.ENTITY_TYPE.getKey(entityType)); - LivingEntity living = archiveEntityPreviews.get(entityId); - if (living == null && entityType != null && !unavailableArchiveEntities.contains(entityId)) { - var entity = entityType.create(Minecraft.getInstance().level); - if (entity instanceof LivingEntity created && !created.isRemoved()) { - living = created; - archiveEntityPreviews.put(entityId, created); - } else { - unavailableArchiveEntities.add(entityId); - logArchivePreviewOnce("entity.unrenderable." + entityId, "Archive mob preview unavailable id={} createdClass={} isLiving={}", entityId, entity == null ? "" : entity.getClass().getName(), entity instanceof LivingEntity); - } - } - if (living != null && !living.isRemoved()) { - if (living instanceof NightmareEntity nightmare) nightmare.setArchivePreviewFlying(); - living.setPos(0.0D, 0.0D, 0.0D); - float yaw = 180.0F + rotation; - living.setYRot(yaw); - living.yRotO = yaw; - living.yBodyRot = yaw; - living.yBodyRotO = yaw; - living.yHeadRot = yaw; - living.yHeadRotO = yaw; - living.tickCount = (int) (Minecraft.getInstance().level.getGameTime() & Integer.MAX_VALUE); - float largestDimension = Math.max(0.45F, Math.max(living.getBbWidth(), living.getBbHeight())); - // Leave room for wide silhouettes and configured yaw rotations (notably the flying squirrel). - int entityRenderScale = Math.max(4, Math.min(size, Math.round(size * 0.52F * renderScale / largestDimension))); - float entityScale = Math.max(0.01F, living.getScale()); - Vector3f translation = new Vector3f(0.0F, living.getBbHeight() / 2.0F + 0.0625F * entityScale, 0.0F); - Quaternionf pose = new Quaternionf().rotateZ((float) Math.PI); - Quaternionf camera = new Quaternionf(); - g.flush(); - enableComputerScissor(g, centerX - size / 2, centerY - size / 2, centerX + size / 2, centerY + size / 2); - g.setColor(0.0F, 1.0F, 0.0F, 1.0F); - try { - InventoryScreen.renderEntityInInventory(g, centerX, centerY, entityRenderScale / entityScale, - translation, pose, camera, living); - g.flush(); - } finally { - g.setColor(1.0F, 1.0F, 1.0F, 1.0F); - g.disableScissor(); - } - logArchivePreviewOnce("entity.render." + entityId, "Archive mob preview rendered id={} class={} size={} center=({}, {})", entityId, living.getClass().getName(), size, centerX, centerY); - return true; - } - } catch (RuntimeException exception) { - logArchivePreviewOnce("entity.error." + entityId, "Archive mob preview failed id={} error={}", entityId, exception.toString()); - } - } - return false; - } - - private void renderArchiveItem(GuiGraphics g, ItemStack stack, int x, int y) { - renderArchiveItem(g, stack, x, y, 16); - } - - private void renderArchiveItem(GuiGraphics g, ItemStack stack, int x, int y, int size) { - g.flush(); - // Keep only the green channel, matching the archive mob treatment and preventing source hues from bleeding through. - g.setColor(0.0F, 1.0F, 0.0F, 1.0F); - g.pose().pushPose(); - try { - g.pose().translate(x, y, 0.0F); - float scale = size / 16.0F; - g.pose().scale(scale, scale, 1.0F); - g.renderItem(stack, 0, 0); - g.flush(); - } finally { - g.pose().popPose(); - g.setColor(1.0F, 1.0F, 1.0F, 1.0F); - } - } - - private ItemStack createArchiveEnchantedBook(String enchantmentId) { - if (Minecraft.getInstance().level == null) return ItemStack.EMPTY; - try { - ResourceLocation id = ResourceLocation.parse(enchantmentId); - ResourceKey key = ResourceKey.create(Registries.ENCHANTMENT, id); - var holder = Minecraft.getInstance().level.registryAccess().lookupOrThrow(Registries.ENCHANTMENT).get(key).orElse(null); - if (holder == null) return ItemStack.EMPTY; - ItemEnchantments.Mutable enchantments = new ItemEnchantments.Mutable(ItemEnchantments.EMPTY); - enchantments.set(holder, 1); - ItemStack stack = new ItemStack(Items.ENCHANTED_BOOK); - stack.set(DataComponents.STORED_ENCHANTMENTS, enchantments.toImmutable().withTooltip(true)); - return stack; - } catch (RuntimeException exception) { - logArchivePreviewOnce("enchantment.error." + enchantmentId, "Archive enchantment preview failed id={} error={}", enchantmentId, exception.toString()); - return ItemStack.EMPTY; - } - } - - private void logArchivePreviewOnce(String key, String message, Object... arguments) { - if (archiveRenderLog.add(key)) Antarchy.LOGGER.info(message, arguments); - } - - private void renderFileExplorer(GuiGraphics g, int x, int y, int w, int h) { - var files = ComputerFileSystemClientState.get(position).files(); - g.drawString(font, Component.literal("FILE EXPLORER // " + trimToWidth(session.fileExplorerDirectory, w - 4)), x, y, GREEN, false); - if (!session.fileExplorerDirectory.equals("/")) g.drawString(font, Component.literal("[ UP ]"), x + w - 40, y, GREEN, false); - g.drawString(font, Component.literal("TYPE PATH SIZE"), x, y + 18, PALE_GREEN, false); - int line = y + 34; - int fileIndex = 0; - for (String file : files) { - String[] fields = file.split("\\t", 3); - if (fields.length < 3 || !isDirectChild(fields[1], session.fileExplorerDirectory)) continue; - if (fileIndex++ < session.fileExplorerScroll || line > y + h - 32) continue; - boolean selected = fields[1].equals(session.fileExplorerSelected); - if (selected) g.fill(x - 3, line - 2, x + w - 3, line + 11, 0xFF173817); - g.drawString(font, Component.literal(fileIcon(fields[0]) + " " + trimToWidth(fields[0], 30)), x, line, PALE_GREEN, false); - g.drawString(font, Component.literal(trimToWidth(fields[1], 112)), x + 42, line, GREEN, false); - g.drawString(font, Component.literal(trimToWidth(fields[2], 28)), x + w - 28, line, PALE_GREEN, false); - line += 14; - } - if (line == y + 34) g.drawString(font, Component.literal("NO FILES // OPEN TERMINAL TO CREATE ONE"), x, y + 38, PALE_GREEN, false); - else { - var state = ComputerFileSystemClientState.get(position); - String footer = session.fileExplorerCreatingDirectory ? "NEW FOLDER: " + session.fileExplorerRename + "_" - : session.fileExplorerMoving ? "MOVE TO PATH: " + session.fileExplorerRename + "_" - : session.fileExplorerRenaming ? "RENAME: " + session.fileExplorerRename + "_" - : session.fileExplorerDeleteConfirm ? "DELETE SELECTED FILE? [ ENTER / ESC ]" : "[ CTRL+N NEW ] [ CTRL+M MOVE ] [ DEL ] [ CTRL+R RENAME ]"; - if (state.lastMutationAction() == com.craisinlord.antarchy.content.network.ComputerAccessPayload.FILE_DELETE - || state.lastMutationAction() == com.craisinlord.antarchy.content.network.ComputerAccessPayload.FILE_MOVE) { - footer += state.lastMutationSuccess() ? " // OK" : " // ERR: " + state.lastMutationError(); - } - g.drawString(font, Component.literal(trimToWidth(footer, w - 4)), x, y + h - 16, PALE_GREEN, false); - } - } - - private String fileIcon(String type) { - return type.equals("DIRECTORY") ? "[D]" : type.equals("TEXT") ? "[T]" : "[I]"; - } - - private boolean isDirectChild(String path, String directory) { - if (path.equals(directory)) return false; - String prefix = directory.equals("/") ? "/" : directory + "/"; - if (!path.startsWith(prefix)) return false; - return path.indexOf('/', prefix.length()) < 0; - } - - private String parentDirectory(String path) { - if (path.equals("/")) return "/"; - int slash = path.lastIndexOf('/'); - return slash <= 0 ? "/" : path.substring(0, slash); - } - - private String trimToWidth(String value, int width) { - if (font.width(value) <= width) return value; - String ellipsis = "..."; - int end = value.length(); - while (end > 0 && font.width(value.substring(0, end) + ellipsis) > width) end--; - return value.substring(0, end) + ellipsis; - } - - private void renderSettings(GuiGraphics g, int x, int y, int h) { - g.drawString(font, Component.literal("SYSTEM STATUS"), x, y, GREEN, false); - g.drawString(font, Component.literal("CPU " + (System.currentTimeMillis() / 100 % 87 + 12) + "%"), x, y + 18, PALE_GREEN, false); - g.drawString(font, Component.literal("MEM " + (System.currentTimeMillis() / 250 % 42 + 31) + "%"), x, y + 32, PALE_GREEN, false); - g.drawString(font, Component.literal("WALLPAPER DEFAULT // LOCKED"), x, y + 46, PALE_GREEN, false); - g.drawString(font, Component.literal("PASSWORD CHANGE IN FULL BUILD"), x, y + 60, GREEN, false); - g.drawString(font, Component.literal("PHYSICAL DISKS"), x, y + 91, GREEN, false); - List disks = physicalDisks(); - if (disks.isEmpty()) { - g.drawString(font, Component.literal("NONE INSTALLED"), x, y + 108, PALE_GREEN, false); - } else { - for (int i = 0; i < disks.size() && i < 3; i++) { - ResourceLocation disk = disks.get(i); - boolean active = disk.equals(selectedDisk); - if (active) g.fill(x - 3, y + 105 + i * 17, x + 205, y + 120 + i * 17, 0xFF173817); - g.drawString(font, Component.literal(trimToWidth(disk.toString(), 202)), x, y + 108 + i * 17, active ? GREEN : PALE_GREEN, false); - } - g.drawString(font, Component.literal("[ EJECT SELECTED ]"), x, y + 162, selectedDisk == null ? 0xFF4A754A : GREEN, false); - } - g.drawString(font, Component.literal("LOG OUT"), x, y + 74, GREEN, false); - } - - private void drawWallpaperPreview(GuiGraphics g, int x, int y, int w, int h, String id) { - int hash = id.hashCode(); - int green = 24 + Math.floorMod(hash, 40); - int blue = 12 + Math.floorMod(hash >>> 8, 24); - int base = 0xFF000000 | (green / 2 << 16) | (green << 8) | blue; - g.fill(x - 1, y - 1, x + w + 1, y + h + 1, GREEN); - g.fill(x, y, x + w, y + h, base); - int accent = 0xFF000000 | (Math.min(120, green + 34) << 8) | Math.min(80, blue + 34); - for (int py = y + 4; py < y + h; py += 9) { - for (int px = x + 4; px < x + w; px += 12) { - if (Math.floorMod(px + py + hash, 3) == 0) g.fill(px, py, Math.min(x + w, px + 3), Math.min(y + h, py + 2), accent); - } - } - } - - private void renderTerminal(GuiGraphics g, int x, int y, int h) { - g.drawString(font, Component.literal("ANTINTOSH TERMINAL [READY]"), x, y, GREEN, false); - int line = y + 17; - for (String output : session.terminalOutput) { - line = wrapLimited(g, output, x, line, 208, y + h - 48, PALE_GREEN) + 1; - if (line >= y + h - 48) break; - } - g.drawString(font, Component.literal(trimToWidth(session.terminalDirectory + "> " + session.terminalInput + "_", 208)), x, y + h - 26, GREEN, false); - } - - private void renderPaint(GuiGraphics g, int x, int y, int w, int h) { - var fileState = ComputerFileSystemClientState.get(position); - if (!session.paintDirty && fileState.openedPath().endsWith(".antpaint") && !fileState.openedContents().isEmpty()) { - try { - AntPaintFile file = AntPaintFileCodec.decode(Base64.getDecoder().decode(fileState.openedContents())); - session.paintName = file.filename(); - session.antmailPaintPath = fileState.openedPath(); - session.paintCanvas = file.canvas().copy(); - } catch (IllegalArgumentException ignored) { - } - } - g.drawString(font, Component.literal(trimToWidth("ANTPAINT // " + session.paintName + (session.paintDirty ? " *" : ""), w)), x, y, GREEN, false); - renderPaintToolbar(g, x, y); - // w and h are already the window's content dimensions; keep rendering in - // lockstep with paintAt(), which receives these same adjusted dimensions. - int canvasHeight = Math.max(1, h - 32); - int size = Math.max(1, Math.min(w / AntPaintCanvas.WIDTH, canvasHeight / AntPaintCanvas.HEIGHT)); - int cx = x + (w - size * AntPaintCanvas.WIDTH) / 2; - int cy = y + 30 + Math.max(0, (canvasHeight - size * AntPaintCanvas.HEIGHT) / 2); - g.fill(cx - 1, cy - 1, cx + size * AntPaintCanvas.WIDTH + 1, cy + size * AntPaintCanvas.HEIGHT + 1, BLACK); - g.fill(cx, cy, cx + size * AntPaintCanvas.WIDTH, cy + size * AntPaintCanvas.HEIGHT, BLACK); - for (int py = 0; py < AntPaintCanvas.HEIGHT; py++) for (int px = 0; px < AntPaintCanvas.WIDTH; px++) if (session.paintCanvas.get(px, py)) g.fill(cx + px * size, cy + py * size, cx + (px + 1) * size, cy + (py + 1) * size, GREEN); - int hoverX = (session.mouseX - cx) / size; - int hoverY = (session.mouseY - cy) / size; - if (session.mouseX >= cx && session.mouseY >= cy && hoverX >= 0 && hoverX < AntPaintCanvas.WIDTH && hoverY >= 0 && hoverY < AntPaintCanvas.HEIGHT) { - int pixelX = cx + hoverX * size; - int pixelY = cy + hoverY * size; - g.fill(pixelX, pixelY, pixelX + size, pixelY + 1, PALE_GREEN); - g.fill(pixelX, pixelY + size - 1, pixelX + size, pixelY + size, PALE_GREEN); - g.fill(pixelX, pixelY, pixelX + 1, pixelY + size, PALE_GREEN); - g.fill(pixelX + size - 1, pixelY, pixelX + size, pixelY + size, PALE_GREEN); - } - } - - private void renderPaintToolbar(GuiGraphics g, int x, int y) { - for (int index = 0; index < 7; index++) { - int buttonX = x + index * 28; - if (index < 3 && ((index == 0 && session.paintTool == AntPaintTool.PENCIL) - || (index == 1 && session.paintTool == AntPaintTool.ERASER) - || (index == 2 && session.paintTool == AntPaintTool.FILL))) { - box(g, buttonX, y + 11, buttonX + 22, y + 28, GREEN); - } - paintToolbarIcon(g, index, buttonX + 11, y + 19); - } - } - - private void paintToolbarIcon(GuiGraphics g, int index, int x, int y) { - String externalIcon = switch (index) { - case 0 -> "pencil"; - case 1 -> "eraser"; - case 3 -> "trash"; - case 4 -> "undo"; - case 5 -> "redo"; - default -> null; - }; - if (externalIcon != null) { - ResourceLocation texture = ResourceLocation.fromNamespaceAndPath( - "antarchy", "textures/gui/antpaint/" + externalIcon + ".png"); - g.blit(texture, x - 9, y - 9, 0, 0, 18, 18, 24, 24); - return; - } - int color = PALE_GREEN; - String[][] sprites = { - // Pencil: graphite point at lower-left, long barrel, and capped eraser at upper-right. - { - ".............##.", - "............####", - "...........##++#", - "..........##+++##", - ".........##+++##.", - "........##+++##..", - ".......##+++##...", - "......##+++##....", - ".....##+++##.....", - "....##+++##......", - "...##+++##.......", - "..##+++##........", - ".##++##..........", - ".####............", - "..##.............", - "...t............." - }, - // Eraser: angled block with a contrasting paper edge and colored rubber. - { - "................", - "...........####.", - ".........###++##", - ".......###+++##.", - ".....###+++##...", - "...###+++##.....", - ".###+++##.......", - "##+++###........", - "#++###...........", - "####.............", - "................", - "................", - "................", - "................", - "................", - "................" - }, - // Bucket: pale arched handle, wide rim, tapered body, and visible paint. - { - "....######......", - "...##....##.....", - "..##......##....", - "..#........#....", - ".#############..", - ".#+++++++++++##.", - ".#++gggggg+++##.", - ".#+++++++++++##.", - "..#+++++++++##..", - "..##++++++++##..", - "...##++++++##...", - "...##++++++##...", - "....########....", - "................", - "................", - "................" - }, - // Clear: trash bin with lid and vertical slats. - { - ".....######.....", - "...##########...", - "....##.##.##....", - "..############..", - "..##++++++++##..", - "..##++##++##++##.", - "..##++##++##++##.", - "..##++##++##++##.", - "...##++++++++##..", - "...############..", - "....##......##...", - "................", - "................", - "................", - "................", - "................" - }, - // Undo: left-facing hooked arrow. - { - "......####......", - "................", - "................", - "....##..........", - "...####.........", - "..##++##........", - ".##++++##.......", - "##++++++++++##..", - ".##++++##.......", - "..##++##........", - "...####.........", - "....##..........", - "................", - "................", - "................", - "................" - }, - // Redo: right-facing hooked arrow, mirrored at render time. - { - "......####......", - "................", - "................", - "....##..........", - "...####.........", - "..##++##........", - ".##++++##.......", - "##++++++++++##..", - ".##++++##.......", - "..##++##........", - "...####.........", - "....##..........", - "................", - "................", - "................", - "................" - }, - // Save icon intentionally retained. - { - ".#############.", - "#+++++++++++++#", - "#++#####++++++#", - "#++#...#++++++#", - "#++#...#++++++#", - "#++#####++++++#", - "#+++++++++++++#", - "#++#########++#", - "#++#+++++++#++#", - "#++#++gg+++#++#", - "#++#+++++++#++#", - "#++#########++#", - "#+++++++++++++#", - ".#############.", - "..............." - } - }; - String[] sprite = sprites[Math.max(0, Math.min(index, sprites.length - 1))]; - if (index == 5) { - sprite = sprite.clone(); - for (int row = 0; row < sprite.length; row++) { - sprite[row] = new StringBuilder(sprite[row].substring(0, Math.min(16, sprite[row].length()))).reverse().toString(); - } - } - for (int row = 0; row < 16; row++) { - String line = row < sprite.length ? sprite[row] : ""; - if (line.length() > 16) line = line.substring(0, 16); - for (int column = 0; column < 16; column++) { - char pixel = column < line.length() ? line.charAt(column) : '.'; - if (pixel != '#' && pixel != '+' && pixel != 'g' && pixel != 't') continue; - for (int[] offset : new int[][]{{0, -1}, {0, 1}, {-1, 0}, {1, 0}}) { - int dx = offset[0]; - int dy = offset[1]; - int nx = column + dx; - int ny = row + dy; - if (nx < 0 || nx >= 16 || ny < 0 || ny >= 16) continue; - String neighborLine = ny < sprite.length ? sprite[ny] : ""; - char neighbor = nx < neighborLine.length() ? neighborLine.charAt(nx) : '.'; - if (neighbor == '.' || neighbor == ' ') g.fill(x - 8 + nx, y - 8 + ny, x - 7 + nx, y - 7 + ny, 0xFF78A878); - } - } - } - for (int row = 0; row < 16; row++) { - String line = row < sprite.length ? sprite[row] : ""; - for (int column = 0; column < 16; column++) { - char pixel = column < line.length() ? line.charAt(column) : '.'; - if (pixel == '#') g.fill(x - 8 + column, y - 8 + row, x - 7 + column, y - 7 + row, BLACK); - else if (pixel == '+') g.fill(x - 8 + column, y - 8 + row, x - 7 + column, y - 7 + row, color); - else if (pixel == 'g') g.fill(x - 8 + column, y - 8 + row, x - 7 + column, y - 7 + row, GREEN); - else if (pixel == 't') g.fill(x - 8 + column, y - 8 + row, x - 7 + column, y - 7 + row, 0xFF657465); - } - } - } - - private void paintToolbarIconLegacy(GuiGraphics g, int index, int x, int y) { - int color = PALE_GREEN; - if (index == 0) { - // Pencil: a full diagonal silhouette with graphite, wood, painted barrel, ferrule, and eraser. - g.fill(x - 9, y + 4, x - 5, y + 8, BLACK); - g.fill(x - 7, y + 2, x - 3, y + 7, BLACK); - g.fill(x - 5, y, x + 3, y + 6, BLACK); - g.fill(x - 2, y - 3, x + 6, y + 3, BLACK); - g.fill(x + 4, y - 6, x + 8, y - 1, BLACK); - g.fill(x - 8, y + 5, x - 6, y + 7, color); - g.fill(x - 6, y + 3, x - 4, y + 5, color); - g.fill(x - 4, y + 1, x - 2, y + 3, color); - g.fill(x - 2, y - 1, x + 1, y + 2, color); - g.fill(x + 1, y - 3, x + 4, y, color); - g.fill(x + 4, y - 5, x + 6, y - 2, color); - g.fill(x - 4, y + 3, x - 2, y + 5, GREEN); - g.fill(x - 2, y + 1, x + 1, y + 3, GREEN); - g.fill(x + 1, y - 1, x + 4, y + 1, GREEN); - g.fill(x + 3, y - 4, x + 6, y - 2, BLACK); - g.fill(x + 5, y - 6, x + 8, y - 4, BLACK); - g.fill(x + 5, y - 4, x + 7, y - 2, color); - } else if (index == 1) { - // Eraser: large rotated block with a paper edge, center band, shadow, and shine. - g.fill(x - 9, y - 3, x + 5, y + 7, BLACK); - g.fill(x - 6, y - 6, x + 8, y + 4, BLACK); - g.fill(x - 7, y - 2, x - 2, y + 3, color); - g.fill(x - 4, y - 4, x + 2, y + 1, color); - g.fill(x - 1, y - 5, x + 5, y, color); - g.fill(x - 9, y + 4, x + 3, y + 8, BLACK); - g.fill(x - 7, y + 4, x - 1, y + 6, color); - g.fill(x - 6, y - 1, x - 3, y + 2, PALE_GREEN); - g.fill(x - 3, y - 3, x, y, PALE_GREEN); - g.fill(x + 1, y - 4, x + 4, y - 1, PALE_GREEN); - g.fill(x + 3, y, x + 6, y + 3, BLACK); - g.fill(x + 5, y - 3, x + 8, y + 1, BLACK); - g.fill(x + 5, y - 2, x + 6, y, color); - } else if (index == 2) { - // Fill bucket: arched handle, thick rim, tapered metal body, and visible paint inside. - g.fill(x - 6, y - 7, x + 6, y - 4, BLACK); - g.fill(x - 8, y - 5, x - 5, y + 1, BLACK); - g.fill(x + 5, y - 5, x + 8, y + 1, BLACK); - g.fill(x - 6, y - 5, x + 6, y - 3, color); - g.fill(x - 7, y - 2, x + 7, y + 2, BLACK); - g.fill(x - 5, y - 1, x + 5, y + 1, color); - g.fill(x - 5, y + 1, x + 5, y + 7, BLACK); - g.fill(x - 4, y + 3, x + 4, y + 6, color); - g.fill(x - 3, y + 2, x + 4, y + 4, PALE_GREEN); - g.fill(x - 4, y + 6, x + 4, y + 8, BLACK); - g.fill(x - 2, y + 5, x + 3, y + 6, GREEN); - g.fill(x - 5, y - 6, x - 3, y - 4, GREEN); - g.fill(x + 3, y - 6, x + 5, y - 4, GREEN); - } else if (index == 3) { - // Clear canvas: trash can with lid, slats, and a strong diagonal clear mark. - g.fill(x - 6, y - 7, x + 6, y - 4, BLACK); - g.fill(x - 3, y - 9, x + 3, y - 6, BLACK); - g.fill(x - 5, y - 3, x + 5, y + 8, BLACK); - g.fill(x - 3, y - 1, x + 3, y + 6, color); - g.fill(x - 4, y - 2, x + 4, y, PALE_GREEN); - g.fill(x - 3, y + 1, x - 1, y + 6, GREEN); - g.fill(x + 1, y + 1, x + 3, y + 6, GREEN); - g.fill(x - 8, y - 8, x + 8, y - 5, BLACK); - g.fill(x - 7, y - 4, x + 7, y - 2, BLACK); - g.fill(x - 8, y - 8, x - 5, y + 8, BLACK); - g.fill(x + 5, y - 8, x + 8, y + 8, BLACK); - g.fill(x - 9, y - 7, x - 7, y + 8, color); - g.fill(x + 7, y - 7, x + 9, y + 8, color); - g.fill(x - 8, y - 1, x + 8, y + 1, BLACK); - g.fill(x - 8, y + 5, x + 8, y + 7, BLACK); - g.fill(x - 8, y - 8, x + 8, y - 6, color); - g.fill(x - 7, y - 7, x + 7, y - 5, BLACK); - } else if (index == 4) { - // Undo: broad pixel arrow, stepped hook, and hollow center. - g.fill(x - 9, y - 4, x - 5, y + 2, color); - g.fill(x - 7, y - 6, x - 3, y - 2, color); - g.fill(x - 7, y, x - 3, y + 4, color); - g.fill(x - 5, y + 3, x + 3, y + 7, color); - g.fill(x + 1, y + 1, x + 6, y + 5, color); - g.fill(x + 4, y - 3, x + 8, y + 3, color); - g.fill(x + 2, y - 6, x + 6, y - 2, color); - g.fill(x - 5, y - 1, x + 3, y + 2, BLACK); - g.fill(x - 3, y + 2, x + 3, y + 4, BLACK); - g.fill(x - 8, y - 5, x - 5, y - 3, PALE_GREEN); - g.fill(x + 5, y - 2, x + 7, y, PALE_GREEN); - } else if (index == 5) { - // Redo: mirrored broad pixel arrow, stepped hook, and hollow center. - g.fill(x + 5, y - 4, x + 9, y + 2, color); - g.fill(x + 3, y - 6, x + 7, y - 2, color); - g.fill(x + 3, y, x + 7, y + 4, color); - g.fill(x - 3, y + 3, x + 5, y + 7, color); - g.fill(x - 6, y + 1, x - 1, y + 5, color); - g.fill(x - 8, y - 3, x - 4, y + 3, color); - g.fill(x - 6, y - 6, x - 2, y - 2, color); - g.fill(x - 3, y - 1, x + 5, y + 2, BLACK); - g.fill(x - 3, y + 2, x + 3, y + 4, BLACK); - g.fill(x + 5, y - 5, x + 8, y - 3, PALE_GREEN); - g.fill(x - 7, y - 2, x - 5, y, PALE_GREEN); - } else { - // Save: floppy disk with corner notch, shutter, label, hub, and highlight. - g.fill(x - 8, y - 8, x + 8, y + 8, BLACK); - g.fill(x - 5, y - 6, x + 5, y + 6, color); - g.fill(x - 5, y - 6, x + 2, y - 2, GREEN); - g.fill(x + 2, y - 6, x + 5, y - 1, BLACK); - g.fill(x + 4, y - 6, x + 5, y - 3, PALE_GREEN); - g.fill(x - 5, y, x + 5, y + 6, BLACK); - g.fill(x - 3, y + 1, x + 3, y + 5, color); - g.fill(x - 2, y + 2, x + 2, y + 4, PALE_GREEN); - g.fill(x - 7, y - 7, x - 5, y + 5, PALE_GREEN); - g.fill(x - 7, y + 6, x + 7, y + 8, BLACK); - g.fill(x - 4, y + 6, x + 4, y + 7, GREEN); - } - } - - private void renderTextEditor(GuiGraphics g, int x, int y, int w, int h) { - var fileState = ComputerFileSystemClientState.get(position); - if (session.textDirty - && fileState.lastMutationSuccess() - && (fileState.lastMutationAction() == com.craisinlord.antarchy.content.network.ComputerAccessPayload.FILE_CREATE - || fileState.lastMutationAction() == com.craisinlord.antarchy.content.network.ComputerAccessPayload.FILE_SAVE) - && fileState.lastMutationPath().equals(session.textPath)) { - session.textDirty = false; - } - if (!session.textSaveAsPendingPath.isBlank() - && fileState.lastMutationAction() == com.craisinlord.antarchy.content.network.ComputerAccessPayload.FILE_CREATE - && fileState.lastMutationPath().equals(session.textSaveAsPendingPath)) { - if (fileState.lastMutationSuccess()) { - session.textPath = session.textSaveAsPendingPath; - session.textDirty = false; - session.textJustSavedAs = true; - } - session.textSaveAsPendingPath = ""; - } - if (!session.textMovePendingPath.isBlank() - && fileState.lastMutationAction() == com.craisinlord.antarchy.content.network.ComputerAccessPayload.FILE_MOVE - && fileState.lastMutationPath().equals(session.textMovePendingPath)) { - if (fileState.lastMutationSuccess()) { - session.textPath = session.textMovePendingPath; - session.textJustSavedAs = true; - } - session.textMovePendingPath = ""; - } - if (!fileState.openedPath().isEmpty() && !session.textDirty && !session.textJustSavedAs) { - session.textPath = fileState.openedPath(); - session.textContent = fileState.openedContents(); - session.textCursor = session.textContent.length(); - } - session.textJustSavedAs = false; - String editorTitle = session.textRenaming ? "RENAME // " + session.textRename + "_" : "ANTTEXT // " + session.textPath + (session.textDirty ? " *" : ""); - g.drawString(font, Component.literal(trimToWidth(editorTitle, Math.max(1, w - 104))), x, y, GREEN, false); - g.drawString(font, Component.literal(trimToWidth("NEW OPEN WRITE SAVE AS", w)), x, y + 18, PALE_GREEN, false); - if (fileState.lastMutationAction() == com.craisinlord.antarchy.content.network.ComputerAccessPayload.FILE_CREATE - || fileState.lastMutationAction() == com.craisinlord.antarchy.content.network.ComputerAccessPayload.FILE_SAVE - || fileState.lastMutationAction() == com.craisinlord.antarchy.content.network.ComputerAccessPayload.FILE_MOVE) { - String status = fileState.lastMutationSuccess() ? "OPERATION OK" : "OPERATION ERROR // " + fileState.lastMutationError(); - String displayStatus = trimToWidth(status, Math.min(100, w)); - g.drawString(font, Component.literal(displayStatus), x + w - font.width(displayStatus), y, fileState.lastMutationSuccess() ? PALE_GREEN : GREEN, false); - } - g.fill(x + 4, y + 36, x + w - 4, y + h - 4, BLACK); - if (session.textListing) { - g.drawString(font, Component.literal("SELECT FILE"), x + 10, y + 46, GREEN, false); - int line = y + 62; - int visibleFiles = 0; - int textIndex = 0; - for (String file : fileState.files()) { - String[] fields = file.split("\\t", 3); - if (fields.length < 3 || !fields[0].equals("TEXT")) continue; - if (textIndex++ < session.textPickerScroll || line > y + h - 50) continue; - g.drawString(font, Component.literal(fields[1]), x + 10, line, PALE_GREEN, false); - line += 14; - visibleFiles++; - } - if (visibleFiles == 0) g.drawString(font, Component.literal("NO TEXT FILES"), x + 10, y + 62, PALE_GREEN, false); - } else { - String content = session.textContent.isEmpty() ? "TYPE HERE..." : session.textContent; - if (session.textFocused) content = content.substring(0, Math.min(session.textCursor, content.length())) + "|" - + content.substring(Math.min(session.textCursor, content.length())); - List lines = font.split(Component.literal(content), w - 28); - int maxLines = Math.max(1, (h - 88) / 11); - session.textScroll = Math.max(0, Math.min(session.textScroll, Math.max(0, lines.size() - maxLines))); - for (int i = session.textScroll; i < lines.size() && i < session.textScroll + maxLines; i++) { - g.drawString(font, lines.get(i), x + 10, y + 46 + (i - session.textScroll) * 11, GREEN, false); - } - } - if (session.textDeleteConfirm) { - g.drawString(font, Component.literal("DELETE CURRENT FILE? [ ENTER / ESC ]"), x, y + h - 28, PALE_GREEN, false); - } else { - g.drawString(font, Component.literal(trimToWidth("[CTRL+S] SAVE [CTRL+SHIFT+S] SAVE AS", w)), x, y + h - 39, PALE_GREEN, false); - g.drawString(font, Component.literal(trimToWidth("[CTRL+R] RENAME [CTRL+DEL] DELETE [ESC] CLOSE", w)), x, y + h - 26, PALE_GREEN, false); - } - } - - private void renderAntmail(GuiGraphics g, int x, int y, int h) { - var result = AntmailClientState.getMailbox(position); - AntmailResultPayload lastResponse = AntmailClientState.get(position); - boolean unconfigured = (result != null && result.address().isBlank()) - || (result == null && lastResponse != null && ("unconfigured".equals(lastResponse.detail()) - || "address_not_found".equals(lastResponse.detail()) || lastResponse.detail().startsWith("registration_failed:"))); - g.drawString(font, Component.literal("ANTMAIL // COMPUTER ADDRESS"), x, y, GREEN, false); - session.antmailAttachmentStartLine = -1; - session.antmailVisibleAttachmentCount = 0; - if (result == null && !unconfigured) { - g.drawString(font, Component.literal("CONTACTING ANTMAIL NETWORK"), x, y + 20, GREEN, false); - String waitStatus = lastResponse != null && !lastResponse.detail().isBlank() - ? "SERVER // " + lastResponse.detail().toUpperCase() - : session.antmailStateWaitTicks >= 100 ? "NO RESPONSE // CHECK CLIENT + SERVER LOGS" : "PLEASE WAIT // RETRYING STATE SYNC"; - g.drawString(font, Component.literal(trimToWidth(waitStatus, 208)), x, y + 40, PALE_GREEN, false); - box(g, x, y + 56, x + 150, y + 79, GREEN); - g.drawString(font, Component.literal("[ RETRY STATE LINK ]"), x + 6, y + 63, GREEN, false); - } else if (unconfigured) { - String registrationStatus = lastResponse != null && lastResponse.detail().startsWith("registration_failed:") - ? "REGISTRATION FAILED // " + lastResponse.detail().substring("registration_failed:".length()).toUpperCase() - : "NO ADDRESS CONFIGURED"; - g.drawString(font, Component.literal(trimToWidth(registrationStatus, 208)), x, y + 20, PALE_GREEN, false); - g.drawString(font, Component.literal("USERNAME // 3-16 CHARACTERS"), x, y + 40, GREEN, false); - g.fill(x, y + 56, x + 206, y + 79, BLACK); - box(g, x, y + 56, x + 206, y + 79, GREEN); - g.drawString(font, Component.literal(trimToWidth(session.antmailUsername + "@antmail.com", 194)), x + 6, y + 63, GREEN, false); - g.drawString(font, Component.literal("[ ENTER ] REGISTER ADDRESS"), x, y + 88, GREEN, false); - } else { - g.drawString(font, Component.literal(trimToWidth(result.address(), 208)), x, y + 20, PALE_GREEN, false); - if (session.antmailMode.equals("inbox")) box(g, x, y + 30, x + 54, y + 53, PALE_GREEN); - if (session.antmailMode.equals("sent")) box(g, x + 54, y + 30, x + 100, y + 53, PALE_GREEN); - if (session.antmailMode.equals("drafts")) box(g, x + 100, y + 30, x + 154, y + 53, PALE_GREEN); - g.drawString(font, Component.literal("INBOX"), x + 6, y + 38, session.antmailMode.equals("inbox") ? PALE_GREEN : GREEN, false); - g.drawString(font, Component.literal("SENT"), x + 60, y + 38, session.antmailMode.equals("sent") ? PALE_GREEN : GREEN, false); - g.drawString(font, Component.literal("DRAFTS"), x + 106, y + 38, session.antmailMode.equals("drafts") ? PALE_GREEN : GREEN, false); - box(g, x + 158, y + 30, x + 214, y + 53, session.antmailMode.equals("compose") ? PALE_GREEN : GREEN); - g.drawString(font, Component.literal("COMPOSE"), x + 163, y + 38, session.antmailMode.equals("compose") ? PALE_GREEN : GREEN, false); - if (session.antmailMode.equals("compose")) { - g.drawString(font, Component.literal(trimToWidth(session.antmailRecipient, 180)), x + 28, y + 52, PALE_GREEN, false); - g.drawString(font, Component.literal(trimToWidth(session.antmailSubject, 156)), x + 52, y + 66, PALE_GREEN, false); - g.drawString(font, Component.literal("TO"), x, y + 52, GREEN, false); - g.drawString(font, Component.literal("SUBJECT"), x, y + 66, GREEN, false); - g.drawString(font, Component.literal("BODY"), x, y + 80, GREEN, false); - wrapLimited(g, session.antmailBody.isEmpty() ? "TYPE MESSAGE..." : session.antmailBody, x, y + 94, 208, y + 124, PALE_GREEN); - g.drawString(font, Component.literal(trimToWidth("[ " + (session.antmailAttachText ? "X" : " ") + " ] TEXT FILE [ " + (session.antmailAttachPaint ? "X" : " ") + " ] PAINTING", 208)), x, y + 128, PALE_GREEN, false); - if (session.antmailPickingAttachment) { - g.fill(x + 4, y + 42, x + 210, y + h - 40, BLACK); - box(g, x + 4, y + 42, x + 210, y + h - 40, GREEN); - g.drawString(font, Component.literal("SELECT FILE TO ATTACH"), x + 10, y + 48, GREEN, false); - int line = y + 64; - for (String file : ComputerFileSystemClientState.get(position).files()) { - String[] fields = file.split("\\t", 3); - if (fields.length < 2 || (!fields[0].equals("TEXT") && !fields[0].equals("IMAGE")) || line > y + h - 52) continue; - g.drawString(font, Component.literal(trimToWidth(fields[1], 190)), x + 10, line, PALE_GREEN, false); - line += 14; - } - } - g.drawString(font, Component.literal("[ ENTER ] SEND"), x, y + h - 28, GREEN, false); - } else if (session.antmailMode.equals("message")) { - AntmailMessage message = selectedAntmailMessage(result); - if (message != null) { - boolean showRetry = session.antmailSent && !message.deliveryStatus().equals("DELIVERED"); - int attachmentBottom = y + h - (showRetry ? 54 : 36); - g.drawString(font, Component.literal("< BACK // " + (session.antmailSent ? "SENT" : "INBOX")), x, y + 40, GREEN, false); - g.drawString(font, Component.literal(trimToWidth(session.antmailSent ? message.recipient().fullAddress() : message.sender().fullAddress(), 208)), x, y + 62, PALE_GREEN, false); - g.drawString(font, Component.literal(trimToWidth(message.subject(), 208)), x, y + 78, GREEN, false); - int messageLine = wrapLimited(g, message.body(), x, y + 98, 208, attachmentBottom, PALE_GREEN) + 4; - if (!message.attachments().isEmpty() && messageLine + 9 <= attachmentBottom) { - session.antmailAttachmentStartLine = messageLine; - for (AntmailAttachment attachment : message.attachments()) { - if (messageLine + 9 > attachmentBottom) break; - g.drawString(font, Component.literal(trimToWidth("[ SAVE ATTACHMENT ] " + attachment.fileName(), 208)), x, messageLine, GREEN, false); - session.antmailVisibleAttachmentCount++; - messageLine += 14; - } - } - if (showRetry) { - String retryLabel = session.antmailRetryMessageId.equals(message.id().toString()) ? "[ RETRYING... ]" : "[ RETRY DELIVERY ]"; - g.drawString(font, Component.literal(retryLabel), x, y + h - 46, GREEN, false); - } - g.drawString(font, Component.literal("[ DELETE MESSAGE ]"), x, y + h - 28, GREEN, false); - } - } else if (session.antmailMode.equals("drafts")) { - List drafts = mailbox(result) == null ? List.of() : mailbox(result).drafts(); - g.drawString(font, Component.literal("DRAFTS // " + drafts.size()), x, y + 62, GREEN, false); - int line = y + 80; - for (AntmailDraft draft : drafts) { - if (line > y + h - 38) break; - g.drawString(font, Component.literal(trimToWidth("* " + (draft.subject().isBlank() ? "UNTITLED DRAFT" : draft.subject()), 30)), x, line, PALE_GREEN, false); - line += 14; - } - if (drafts.isEmpty()) g.drawString(font, Component.literal("NO SAVED DRAFTS"), x, y + 80, PALE_GREEN, false); - } else { - List messages = mailboxMessages(result, session.antmailSent); - int total = antmailTotal(result, session.antmailSent); - g.drawString(font, Component.literal((session.antmailSent ? "SENT // " : "INBOX // ") + total), x, y + 62, GREEN, false); - int line = y + 80; - for (AntmailMessage message : messages) { - if (line > y + h - 38) break; - String status = session.antmailSent ? " // " + message.deliveryStatus() : ""; - g.drawString(font, Component.literal((message.read() ? " " : "* ") + trimToWidth(message.subject() + status, 28)), x, line, message.read() ? PALE_GREEN : GREEN, false); - line += 14; - } - g.drawString(font, Component.literal("[ < ] PAGE " + (session.antmailPage + 1) + " [ > ]"), x, y + h - 42, GREEN, false); - } - } - AntmailResultPayload operation = AntmailClientState.get(position); - if (session.antmailSendPending && operation != null && operation != session.antmailSendBaseline && !operation.messageId().isBlank()) { - session.antmailSendPending = false; - session.antmailSendBaseline = null; - if (operation.status() == 0 || operation.status() == 1) { - if (session.antmailDraftId != null) AntmailNetworking.deleteDraft(position, session.antmailDraftId); - session.antmailDraftId = null; - session.antmailDraftLoaded = false; - session.antmailStatus = antmailStatus(operation); - session.antmailMode = "inbox"; - session.antmailFocused = false; - session.antmailRecipient = ""; - session.antmailSubject = ""; - session.antmailBody = ""; - session.antmailAttachText = false; - session.antmailAttachPaint = false; - session.antmailPaintAttachment = null; - session.antmailPaintLoadPendingPath = ""; - session.antmailTextPath = ""; - session.antmailPaintPath = ""; - session.antmailPage = 0; - requestAntmailState(true); - } else { - session.antmailFocused = true; - session.antmailStatus = antmailStatus(operation); - } - } - String displayStatus = session.antmailStatus; - if (!displayStatus.isEmpty()) drawBottomWrapped(g, displayStatus, x, y, h, 208, PALE_GREEN); - } - - private String antmailStatus(AntmailResultPayload result) { - if (result.status() == 0) return "DELIVERED"; - if (result.status() == 1) return "QUEUED"; - return "DELIVERY FAILED // " + (result.detail().isBlank() ? "SERVER REJECTED" : result.detail().toUpperCase()); - } - - private AntmailMailbox mailbox(AntmailResultPayload result) { - if (result == null || result.data().isBlank()) return null; - try { - return AntmailMailbox.fromTag(AntmailWire.decodeTag(result.data())); - } catch (RuntimeException ignored) { - return null; - } - } - - private List mailboxMessages(AntmailResultPayload result, boolean sent) { - AntmailMailbox mailbox = mailbox(result); - if (mailbox == null) return List.of(); - return sent ? mailbox.sent() : mailbox.inbox(); - } - - private int antmailTotal(AntmailResultPayload result, boolean sent) { - if (result == null || result.data().isBlank()) return 0; - try { - var tag = AntmailWire.decodeTag(result.data()); - return tag.getInt(sent ? "TotalSent" : "TotalInbox"); - } catch (RuntimeException ignored) { - return mailboxMessages(result, sent).size(); - } - } - - private AntmailMessage selectedAntmailMessage(AntmailResultPayload result) { - List messages = mailboxMessages(result, session.antmailSent); - if (session.antmailMessageIndex < 0 || session.antmailMessageIndex >= messages.size()) return null; - AntmailMessage summary = messages.get(session.antmailMessageIndex); - AntmailMessage detail = AntmailClientState.getMessage(position, summary.id()); - return detail == null ? summary : detail; - } - - private void renderGames(GuiGraphics g, Window window, int x, int y, int mouseX, int mouseY) { - g.drawString(font, Component.literal("INSTALLED GAMES"), x, y, GREEN, false); - if (window.gameOpen) { - if (window.gameId.equals("antman")) antman.render(g, font, x, y + 16, 214, 155); - else if (window.gameId.equals("blockle")) blockle.render(g, font, x, y + 16, 214, 155); - else basilisk.render(g, font, x, y + 16, 214, 155); - return; - } - List games = installedGameIds(); - for (int index = 0; index < games.size(); index++) { - int rowTop = y + 18 + index * 16; - if (inside(x - 4, rowTop, 218, 16, mouseX, mouseY)) box(g, x - 4, rowTop, x + 214, rowTop + 16, GREEN); - g.drawString(font, Component.literal(gameLabel(games.get(index))), x, y + 22 + index * 16, PALE_GREEN, false); - } - if (games.isEmpty()) { - g.drawString(font, Component.literal("NO GAMES INSTALLED"), x, y + 22, PALE_GREEN, false); - g.drawString(font, Component.literal(trimToWidth("FIND GAME DISKS TO INSTALL PROGRAMS", 214)), x, y + 40, PALE_GREEN, false); - } - } - - private List installedGameIds() { - List games = new ArrayList<>(); - if (basilisk.installed()) games.add("basilisk"); - if (antman.installed()) games.add("antman"); - if (blockle.installed()) games.add("blockle"); - return games; - } - - private String gameLabel(String gameId) { - return switch (gameId) { - case "basilisk" -> "BASILISK [ ENTER ]"; - case "antman" -> "ANTMAN.EXE [ ENTER ]"; - default -> "BLOCKLE [ ENTER ]"; - }; - } - - private void renderTrash(GuiGraphics g, int x, int y) { - g.drawString(font, Component.literal("DROP A DISK HERE TO EJECT"), x, y, GREEN, false); - g.drawString(font, Component.literal("EJECTED FILES RETURN TO PLAYER"), x, y + 22, PALE_GREEN, false); - } - - private int wrap(GuiGraphics g, String text, int x, int y, int width, int color) { return wrap(g, Component.literal(text), x, y, width, color); } - - private int wrap(GuiGraphics g, Component text, int x, int y, int width, int color) { - for (var line : font.split(text, width)) { g.drawString(font, line, x, y, color, false); y += 11; } - return y; - } - - private int wrapLimited(GuiGraphics g, String text, int x, int y, int width, int bottom, int color) { - for (var line : font.split(Component.literal(text), width)) { - if (y + 11 > bottom) break; - g.drawString(font, line, x, y, color, false); - y += 11; - } - return y; - } - - private void drawBottomWrapped(GuiGraphics g, String text, int x, int y, int h, int width, int color) { - List lines = font.split(Component.literal(text), width); - int lineY = y + h - 16 - Math.max(0, lines.size() - 1) * 11; - for (var line : lines) { - g.drawString(font, line, x, lineY, color, false); - lineY += 11; - } - } - - private void box(GuiGraphics g, int x1, int y1, int x2, int y2, int color) { - g.fill(x1, y1, x2, y1 + 2, color); - g.fill(x1, y2 - 2, x2, y2, color); - g.fill(x1, y1, x1 + 2, y2, color); - g.fill(x2 - 2, y1, x2, y2, color); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - float scale = uiScale(); - mouseX = (mouseX - width / 2.0F) / scale; - mouseY = (mouseY - height / 2.0F) / scale; - int l = -WIDTH / 2; - int t = -HEIGHT / 2; - if (!loggedIn) { - ComputerBlockEntity computer = computer(); - boolean setup = (accessResult != null && !accessResult.hasPassword()) || (computer != null && !computer.hasPassword()); - int formX = setup ? l + 110 : l + 242; - if (inside(formX, t + 181, setup ? 150 : 100, 24, mouseX, mouseY)) tryLogin(); - return true; - } - session.lastUse = System.currentTimeMillis(); - for (int i = session.windows.size() - 1; i >= 0; i--) { - Window window = session.windows.get(i); - if (window.minimized) continue; - int x = l + windowLocalX(window); - int y = t + windowLocalY(window); - int w = windowWidth(window); - int h = windowHeight(window); - int contentX = x + 8; - int contentY = y + 28; - int contentW = w - 16; - int contentH = h - 34; - if (inside(x, y + TITLE_BAR_HEIGHT, w, h - TITLE_BAR_HEIGHT, mouseX, mouseY)) { - activeWindow = window; - session.windows.remove(i); - session.windows.add(window); - if (window.type.equals("SETTINGS") && inside(contentX, contentY + 105, Math.min(205, contentW), 51, mouseX, mouseY)) { - List disks = physicalDisks(); - int index = ((int) mouseY - (contentY + 105)) / 17; - if (index >= 0 && index < disks.size() && index < 3) selectedDisk = disks.get(index); - return true; - } - if (window.type.equals("ARCHIVE")) { - List entries = filterArchiveEntries(ComputerGuideData.entriesFor(computer() == null ? List.of() : computer().diskIds())); - int archiveX = x + 8; - int archiveY = y + 28; - if (session.archiveEntryId != null) { - if (inside(archiveX, archiveY, w - 16, 20, mouseX, mouseY)) { - session.archiveEntryId = null; - session.archiveDetailScroll = 0; - } - } else { - if (inside(archiveX, archiveY + 14, w - 16, 21, mouseX, mouseY)) { - session.archiveSearchFocused = true; - return true; - } - session.archiveSearchFocused = false; - int columns = window.maximized ? 3 : 1; - int cellHeight = window.maximized ? 72 : 38; - int visibleRows = Math.max(1, (contentH - 58) / cellHeight); - int totalRows = (entries.size() + columns - 1) / columns; - int startRow = Math.max(0, Math.min(session.archiveScroll, Math.max(0, totalRows - visibleRows))); - int gridTop = archiveY + 40; - int relativeRow = ((int) mouseY - gridTop) / cellHeight; - int relativeColumn = Math.min(columns - 1, Math.max(0, ((int) mouseX - archiveX) / Math.max(1, (contentW - 8) / columns))); - int index = (startRow + relativeRow) * columns + relativeColumn; - int cellWidth = (contentW - 8) / columns; - int cellX = archiveX + relativeColumn * cellWidth; - int rowTop = gridTop + relativeRow * cellHeight; - if (relativeRow >= 0 && relativeRow < visibleRows && index < entries.size() - && inside(cellX, rowTop, cellWidth - 2, cellHeight - 2, mouseX, mouseY)) { - ComputerGuideData.Entry openedEntry = entries.get(index); - session.archiveEntryId = openedEntry.id(); - session.archiveDetailScroll = 0; - if (!openedEntry.structureId().isBlank()) { - com.craisinlord.antarchy.content.client.ComputerStructureLocatorClientState.searching(position, openedEntry.dimensionId()); - ComputerNetworking.locateStructure(position, openedEntry.id()); - } - } - } - return true; - } - if (window.type.equals("FILES")) { - var files = ComputerFileSystemClientState.get(position).files(); - if (!session.fileExplorerDirectory.equals("/") && mouseY >= contentY && mouseY < contentY + 12 && mouseX > x + w - 48) { - session.fileExplorerDirectory = parentDirectory(session.fileExplorerDirectory); - session.fileExplorerScroll = 0; - return true; - } - int row = 0; - for (String file : files) { - String[] fields = file.split("\\t", 3); - if (fields.length < 3 || !isDirectChild(fields[1], session.fileExplorerDirectory)) continue; - int rowIndex = row++; - if (rowIndex < session.fileExplorerScroll) continue; - int rowTop = contentY + 34 + (rowIndex - session.fileExplorerScroll) * 14; - if (rowTop > contentY + contentH - 32) break; - if (!inside(contentX, rowTop - 2, contentW, 14, mouseX, mouseY)) continue; - session.fileExplorerSelected = fields[1]; - if (fields[0].equals("DIRECTORY")) { - session.fileExplorerDirectory = fields[1]; - session.fileExplorerScroll = 0; - } - else if (fields[0].equals("TEXT") || fields[0].equals("IMAGE")) { - ComputerNetworking.openFile(position, fields[1]); - open(fields[1].endsWith(".antpaint") ? "PAINT" : "TEXT"); - } - break; - } - return true; - } - if (window.type.equals("PAINT")) { - int canvasX = contentX; - int canvasY = contentY + 30; - int canvasHeight = Math.max(1, contentH - 32); - if (inside(canvasX, canvasY, contentW, canvasHeight, mouseX, mouseY)) { - if (button == 0 || button == 1) { - paintStrokeActive = session.paintTool == AntPaintTool.PENCIL || session.paintTool == AntPaintTool.ERASER; - paintStrokeButton = button; - lastPaintPixelX = -1; - lastPaintPixelY = -1; - if (paintStrokeActive) session.paintHistory.record(session.paintCanvas); - } - if (button == 0 || button == 1) paintAt(mouseX, mouseY, canvasX, canvasY, contentW, canvasHeight); - } - else if (mouseY >= contentY + 11 && mouseY < contentY + 30 && mouseX >= contentX && mouseX < contentX + Math.min(196, contentW)) { - paintStrokeActive = false; - paintToolbarAction(((int) mouseX - contentX) / 28); - } - return true; - } - if (window.type.equals("TEXT")) { - if (inside(contentX, contentY + 12, contentW, 26, mouseX, mouseY)) { - int toolbarX = (int) mouseX - contentX; - if (toolbarX < 30) newText(); - else if (toolbarX < 60) { session.textListing = true; session.textPickerScroll = 0; ComputerNetworking.listFiles(position); } - else if (toolbarX < 102) writeText(); - else if (toolbarX < 138) saveText(); - else if (toolbarX < 210) beginSaveAs(); - } else if (session.textListing) { - var files = ComputerFileSystemClientState.get(position).files(); - int index = session.textPickerScroll + ((int) mouseY - (contentY + 62)) / 14; - int textIndex = 0; - for (String file : files) { - String[] fields = file.split("\\t", 3); - if (fields.length < 3 || !fields[0].equals("TEXT")) continue; - if (textIndex++ == index) { - session.textListing = false; - ComputerNetworking.openFile(position, fields[1]); - break; - } - } - } else { - session.textFocused = true; - setTextCursorFromMouse(mouseX - (contentX + 10), mouseY - (contentY + 46), contentW - 12); - } - return true; - } - if (window.type.equals("ANTMAIL")) { - var result = AntmailClientState.getMailbox(position); - if (result == null && !antmailUnconfigured()) { - if (inside(contentX, contentY + 56, Math.min(150, contentW), 23, mouseX, mouseY)) { - session.antmailStateWaitTicks = 0; - requestAntmailState(true); - } - return true; - } else if (result == null || result.address().isBlank()) { - if (inside(contentX, contentY + 56, Math.min(206, contentW), 23, mouseX, mouseY)) { - session.antmailFocused = true; - return true; - } - if (inside(contentX, contentY + 84, contentW, 24, mouseX, mouseY)) { - setupAntmail(); - return true; - } - } else if (inside(contentX, contentY + 30, 54, 24, mouseX, mouseY)) { - session.antmailMode = "inbox"; - session.antmailSent = false; - session.antmailPage = 0; - session.antmailMessageIndex = -1; - requestAntmailState(true); - } else if (inside(contentX + 54, contentY + 30, 46, 24, mouseX, mouseY)) { - session.antmailMode = "sent"; - session.antmailSent = true; - session.antmailPage = 0; - session.antmailMessageIndex = -1; - requestAntmailState(true); - } else if (inside(contentX + 100, contentY + 30, 54, 24, mouseX, mouseY)) { - session.antmailMode = "drafts"; - session.antmailSent = false; - session.antmailPage = 0; - session.antmailMessageIndex = -1; - requestAntmailState(true); - } else if (inside(contentX + 158, contentY + 30, Math.min(56, Math.max(0, contentW - 158)), 24, mouseX, mouseY)) { - session.antmailMode = "compose"; - session.antmailFocused = true; - session.antmailField = 1; - restoreLatestDraft(result); - } else if (session.antmailMode.equals("inbox") || session.antmailMode.equals("sent")) { - if (mouseY >= contentY + contentH - 48 && mouseY < contentY + contentH - 28) { - if (mouseX < contentX + 52 && session.antmailPage > 0) { - session.antmailPage--; - requestAntmailState(true); - } else if (mouseX >= contentX + 142 && (session.antmailPage + 1) * AntmailMailbox.PAGE_SIZE < antmailTotal(result, session.antmailSent)) { - session.antmailPage++; - requestAntmailState(true); - } - return true; - } - int index = ((int) mouseY - (contentY + 80)) / 14; - List messages = mailboxMessages(result, session.antmailSent); - if (index >= 0 && index < messages.size()) { - session.antmailMessageIndex = index; - session.antmailMode = "message"; - AntmailNetworking.requestMessage(position, messages.get(index).id()); - if (!session.antmailSent) AntmailNetworking.markRead(position, messages.get(index).id()); - } - } else if (session.antmailMode.equals("drafts")) { - int index = ((int) mouseY - (contentY + 80)) / 14; - AntmailMailbox mailbox = mailbox(result); - if (mailbox != null && index >= 0 && index < mailbox.drafts().size()) { - restoreDraft(mailbox.drafts().get(index)); - session.antmailMode = "compose"; - session.antmailFocused = true; - session.antmailField = 1; - } - } else if (session.antmailMode.equals("message")) { - AntmailMessage message = selectedAntmailMessage(result); - if (session.antmailSent && message != null && !message.deliveryStatus().equals("DELIVERED") - && session.antmailRetryMessageId.isBlank() - && mouseY >= contentY + contentH - 50 && mouseY < contentY + contentH - 32) { - session.antmailRetryBaseline = AntmailClientState.get(position); - session.antmailRetryMessageId = message.id().toString(); - session.antmailRetryTicks = 100; - AntmailNetworking.retry(position, message.id()); - session.antmailStatus = "RETRYING DELIVERY"; - return true; - } - if (mouseY >= contentY + contentH - 32 && mouseY < contentY + contentH - 8) { - if (message != null) AntmailNetworking.delete(position, message.id(), session.antmailSent); - session.antmailMode = session.antmailSent ? "sent" : "inbox"; - session.antmailMessageIndex = -1; - return true; - } - if (message != null && session.antmailAttachmentStartLine >= 0 - && mouseY >= session.antmailAttachmentStartLine - && mouseY < session.antmailAttachmentStartLine + session.antmailVisibleAttachmentCount * 14 - && !message.attachments().isEmpty()) { - int attachmentIndex = ((int) mouseY - session.antmailAttachmentStartLine) / 14; - saveAntmailAttachment(message.attachments().get(attachmentIndex)); - return true; - } - if (mouseY < contentY + 72) { - session.antmailMode = session.antmailSent ? "sent" : "inbox"; - session.antmailMessageIndex = -1; - } - } else if (session.antmailMode.equals("compose")) { - if (session.antmailPickingAttachment) { - int row = 0; - for (String file : ComputerFileSystemClientState.get(position).files()) { - String[] fields = file.split("\\t", 3); - if (fields.length < 2 || (!fields[0].equals("TEXT") && !fields[0].equals("IMAGE"))) continue; - int rowTop = contentY + 64 + row++ * 14; - if (rowTop > contentY + contentH - 52) break; - if (mouseY >= rowTop - 2 && mouseY < rowTop + 12) { - session.fileExplorerSelected = fields[1]; - session.antmailAttachText = fields[0].equals("TEXT"); - session.antmailAttachPaint = fields[0].equals("IMAGE"); - session.antmailPickingAttachment = false; - if (session.antmailAttachText) { - session.textPath = fields[1]; - session.antmailTextPath = fields[1]; - } else { - session.antmailPaintPath = fields[1]; - session.paintName = fields[1].substring(fields[1].lastIndexOf('/') + 1); - session.antmailPaintAttachment = null; - session.antmailPaintLoadPendingPath = fields[1]; - } - ComputerNetworking.openFile(position, fields[1]); - return true; - } - } - return true; - } - if (mouseY >= contentY + 116 && mouseY < contentY + 141) { - session.antmailPickingAttachment = true; - return true; - } - if (mouseY >= contentY + 42 && mouseY < contentY + 59) { - session.antmailField = 1; - session.antmailFocused = true; - } else if (mouseY >= contentY + 59 && mouseY < contentY + 75) { - session.antmailField = 2; - session.antmailFocused = true; - } else if (mouseY >= contentY + 75 && mouseY < contentY + 116) { - session.antmailField = 3; - session.antmailFocused = true; - } else if (mouseY >= contentY + contentH - 38 && mouseY < contentY + contentH - 8) { - sendAntmail(); - } - } - return true; - } - if (window.type.equals("GAMES") && !window.gameOpen) { - List games = installedGameIds(); - int index = ((int) mouseY - (contentY + 18)) / 16; - if (index >= 0 && index < games.size() && mouseY < contentY + 18 + games.size() * 16) { - window.gameId = games.get(index); - window.gameOpen = true; - activeWindow = window; - return true; - } - } - if (window.type.equals("TERMINAL")) { session.terminalFocused = true; return true; } - } - if (window.type.equals("SETTINGS") && inside(contentX, contentY + 156, Math.min(205, contentW), 20, mouseX, mouseY)) { - ejectSelected(); - return true; - } - if (window.type.equals("SETTINGS") && inside(contentX, contentY + 70, 90, 18, mouseX, mouseY)) { - ComputerNetworking.logout(position); - loggedIn = false; - session.authenticated = false; - session.windows.clear(); - activeWindow = null; - return true; - } - if (inside(x, y + TITLE_BAR_HEIGHT, w, h - TITLE_BAR_HEIGHT, mouseX, mouseY)) return true; - if (inside(x, y, w, TITLE_BAR_HEIGHT, mouseX, mouseY)) { - int controlsLeft = x + w - WINDOW_CONTROL_WIDTH * WINDOW_CONTROL_COUNT; - if (inside(controlsLeft + WINDOW_CONTROL_WIDTH * 2, y, WINDOW_CONTROL_WIDTH, TITLE_BAR_HEIGHT, mouseX, mouseY)) { - if (window.type.equals("ANTMAIL") && session.antmailMode.equals("compose")) saveAntmailDraft(); - session.windows.remove(i); - if (activeWindow == window) activeWindow = null; - } - else if (inside(controlsLeft + WINDOW_CONTROL_WIDTH, y, WINDOW_CONTROL_WIDTH, TITLE_BAR_HEIGHT, mouseX, mouseY)) toggleMaximized(window); - else if (inside(controlsLeft, y, WINDOW_CONTROL_WIDTH, TITLE_BAR_HEIGHT, mouseX, mouseY)) { - window.minimized = true; - if (activeWindow == window) activeWindow = null; - } - else if (!window.maximized) { dragging = window; dragX = (int) mouseX - x; dragY = (int) mouseY - y; session.windows.remove(i); session.windows.add(window); } - return true; - } - } - for (int i = 0; i < ICONS.length; i++) { - int x = l + 24 + i % 4 * 94; - int y = t + 48 + i / 4 * 76; - if (inside(x - 6, y - 6, 76, 57, mouseX, mouseY)) { open(ICONS[i]); return true; } - } - List disks = physicalDisks().stream().filter(id -> !id.getPath().equals("blockle_game")).toList(); - for (int i = 0; i < disks.size() && i < 3; i++) { - int x = l + 24 + (i + 1) * 94; - int y = t + 200 + i / 4 * 54; - if (inside(x - 6, y - 6, 76, 48, mouseX, mouseY)) { - draggedDisk = disks.get(i).toString(); - selectedDisk = disks.get(i); - return true; - } - } - return true; - } - - @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double dragX, double dragY) { - float scale = uiScale(); - mouseX = (mouseX - width / 2.0F) / scale; - mouseY = (mouseY - height / 2.0F) / scale; - if (dragging != null) { - int l = -WIDTH / 2; - int t = -HEIGHT / 2; - dragging.x = Math.max(12, Math.min(WIDTH - dragging.renderWidth - 12, (int) mouseX - l - this.dragX)); - dragging.y = Math.max(34, Math.min(HEIGHT - dragging.renderHeight - 12, (int) mouseY - t - this.dragY)); - } - if (paintStrokeActive && button == paintStrokeButton && activeWindow != null && activeWindow.type.equals("PAINT")) { - int l = -WIDTH / 2; - int t = -HEIGHT / 2; - int x = l + windowLocalX(activeWindow) + 8; - int y = t + windowLocalY(activeWindow) + 58; - paintAt(mouseX, mouseY, x, y, activeWindow.renderWidth - 16, Math.max(1, activeWindow.renderHeight - 66)); - } - return true; - } - - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - float scale = uiScale(); - mouseX = (mouseX - width / 2.0F) / scale; - mouseY = (mouseY - height / 2.0F) / scale; - if (draggedDisk != null) { - int l = -WIDTH / 2; - int t = -HEIGHT / 2; - int trashX = l + 24 + (TRASH_ICON_INDEX % 4) * 94; - int trashY = t + 48 + (TRASH_ICON_INDEX / 4) * 76; - if (inside(trashX - 6, trashY - 6, 76, 57, mouseX, mouseY)) ejectSelected(); - draggedDisk = null; - } - dragging = null; - if (button == paintStrokeButton) { - paintStrokeActive = false; - paintStrokeButton = -1; - lastPaintPixelX = -1; - lastPaintPixelY = -1; - } - return true; - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { - Window hoveredWindow = windowAt(mouseX, mouseY); - if (!loggedIn || hoveredWindow == null) return super.mouseScrolled(mouseX, mouseY, scrollX, scrollY); - activeWindow = hoveredWindow; - if (activeWindow.type.equals("FILES")) { - session.fileExplorerScroll = Math.max(0, session.fileExplorerScroll - (int) Math.signum(scrollY)); - return true; - } - if (activeWindow.type.equals("TEXT") && session.textListing) { - session.textPickerScroll = Math.max(0, session.textPickerScroll - (int) Math.signum(scrollY)); - return true; - } - if (activeWindow.type.equals("TEXT")) { - session.textScroll = Math.max(0, session.textScroll - (int) Math.signum(scrollY)); - return true; - } - if (activeWindow.type.equals("ARCHIVE")) { - if (session.archiveEntryId == null) session.archiveScroll = Math.max(0, session.archiveScroll - (int) Math.signum(scrollY)); - else session.archiveDetailScroll = Math.max(0, session.archiveDetailScroll - (int) Math.signum(scrollY)); - return true; - } - return super.mouseScrolled(mouseX, mouseY, scrollX, scrollY); - } - - @Override - public boolean charTyped(char codePoint, int modifiers) { - if (!loggedIn && codePoint >= 32) { - if (confirmingPassword) { - if (confirmation.length() < 32) confirmation += Character.toUpperCase(codePoint); - } else if (password.length() < 32) { - password += Character.toUpperCase(codePoint); - } - } - if (loggedIn && activeWindow != null && activeWindow.type.equals("FILES") && session.fileExplorerRenaming && codePoint >= 32 && codePoint != '/' && codePoint != '\\') { - if (session.fileExplorerRename.length() < 48) session.fileExplorerRename += codePoint; - return true; - } - if (loggedIn && activeWindow != null && activeWindow.type.equals("ARCHIVE") && session.archiveSearchFocused && codePoint >= 32 && session.archiveSearch.length() < 48) { - session.archiveSearch += codePoint; - session.archiveScroll = 0; - return true; - } - if (loggedIn && activeWindow != null && activeWindow.type.equals("FILES") && session.fileExplorerCreatingDirectory && codePoint >= 32 && codePoint != '/' && codePoint != '\\') { - if (session.fileExplorerRename.length() < 48) session.fileExplorerRename += codePoint; - return true; - } - if (loggedIn && activeWindow != null && activeWindow.type.equals("FILES") && session.fileExplorerMoving && codePoint >= 32 && codePoint != '\\') { - if (session.fileExplorerRename.length() < 64) session.fileExplorerRename += codePoint; - return true; - } - if (loggedIn && activeWindow != null && activeWindow.type.equals("TEXT") && session.textRenaming && codePoint >= 32 && codePoint != '/' && codePoint != '\\') { - if (session.textRename.length() < 48) session.textRename += codePoint; - return true; - } - if (loggedIn && activeWindow != null) { - if (activeWindow.type.equals("GAMES") && activeWindow.gameOpen && activeWindow.gameId.equals("blockle") && blockle.charTyped(codePoint)) return true; - if (activeWindow.type.equals("TEXT") && session.textFocused && codePoint >= 32) { - session.textContent = session.textContent.substring(0, session.textCursor) + codePoint + session.textContent.substring(session.textCursor); - session.textCursor++; - session.textDirty = true; - return true; - } - if (activeWindow.type.equals("TERMINAL") && session.terminalFocused && codePoint >= 32) { session.terminalInput += codePoint; return true; } - if (activeWindow.type.equals("ANTMAIL") && session.antmailFocused && codePoint >= 32) { - if (session.antmailMode.equals("compose")) { - if (session.antmailField == 1 && session.antmailRecipient.length() < 64) session.antmailRecipient += codePoint; - else if (session.antmailField == 2 && session.antmailSubject.length() < 64) session.antmailSubject += codePoint; - else if (session.antmailField == 3 && session.antmailBody.length() < 16384) session.antmailBody += codePoint; - } else if (Character.isLetterOrDigit(codePoint) || codePoint == '_') session.antmailUsername += Character.toLowerCase(codePoint); - return true; - } - } - return true; - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (!loggedIn) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { onClose(); return true; } - if (keyCode == 259) { - if (confirmingPassword && !confirmation.isEmpty()) confirmation = confirmation.substring(0, confirmation.length() - 1); - else if (!password.isEmpty()) password = password.substring(0, password.length() - 1); - } - else if (keyCode == 257 || keyCode == 335) tryLogin(); - return true; - } - if (activeWindow != null && activeWindow.type.equals("GAMES") && activeWindow.gameOpen) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { - activeWindow.gameOpen = false; - return true; - } - if (activeWindow.gameId.equals("antman") ? antman.keyPressed(keyCode) : activeWindow.gameId.equals("blockle") ? blockle.keyPressed(keyCode) : basilisk.keyPressed(keyCode)) return true; - } - if (activeWindow != null && activeWindow.type.equals("FILES")) { - if (session.fileExplorerDeleteConfirm) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { session.fileExplorerDeleteConfirm = false; return true; } - if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { session.fileExplorerDeleteConfirm = false; deleteSelectedFile(); return true; } - } - if (session.fileExplorerCreatingDirectory) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { if (!session.fileExplorerRename.isEmpty()) session.fileExplorerRename = session.fileExplorerRename.substring(0, session.fileExplorerRename.length() - 1); return true; } - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { session.fileExplorerCreatingDirectory = false; session.fileExplorerRename = ""; return true; } - if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { - if (!session.fileExplorerRename.isBlank()) { - String folder = session.fileExplorerRename.replace("\\", "\\\\").replace("\"", "\\\""); - ComputerNetworking.terminalCommand(position, session.fileExplorerDirectory, "mkdir \"" + folder + "\""); - } - session.fileExplorerCreatingDirectory = false; - session.fileExplorerRename = ""; - ComputerNetworking.listFiles(position); - return true; - } - } - if (session.fileExplorerMoving) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { if (!session.fileExplorerRename.isEmpty()) session.fileExplorerRename = session.fileExplorerRename.substring(0, session.fileExplorerRename.length() - 1); return true; } - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { session.fileExplorerMoving = false; session.fileExplorerRename = ""; return true; } - if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { - if (!session.fileExplorerRename.isBlank() && !session.fileExplorerSelected.isBlank()) { - String destination = session.fileExplorerRename.startsWith("/") - ? ComputerFileSystem.normalize(session.fileExplorerRename) - : ComputerFileSystem.normalize(session.fileExplorerDirectory + "/" + session.fileExplorerRename); - ComputerNetworking.moveFile(position, session.fileExplorerSelected, destination); - } - session.fileExplorerMoving = false; - session.fileExplorerRename = ""; - ComputerNetworking.listFiles(position); - return true; - } - } - if (session.fileExplorerRenaming) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { - if (!session.fileExplorerRename.isEmpty()) session.fileExplorerRename = session.fileExplorerRename.substring(0, session.fileExplorerRename.length() - 1); - return true; - } - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { - session.fileExplorerRenaming = false; - session.fileExplorerRename = ""; - return true; - } - if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { - renameSelectedFile(); - return true; - } - } else if (keyCode == GLFW.GLFW_KEY_R && hasControl(modifiers)) { - beginRenameSelectedFile(); - return true; - } else if (keyCode == GLFW.GLFW_KEY_DELETE) { - session.fileExplorerDeleteConfirm = true; - return true; - } else if (keyCode == GLFW.GLFW_KEY_N && hasControl(modifiers)) { - session.fileExplorerCreatingDirectory = true; - session.fileExplorerRename = ""; - return true; - } else if (keyCode == GLFW.GLFW_KEY_M && hasControl(modifiers) && !session.fileExplorerSelected.isBlank()) { - session.fileExplorerMoving = true; - session.fileExplorerRename = ""; - return true; - } - } - if (activeWindow != null && activeWindow.type.equals("TERMINAL") && session.terminalFocused) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { if (!session.terminalInput.isEmpty()) session.terminalInput = session.terminalInput.substring(0, session.terminalInput.length() - 1); return true; } - if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { executeTerminal(); return true; } - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { session.terminalFocused = false; return true; } - } - - if (activeWindow != null && activeWindow.type.equals("ANTMAIL") && session.antmailFocused) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE && session.antmailPickingAttachment) { - session.antmailPickingAttachment = false; - return true; - } - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { - if (session.antmailMode.equals("compose")) { - if (session.antmailField == 1 && !session.antmailRecipient.isEmpty()) session.antmailRecipient = session.antmailRecipient.substring(0, session.antmailRecipient.length() - 1); - else if (session.antmailField == 2 && !session.antmailSubject.isEmpty()) session.antmailSubject = session.antmailSubject.substring(0, session.antmailSubject.length() - 1); - else if (session.antmailField == 3 && !session.antmailBody.isEmpty()) session.antmailBody = session.antmailBody.substring(0, session.antmailBody.length() - 1); - } else if (!session.antmailUsername.isEmpty()) session.antmailUsername = session.antmailUsername.substring(0, session.antmailUsername.length() - 1); - return true; - } - if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { - if (session.antmailMode.equals("compose")) sendAntmail(); else setupAntmail(); - return true; - } - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { session.antmailFocused = false; return true; } - } - if (activeWindow != null && activeWindow.type.equals("TEXT") && session.textFocused) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { if (session.textCursor > 0) { session.textContent = session.textContent.substring(0, session.textCursor - 1) + session.textContent.substring(session.textCursor); session.textCursor--; session.textDirty = true; } return true; } - if (keyCode == GLFW.GLFW_KEY_DELETE && !hasControl(modifiers)) { if (session.textCursor < session.textContent.length()) { session.textContent = session.textContent.substring(0, session.textCursor) + session.textContent.substring(session.textCursor + 1); session.textDirty = true; } return true; } - if (keyCode == GLFW.GLFW_KEY_LEFT) { session.textCursor = Math.max(0, session.textCursor - 1); return true; } - if (keyCode == GLFW.GLFW_KEY_RIGHT) { session.textCursor = Math.min(session.textContent.length(), session.textCursor + 1); return true; } - if (keyCode == GLFW.GLFW_KEY_UP || keyCode == GLFW.GLFW_KEY_DOWN) { moveTextCursorVertically(keyCode == GLFW.GLFW_KEY_UP); return true; } - if (keyCode == GLFW.GLFW_KEY_HOME) { session.textCursor = session.textContent.lastIndexOf('\n', Math.max(0, session.textCursor - 1)) + 1; return true; } - if (keyCode == GLFW.GLFW_KEY_END) { int next = session.textContent.indexOf('\n', session.textCursor); session.textCursor = next < 0 ? session.textContent.length() : next; return true; } - if (keyCode == GLFW.GLFW_KEY_ENTER) { session.textContent = session.textContent.substring(0, session.textCursor) + "\n" + session.textContent.substring(session.textCursor); session.textCursor++; session.textDirty = true; return true; } - if (keyCode == GLFW.GLFW_KEY_S && hasControl(modifiers) && (modifiers & GLFW.GLFW_MOD_SHIFT) == 0) { saveText(); return true; } - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { session.textFocused = false; return true; } - } - if (activeWindow != null && activeWindow.type.equals("TEXT")) { - if (session.textDeleteConfirm) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { session.textDeleteConfirm = false; return true; } - if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { session.textDeleteConfirm = false; deleteTextFile(); return true; } - } - if (keyCode == GLFW.GLFW_KEY_DELETE && hasControl(modifiers)) { session.textDeleteConfirm = true; session.textFocused = false; return true; } - if (keyCode == GLFW.GLFW_KEY_S && hasControl(modifiers) && (modifiers & GLFW.GLFW_MOD_SHIFT) != 0) { - beginSaveAs(); - return true; - } - if (keyCode == GLFW.GLFW_KEY_R && hasControl(modifiers) && !session.textPath.isBlank()) { - int slash = session.textPath.lastIndexOf('/'); - session.textRename = session.textPath.substring(slash + 1); - session.textRenaming = true; - return true; - } - if (session.textRenaming) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { - if (!session.textRename.isEmpty()) session.textRename = session.textRename.substring(0, session.textRename.length() - 1); - return true; - } - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { - session.textRenaming = false; - session.textRename = ""; - return true; - } - if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { - renameTextFile(); - return true; - } - } - } - if (activeWindow != null && activeWindow.type.equals("ARCHIVE") && session.archiveEntryId != null && keyCode == GLFW.GLFW_KEY_ESCAPE) { - session.archiveEntryId = null; - session.archiveDetailScroll = 0; - return true; - } - if (activeWindow != null && activeWindow.type.equals("ARCHIVE") && session.archiveSearchFocused) { - if (keyCode == GLFW.GLFW_KEY_BACKSPACE) { - if (!session.archiveSearch.isEmpty()) session.archiveSearch = session.archiveSearch.substring(0, session.archiveSearch.length() - 1); - session.archiveScroll = 0; - return true; - } - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { - session.archiveSearchFocused = false; - return true; - } - } - return super.keyPressed(keyCode, scanCode, modifiers); - } - - private void tryLogin() { - if (password.isBlank()) return; - if (accessResult != null && !accessResult.hasPassword()) { - if (!confirmingPassword) { - confirmingPassword = true; - confirmation = ""; - loginMessage = "RETYPE PASSWORD // CONFIRMATION REQUIRED"; - loginMessageTicks = 100; - return; - } - if (!password.equals(confirmation)) { - password = ""; - confirmation = ""; - confirmingPassword = false; - loginMessage = "SETUP ERROR // PASSWORDS DO NOT MATCH"; - loginMessageTicks = 100; - return; - } - ComputerNetworking.setup(position, password); - loginMessage = "INITIALIZING ACCESS // WAITING"; - } else { - ComputerNetworking.login(position, password); - loginMessage = "AUTHENTICATING // WAITING"; - } - loginMessageTicks = 40; - password = ""; - confirmation = ""; - confirmingPassword = false; - } - - private void executeTerminal() { - String input = session.terminalInput.trim(); - if (input.isEmpty()) return; - session.terminalOutput.add(session.terminalDirectory + "> " + input); - ComputerNetworking.terminalCommand(position, session.terminalDirectory, input); - session.terminalInput = ""; - } - - private void requestAntmailState() { - requestAntmailState(false); - } - - private boolean antmailUnconfigured() { - AntmailResultPayload mailbox = AntmailClientState.getMailbox(position); - if (mailbox != null) return mailbox.address().isBlank(); - AntmailResultPayload response = AntmailClientState.get(position); - return response != null && ("unconfigured".equals(response.detail()) - || "address_not_found".equals(response.detail()) - || response.detail().startsWith("registration_failed:")); - } - - private void requestAntmailState(boolean force) { - int folder = session.antmailMode.equals("sent") ? com.craisinlord.antarchy.content.network.AntmailStateRequestPayload.SENT - : session.antmailMode.equals("drafts") ? com.craisinlord.antarchy.content.network.AntmailStateRequestPayload.DRAFTS - : com.craisinlord.antarchy.content.network.AntmailStateRequestPayload.INBOX; - AntmailNetworking.requestState(position, folder, session.antmailPage, force ? 0L : AntmailClientState.getVersion(position)); - if (force) session.antmailStateWaitTicks = 0; - } - - private void setupAntmail() { - if (!loggedIn) { - session.antmailStatus = "SETUP ERROR // SIGN IN TO THE COMPUTER FIRST"; - return; - } - if (!AntmailAddress.isValidUsername(session.antmailUsername)) { - session.antmailStatus = "SETUP ERROR // USE 3-16 LOWERCASE LETTERS, NUMBERS, OR _"; - session.antmailFocused = true; - return; - } - AntmailClientState.clear(position); - AntmailNetworking.setup(position, session.antmailUsername); - session.antmailStatus = "REGISTERING ADDRESS"; - session.antmailRegistrationPending = true; - session.antmailFocused = false; - } - - private void sendAntmail() { - if (!AntmailAddress.isValidAddress(session.antmailRecipient)) { - session.antmailStatus = "SEND ERROR // INVALID RECIPIENT"; - return; - } - if (session.antmailSubject.isBlank() || session.antmailBody.isBlank()) { - session.antmailStatus = "SEND ERROR // SUBJECT AND BODY REQUIRED"; - return; - } - if (session.antmailAttachText && (session.textDirty || session.textPath.isBlank() || session.textPath.contains("untitled") || !session.textPath.equals(session.antmailTextPath))) { - session.antmailStatus = "SEND ERROR // SAVE TEXT FILE FIRST"; - return; - } - if (session.antmailAttachPaint && !session.antmailPaintLoadPendingPath.isBlank()) { - session.antmailStatus = "ATTACHMENT STILL LOADING // TRY AGAIN"; - return; - } - if (session.antmailAttachPaint && session.antmailPaintAttachment == null - && (session.paintDirty || session.paintName.isBlank() || session.paintName.startsWith("UNTITLED") - || !session.antmailPaintPath.endsWith(session.paintName))) { - session.antmailStatus = "SEND ERROR // SAVE PAINTING FIRST"; - return; - } - List attachments = composeAttachments(); - session.antmailSendBaseline = AntmailClientState.get(position); - AntmailNetworking.send(position, session.antmailRecipient, session.antmailSubject, session.antmailBody, attachments); - session.antmailStatus = "SENDING MESSAGE"; - session.antmailSendPending = true; - session.antmailFocused = false; - session.antmailDraftId = null; - session.antmailDraftLoaded = false; - session.antmailPickingAttachment = false; - } - - private void restoreLatestDraft(AntmailResultPayload result) { - if (session.antmailDraftLoaded) return; - AntmailMailbox mailbox = mailbox(result); - if (mailbox == null || mailbox.drafts().isEmpty()) { - session.antmailDraftLoaded = true; - return; - } - restoreDraft(mailbox.drafts().getLast()); - session.antmailStatus = "DRAFT RECOVERED"; - session.antmailDraftLoaded = true; - } - - private void restoreDraft(AntmailDraft draft) { - session.antmailDraftId = draft.id(); - session.antmailRecipient = draft.recipient() == null ? "" : draft.recipient().fullAddress(); - session.antmailSubject = draft.subject(); - session.antmailBody = draft.body(); - session.antmailAttachText = false; - session.antmailAttachPaint = false; - session.antmailPickingAttachment = false; - for (AntmailAttachment attachment : draft.attachments()) { - if (attachment instanceof AntmailAttachment.TextFile text) { - session.antmailAttachText = true; - session.textPath = "/documents/" + text.fileName(); - session.antmailTextPath = session.textPath; - session.textContent = text.contents(); - } else if (attachment instanceof AntmailAttachment.PaintImage paint) { - session.antmailAttachPaint = true; - session.paintName = paint.fileName(); - session.antmailPaintPath = "/pictures/" + paint.fileName(); - session.antmailPaintAttachment = paint; - session.antmailPaintLoadPendingPath = ""; - AntPaintCanvas canvas = new AntPaintCanvas(); - byte[] pixels = paint.pixels(); - for (int index = 0; index < pixels.length; index++) if (pixels[index] == 1) canvas.set(index % AntPaintCanvas.WIDTH, index / AntPaintCanvas.WIDTH, true); - session.paintCanvas = canvas; - } - } - } - - private void saveAntmailDraft() { - try { - if (session.antmailRecipient.isBlank() && session.antmailSubject.isBlank() && session.antmailBody.isBlank()) return; - AntmailResultPayload result = AntmailClientState.getMailbox(position); - AntmailMailbox mailbox = mailbox(result); - if (mailbox == null) return; - AntmailDraft draft = new AntmailDraft(session.antmailDraftId, AntmailAddress.parse(mailbox.address().fullAddress()), - session.antmailRecipient.isBlank() ? null : AntmailAddress.parse(session.antmailRecipient), session.antmailSubject, session.antmailBody, composeAttachments()); - AntmailNetworking.saveDraft(position, draft); - } catch (RuntimeException ignored) { - session.antmailStatus = "DRAFT SAVE ERROR // CHECK RECIPIENT"; - } - } - - private List composeAttachments() { - List attachments = new ArrayList<>(); - if (session.antmailAttachText) attachments.add(new AntmailAttachment.TextFile(session.textPath.substring(session.textPath.lastIndexOf('/') + 1), session.textContent)); - if (session.antmailAttachPaint && session.antmailPaintAttachment != null) { - attachments.add(session.antmailPaintAttachment); - } else if (session.antmailAttachPaint) { - byte[] pixels = new byte[AntPaintCanvas.WIDTH * AntPaintCanvas.HEIGHT]; - for (int py = 0; py < AntPaintCanvas.HEIGHT; py++) for (int px = 0; px < AntPaintCanvas.WIDTH; px++) pixels[py * AntPaintCanvas.WIDTH + px] = (byte) (session.paintCanvas.get(px, py) ? 1 : 0); - attachments.add(new AntmailAttachment.PaintImage(session.paintName, AntPaintCanvas.WIDTH, AntPaintCanvas.HEIGHT, pixels)); - } - return attachments; - } - - private void syncAntmailPaintAttachment() { - String requestedPath = session.antmailPaintLoadPendingPath; - if (requestedPath.isBlank()) return; - ComputerFileSystemClientState.State fileState = ComputerFileSystemClientState.get(position); - if (!requestedPath.equals(fileState.openedPath()) || fileState.openedContents().isBlank()) return; - try { - AntPaintFile file = AntPaintFileCodec.decode(Base64.getDecoder().decode(fileState.openedContents())); - session.paintName = file.filename(); - session.antmailPaintPath = requestedPath; - session.antmailPaintAttachment = AntmailAttachmentFiles.fromPaintFile(file); - session.antmailPaintLoadPendingPath = ""; - session.antmailStatus = "PAINTING ATTACHED // " + file.filename(); - } catch (RuntimeException exception) { - session.antmailPaintLoadPendingPath = ""; - session.antmailStatus = "ATTACHMENT ERROR // INVALID PAINT FILE"; - } - } - - private void saveAntmailAttachment(AntmailAttachment attachment) { - try { - if (attachment instanceof AntmailAttachment.TextFile text) { - String path = "/documents/" + text.fileName(); - if (computerFileExists(path)) ComputerNetworking.saveFile(position, path, text.contents()); - else ComputerNetworking.createFile(position, path, text.contents()); - session.antmailStatus = "ATTACHMENT SAVED // " + text.fileName(); - } else if (attachment instanceof AntmailAttachment.PaintImage paint) { - String name = paint.fileName().endsWith(".antpaint") ? paint.fileName() : paint.fileName() + ".antpaint"; - AntPaintFile file = AntmailAttachmentFiles.toPaintFile(paint, UUID.randomUUID().toString(), 0L, 0L); - String encoded = Base64.getEncoder().encodeToString(AntPaintFileCodec.encode(file)); - String path = "/pictures/" + name; - if (computerFileExists(path)) ComputerNetworking.saveFile(position, path, encoded); - else ComputerNetworking.createFile(position, path, encoded); - session.antmailStatus = "ATTACHMENT SAVED // " + name; - } - ComputerNetworking.listFiles(position); - } catch (RuntimeException exception) { - session.antmailStatus = "ATTACHMENT ERROR // INVALID FILE"; - } - } - - private boolean computerFileExists(String path) { - return ComputerFileSystemClientState.get(position).files().stream().anyMatch(entry -> entry.contains("\t" + path + "\t")); - } - - private void newText() { - session.textPath = "/documents/untitled.txt"; - session.textContent = ""; - session.textCursor = 0; - session.textScroll = 0; - session.textDirty = true; - session.textListing = false; - session.textFocused = true; - } - - private void beginSaveAs() { - int slash = session.textPath.lastIndexOf('/'); - session.textRename = session.textPath.substring(slash + 1); - session.textSaveAs = true; - session.textRenaming = true; - session.textFocused = false; - } - - private void setTextCursorFromMouse(double mouseX, double mouseY, int width) { - if (session.textContent.isEmpty()) { session.textCursor = 0; return; } - StringBuilder line = new StringBuilder(); - int cursor = 0; - int targetLine = Math.max(0, (int) (mouseY / 11)); - int currentLine = 0; - for (int index = 0; index < session.textContent.length(); index++) { - char character = session.textContent.charAt(index); - if (character == '\n' || font.width(line.toString() + character) > width) { - if (currentLine == targetLine) { - session.textCursor = index; - return; - } - currentLine++; - line.setLength(0); - if (character == '\n') continue; - } - line.append(character); - cursor = index + 1; - } - session.textCursor = cursor; - } - - private void moveTextCursorVertically(boolean up) { - int lineStart = session.textContent.lastIndexOf('\n', Math.max(0, session.textCursor - 1)) + 1; - int column = session.textCursor - lineStart; - int target = up ? lineStart - 1 : session.textContent.indexOf('\n', session.textCursor); - if (target < 0) return; - int targetStart = up ? session.textContent.lastIndexOf('\n', target - 1) + 1 : target + 1; - int targetEnd = session.textContent.indexOf('\n', targetStart); - if (targetEnd < 0) targetEnd = session.textContent.length(); - session.textCursor = Math.min(targetStart + column, targetEnd); - } - - private void writeText() { - boolean exists = ComputerFileSystemClientState.get(position).files().stream().anyMatch(entry -> entry.contains("\t" + session.textPath + "\t")); - if (exists) ComputerNetworking.saveFile(position, session.textPath, session.textContent); - else ComputerNetworking.createFile(position, session.textPath, session.textContent); - ComputerNetworking.listFiles(position); - } - - private void saveText() { - boolean exists = ComputerFileSystemClientState.get(position).files().stream().anyMatch(entry -> entry.contains("\t" + session.textPath + "\t")); - if (exists) ComputerNetworking.saveFile(position, session.textPath, session.textContent); - else ComputerNetworking.createFile(position, session.textPath, session.textContent); - ComputerNetworking.listFiles(position); - } - - private void renameTextFile() { - if (!session.textRename.isBlank() && !session.textRename.contains("/") && !ComputerFileSystem.isProtected(session.textPath)) { - String parent = parentDirectory(session.textPath); - String destination = parent.equals("/") ? "/" + session.textRename : parent + "/" + session.textRename; - if (session.textSaveAs) { - session.textSaveAsPendingPath = destination; - ComputerNetworking.createFile(position, destination, session.textContent); - } else { - ComputerNetworking.moveFile(position, session.textPath, destination); - session.textMovePendingPath = destination; - } - ComputerNetworking.listFiles(position); - } - session.textSaveAs = false; - session.textRenaming = false; - session.textRename = ""; - } - - private void savePaint() { - String path = "/pictures/" + session.paintName; - if (!path.endsWith(".antpaint")) path += ".antpaint"; - session.paintName = path.substring(path.lastIndexOf('/') + 1); - AntPaintFile file = new AntPaintFile(UUID.randomUUID().toString(), session.paintName, session.paintCanvas.copy(), 0L, 0L); - String encoded = Base64.getEncoder().encodeToString(AntPaintFileCodec.encode(file)); - String savedPath = path; - boolean exists = ComputerFileSystemClientState.get(position).files().stream().anyMatch(entry -> entry.contains("\t" + savedPath + "\t")); - if (exists) ComputerNetworking.saveFile(position, savedPath, encoded); else ComputerNetworking.createFile(position, savedPath, encoded); - session.antmailPaintPath = savedPath; - session.antmailPaintAttachment = null; - session.antmailPaintLoadPendingPath = ""; - session.paintDirty = false; - ComputerNetworking.listFiles(position); - } - - private void paintTool(int offset) { - session.paintTool = offset < 52 ? AntPaintTool.PENCIL : offset < 108 ? AntPaintTool.ERASER : AntPaintTool.FILL; - } - - private void paintToolbarAction(int index) { - if (index == 0) session.paintTool = AntPaintTool.PENCIL; - else if (index == 1) session.paintTool = AntPaintTool.ERASER; - else if (index == 2) session.paintTool = AntPaintTool.FILL; - else if (index == 3) { - session.paintHistory.record(session.paintCanvas); - session.paintCanvas.clear(); - session.paintDirty = true; - } else if (index == 4 && session.paintHistory.canUndo()) { - session.paintCanvas = session.paintHistory.undo(session.paintCanvas); - session.paintDirty = true; - } else if (index == 5 && session.paintHistory.canRedo()) { - session.paintCanvas = session.paintHistory.redo(session.paintCanvas); - session.paintDirty = true; - } else if (index == 6) { - savePaint(); - } - } - - private void paintAt(double mouseX, double mouseY, int x, int y, int w, int h) { - int size = Math.min(w / AntPaintCanvas.WIDTH, h / AntPaintCanvas.HEIGHT); - if (size <= 0) return; - int canvasX = x + (w - size * AntPaintCanvas.WIDTH) / 2; - int px = (int) ((mouseX - canvasX) / size); - int canvasY = y + Math.max(0, (h - size * AntPaintCanvas.HEIGHT) / 2); - int py = (int) ((mouseY - canvasY) / size); - if (px < 0 || py < 0 || px >= AntPaintCanvas.WIDTH || py >= AntPaintCanvas.HEIGHT) { - lastPaintPixelX = -1; - lastPaintPixelY = -1; - return; - } - if (session.paintTool == AntPaintTool.FILL) { - session.paintHistory.record(session.paintCanvas); - if (session.paintCanvas.floodFill(px, py, true) > 0) session.paintDirty = true; - return; - } - if (lastPaintPixelX < 0 || lastPaintPixelY < 0) applyPaintPixel(px, py); - else { - int dx = Math.abs(px - lastPaintPixelX); - int dy = Math.abs(py - lastPaintPixelY); - int stepX = lastPaintPixelX < px ? 1 : -1; - int stepY = lastPaintPixelY < py ? 1 : -1; - int error = dx - dy; - int currentX = lastPaintPixelX; - int currentY = lastPaintPixelY; - while (currentX != px || currentY != py) { - int twiceError = error * 2; - if (twiceError > -dy) { error -= dy; currentX += stepX; } - if (twiceError < dx) { error += dx; currentY += stepY; } - applyPaintPixel(currentX, currentY); - } - } - lastPaintPixelX = px; - lastPaintPixelY = py; - } - - private void applyPaintPixel(int x, int y) { - boolean changed = session.paintTool == AntPaintTool.PENCIL - ? session.paintCanvas.draw(x, y) - : session.paintCanvas.erase(x, y); - if (changed) session.paintDirty = true; - } - - private boolean hasControl(int modifiers) { - return (modifiers & GLFW.GLFW_MOD_CONTROL) != 0; - } - - private ComputerBlockEntity computer() { - if (Minecraft.getInstance().level == null) return null; - return Minecraft.getInstance().level.getBlockEntity(position) instanceof ComputerBlockEntity computer ? computer : null; - } - - private List physicalDisks() { - ComputerBlockEntity computer = computer(); - if (computer == null) return List.of(); - return computer.diskIds().stream() - .filter(id -> !id.equals(ResourceLocation.fromNamespaceAndPath("antarchy", "introduction"))) - .toList(); - } - - private void ejectSelected() { - if (selectedDisk == null) return; - ComputerNetworking.eject(position, selectedDisk); - loginMessage = "EJECTING DISK // WAITING"; - loginMessageTicks = 100; - selectedDisk = null; - } - - private void beginRenameSelectedFile() { - if (session.fileExplorerSelected.isEmpty() || session.fileExplorerSelected.equals("/") || ComputerFileSystem.isProtected(session.fileExplorerSelected)) return; - int slash = session.fileExplorerSelected.lastIndexOf('/'); - session.fileExplorerRename = session.fileExplorerSelected.substring(slash + 1); - session.fileExplorerRenaming = true; - } - - private void renameSelectedFile() { - if (!session.fileExplorerRename.isBlank() && !session.fileExplorerRename.contains("/")) { - String parent = parentDirectory(session.fileExplorerSelected); - String destination = parent.equals("/") ? "/" + session.fileExplorerRename : parent + "/" + session.fileExplorerRename; - ComputerNetworking.moveFile(position, session.fileExplorerSelected, destination); - session.fileExplorerSelected = destination; - ComputerNetworking.listFiles(position); - } - session.fileExplorerRenaming = false; - session.fileExplorerRename = ""; - } - - private void deleteSelectedFile() { - if (session.fileExplorerSelected.isEmpty() || session.fileExplorerSelected.equals("/") || ComputerFileSystem.isProtected(session.fileExplorerSelected)) return; - ComputerNetworking.deleteFile(position, session.fileExplorerSelected); - session.fileExplorerSelected = ""; - ComputerNetworking.listFiles(position); - } - - private void deleteTextFile() { - if (session.textPath.isBlank() || ComputerFileSystem.isProtected(session.textPath)) return; - ComputerNetworking.deleteFile(position, session.textPath); - session.textPath = "/documents/untitled.txt"; - session.textContent = ""; - session.textCursor = 0; - session.textDirty = false; - ComputerNetworking.listFiles(position); - } - - private void open(String type) { - for (int index = 0; index < session.windows.size(); index++) { - Window window = session.windows.get(index); - if (!window.type.equals(type)) continue; - window.minimized = false; - session.windows.remove(index); - session.windows.add(window); - activeWindow = window; - if (type.equals("FILES")) ComputerNetworking.listFiles(position); - return; - } - Window window = new Window(type, TITLES.get(type), 112 + session.windows.size() * 12, 52 + session.windows.size() * 10); - session.windows.add(window); - activeWindow = window; - if (type.equals("ANTMAIL")) requestAntmailState(); - else if (type.equals("FILES")) ComputerNetworking.listFiles(position); - } - - private Window windowAt(double mouseX, double mouseY) { - float scale = uiScale(); - double localMouseX = (mouseX - width / 2.0F) / scale; - double localMouseY = (mouseY - height / 2.0F) / scale; - int left = -WIDTH / 2; - int top = -HEIGHT / 2; - for (int index = session.windows.size() - 1; index >= 0; index--) { - Window window = session.windows.get(index); - if (window.minimized) continue; - int windowX = left + windowLocalX(window); - int windowY = top + windowLocalY(window); - int renderedWidth = windowWidth(window); - int renderedHeight = windowHeight(window); - if (inside(windowX, windowY + TITLE_BAR_HEIGHT, renderedWidth, renderedHeight - TITLE_BAR_HEIGHT, localMouseX, localMouseY)) return window; - } - return null; - } - - private static boolean inside(int x, int y, int w, int h, double mx, double my) { return mx >= x && mx < x + w && my >= y && my < y + h; } - - @Override - public boolean isPauseScreen() { return false; } - - @Override - public void onClose() { - ComputerNetworking.close(position); - super.onClose(); - } - - private static final class Session { - private boolean authenticated; - private long lastUse; - private final List windows = new ArrayList<>(); - private final List terminalOutput = new ArrayList<>(List.of("ANTINTOSH TERMINAL [READY]", "TYPE HELP FOR COMMANDS")); - private String terminalInput = ""; - private String terminalDirectory = "/"; - private String terminalResponse = ""; - private boolean terminalFocused; - private String textPath = "/documents/untitled.txt"; - private String textContent = ""; - private int textCursor; - private int textScroll; - private boolean textDirty; - private boolean textFocused; - private boolean textListing; - private int textPickerScroll; - private boolean textRenaming; - private boolean textSaveAs; - private String textSaveAsPendingPath = ""; - private String textMovePendingPath = ""; - private boolean textJustSavedAs; - private boolean textDeleteConfirm; - private String textRename = ""; - private ResourceLocation archiveEntryId; - private int archiveScroll; - private String archiveSearch = ""; - private boolean archiveSearchFocused; - private int fileExplorerScroll; - private boolean fileExplorerDeleteConfirm; - private boolean fileExplorerCreatingDirectory; - private boolean fileExplorerMoving; - private int archiveDetailScroll; - private int archiveDetailMaxScroll; - private int archiveMouseX; - private int archiveMouseY; - private int mouseX; - private int mouseY; - private AntPaintCanvas paintCanvas = new AntPaintCanvas(); - private final AntPaintHistory paintHistory = new AntPaintHistory(); - private AntPaintTool paintTool = AntPaintTool.PENCIL; - private String paintName = "UNTITLED.ANTPAINT"; - private boolean paintDirty; - private String antmailUsername = ""; - private String antmailStatus = ""; - private boolean antmailSendPending; - private AntmailResultPayload antmailSendBaseline; - private String antmailRetryMessageId = ""; - private AntmailResultPayload antmailRetryBaseline; - private int antmailRetryTicks; - private boolean antmailRegistrationPending; - private int antmailRefreshTicks; - private int antmailStateWaitTicks; - private boolean antmailFocused; - private String antmailMode = "inbox"; - private String antmailRecipient = ""; - private String antmailSubject = ""; - private String antmailBody = ""; - private int antmailField; - private boolean antmailSent; - private int antmailMessageIndex = -1; - private int antmailPage; - private int antmailAttachmentStartLine = -1; - private int antmailVisibleAttachmentCount; - private boolean antmailAttachText; - private boolean antmailAttachPaint; - private String antmailTextPath = ""; - private String antmailPaintPath = ""; - private AntmailAttachment.PaintImage antmailPaintAttachment; - private String antmailPaintLoadPendingPath = ""; - private UUID antmailDraftId; - private boolean antmailDraftLoaded; - private boolean antmailPickingAttachment; - private String fileExplorerDirectory = "/"; - private String fileExplorerSelected = ""; - private String fileExplorerRename = ""; - private boolean fileExplorerRenaming; - private String wallpaperId = ComputerDesktopState.DEFAULT_WALLPAPER.toString(); - private List wallpapers = List.of(ComputerDesktopState.DEFAULT_WALLPAPER.toString()); - private boolean desktopRequested; - private int bootTicks = -1; - private String basiliskResponse = ""; - private boolean basiliskStateRequested; - private String antmanResponse = ""; - private boolean antmanStateRequested; - private boolean blockleStateRequested; - } - - private static final class Window { - private final String type; - private final String title; - private final int width = 230; - private final int height = 210; - private int x; - private int y; - private int restoreX; - private int restoreY; - private int renderWidth = width; - private int renderHeight = height; - private boolean minimized; - private boolean maximized; - private boolean gameOpen; - private String gameId = "basilisk"; - - private Window(String type, String title, int x, int y) { - this.type = type; - this.title = title; - this.x = x; - this.y = y; - this.restoreX = x; - this.restoreY = y; - } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/AntarchyGameSavedData.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/AntarchyGameSavedData.java new file mode 100644 index 00000000..ca9e45f8 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/AntarchyGameSavedData.java @@ -0,0 +1,75 @@ +package com.craisinlord.antarchy.content.computer; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.saveddata.SavedData; + +/** Persistent Antarchy game progress keyed by AntOS computer location. */ +public final class AntarchyGameSavedData extends SavedData { + private static final String ID = "antarchy_computer_games"; + private final Map games = new HashMap<>(); + + public static AntarchyGameSavedData create() { return new AntarchyGameSavedData(); } + + public static AntarchyGameSavedData load(CompoundTag tag, HolderLookup.Provider registries) { + AntarchyGameSavedData data = new AntarchyGameSavedData(); + for (net.minecraft.nbt.Tag raw : tag.getList("Games", net.minecraft.nbt.Tag.TAG_COMPOUND)) { + CompoundTag item = (CompoundTag) raw; + GameState state = new GameState(); + state.basiliskScore = item.getInt("BasiliskScore"); + state.basiliskHighScore = item.getInt("BasiliskHighScore"); + state.antmanScore = item.getInt("AntmanScore"); + state.antmanHighScore = item.getInt("AntmanHighScore"); + state.blockleDay = item.getLong("BlockleDay"); + for (net.minecraft.nbt.Tag guess : item.getList("BlockleGuesses", net.minecraft.nbt.Tag.TAG_STRING)) state.blockleGuesses.add(guess.getAsString()); + data.games.put(item.getString("Computer"), state); + } + return data; + } + + @Override public CompoundTag save(CompoundTag tag, HolderLookup.Provider registries) { + ListTag list = new ListTag(); + games.forEach((key, state) -> { + CompoundTag item = new CompoundTag(); + item.putString("Computer", key); + item.putInt("BasiliskScore", state.basiliskScore); + item.putInt("BasiliskHighScore", state.basiliskHighScore); + item.putInt("AntmanScore", state.antmanScore); + item.putInt("AntmanHighScore", state.antmanHighScore); + item.putLong("BlockleDay", state.blockleDay); + ListTag guesses = new ListTag(); + state.blockleGuesses.forEach(guess -> guesses.add(net.minecraft.nbt.StringTag.valueOf(guess))); + item.put("BlockleGuesses", guesses); + list.add(item); + }); + tag.put("Games", list); + return tag; + } + + public static GameState get(MinecraftServer server, String key) { + AntarchyGameSavedData data = server.overworld().getDataStorage().computeIfAbsent( + new SavedData.Factory<>(AntarchyGameSavedData::create, AntarchyGameSavedData::load, null), ID); + return data.games.computeIfAbsent(key, ignored -> new GameState()); + } + + public static void changed(MinecraftServer server) { + server.overworld().getDataStorage().computeIfAbsent( + new SavedData.Factory<>(AntarchyGameSavedData::create, AntarchyGameSavedData::load, null), ID).setDirty(); + } + + public static String key(net.minecraft.resources.ResourceLocation dimension, net.minecraft.core.BlockPos pos) { + return dimension + "|" + pos.asLong(); + } + + public static final class GameState { + public int basiliskScore, basiliskHighScore, antmanScore, antmanHighScore; + public long blockleDay = Long.MIN_VALUE; + public final List blockleGuesses = new ArrayList<>(); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/ComputerDesktopState.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/ComputerDesktopState.java deleted file mode 100644 index 87a45062..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/ComputerDesktopState.java +++ /dev/null @@ -1,197 +0,0 @@ -package com.craisinlord.antarchy.content.computer; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.StringTag; -import net.minecraft.resources.ResourceLocation; - -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -public final class ComputerDesktopState { - public static final ResourceLocation DEFAULT_WALLPAPER = ResourceLocation.fromNamespaceAndPath("antarchy", "grid_ant"); - public static final int MAX_UNLOCKED_WALLPAPERS = 64; - public static final int MAX_INSTALLED_PROGRAMS = 64; - public static final int MAX_ICON_POSITIONS = 64; - public static final int MAX_ID_LENGTH = 128; - public static final int MIN_ICON_COORDINATE = 0; - public static final int MAX_ICON_COORDINATE = 4096; - private static final String SELECTED_WALLPAPER_TAG = "SelectedWallpaper"; - private static final String UNLOCKED_WALLPAPERS_TAG = "UnlockedWallpapers"; - private static final String INSTALLED_PROGRAMS_TAG = "InstalledPrograms"; - private static final String ICON_POSITIONS_TAG = "IconPositions"; - private static final String ID_TAG = "Id"; - private static final String X_TAG = "X"; - private static final String Y_TAG = "Y"; - private ResourceLocation selectedWallpaper; - private final Set unlockedWallpaperIds = new LinkedHashSet<>(); - private final Set installedProgramIds = new LinkedHashSet<>(); - private final Map iconPositions = new LinkedHashMap<>(); - - public ResourceLocation selectedWallpaper() { - return selectedWallpaper; - } - - public Set unlockedWallpaperIds() { - return Collections.unmodifiableSet(new LinkedHashSet<>(unlockedWallpaperIds)); - } - - public Set installedProgramIds() { - return Collections.unmodifiableSet(new LinkedHashSet<>(installedProgramIds)); - } - - public Map iconPositions() { - return Collections.unmodifiableMap(new LinkedHashMap<>(iconPositions)); - } - - public boolean hasWallpaper(ResourceLocation id) { - return id != null && unlockedWallpaperIds.contains(id); - } - - public boolean hasProgram(ResourceLocation id) { - return id != null && installedProgramIds.contains(id); - } - - public IconPosition iconPosition(ResourceLocation id) { - return iconPositions.get(id); - } - - public boolean unlockWallpaper(ResourceLocation id) { - if (!validId(id) || unlockedWallpaperIds.contains(id)) { - return false; - } - if (unlockedWallpaperIds.size() >= MAX_UNLOCKED_WALLPAPERS) { - return false; - } - return unlockedWallpaperIds.add(id); - } - - public boolean installProgram(ResourceLocation id) { - if (!validId(id) || installedProgramIds.size() >= MAX_INSTALLED_PROGRAMS && !installedProgramIds.contains(id)) { - return false; - } - return installedProgramIds.add(id); - } - - public boolean uninstallProgram(ResourceLocation id) { - if (id == null || !installedProgramIds.remove(id)) { - return false; - } - iconPositions.remove(id); - return true; - } - - public boolean selectWallpaper(ResourceLocation id) { - if (id != null && !unlockedWallpaperIds.contains(id)) { - return false; - } - if (id == null ? selectedWallpaper == null : id.equals(selectedWallpaper)) { - return false; - } - selectedWallpaper = id; - return true; - } - - public boolean setIconPosition(ResourceLocation id, int x, int y) { - if (!validId(id) || x < MIN_ICON_COORDINATE || x > MAX_ICON_COORDINATE || y < MIN_ICON_COORDINATE || y > MAX_ICON_COORDINATE) { - return false; - } - IconPosition position = new IconPosition(x, y); - if (position.equals(iconPositions.get(id))) { - return false; - } - if (!iconPositions.containsKey(id) && iconPositions.size() >= MAX_ICON_POSITIONS) { - return false; - } - iconPositions.put(id, position); - return true; - } - - public boolean removeIconPosition(ResourceLocation id) { - return id != null && iconPositions.remove(id) != null; - } - - public void clear() { - unlockedWallpaperIds.clear(); - installedProgramIds.clear(); - iconPositions.clear(); - unlockedWallpaperIds.add(DEFAULT_WALLPAPER); - selectedWallpaper = DEFAULT_WALLPAPER; - } - - public CompoundTag save() { - CompoundTag tag = new CompoundTag(); - if (selectedWallpaper != null) { - tag.putString(SELECTED_WALLPAPER_TAG, selectedWallpaper.toString()); - } - tag.put(UNLOCKED_WALLPAPERS_TAG, saveIds(unlockedWallpaperIds)); - tag.put(INSTALLED_PROGRAMS_TAG, saveIds(installedProgramIds)); - ListTag positions = new ListTag(); - for (Map.Entry entry : iconPositions.entrySet()) { - CompoundTag position = new CompoundTag(); - position.putString(ID_TAG, entry.getKey().toString()); - position.putInt(X_TAG, entry.getValue().x()); - position.putInt(Y_TAG, entry.getValue().y()); - positions.add(position); - } - tag.put(ICON_POSITIONS_TAG, positions); - return tag; - } - - public void load(CompoundTag tag) { - clear(); - loadIds(tag.getList(UNLOCKED_WALLPAPERS_TAG, 8), unlockedWallpaperIds, MAX_UNLOCKED_WALLPAPERS); - ResourceLocation storedSelection = parseId(tag.getString(SELECTED_WALLPAPER_TAG)); - selectedWallpaper = storedSelection != null && unlockedWallpaperIds.contains(storedSelection) ? storedSelection : DEFAULT_WALLPAPER; - loadIds(tag.getList(INSTALLED_PROGRAMS_TAG, 8), installedProgramIds, MAX_INSTALLED_PROGRAMS); - ListTag positions = tag.getList(ICON_POSITIONS_TAG, 10); - for (int index = 0; index < positions.size() && iconPositions.size() < MAX_ICON_POSITIONS; index++) { - CompoundTag stored = positions.getCompound(index); - ResourceLocation id = parseId(stored.getString(ID_TAG)); - int x = stored.getInt(X_TAG); - int y = stored.getInt(Y_TAG); - if (id != null && x >= MIN_ICON_COORDINATE && x <= MAX_ICON_COORDINATE && y >= MIN_ICON_COORDINATE && y <= MAX_ICON_COORDINATE) { - iconPositions.putIfAbsent(id, new IconPosition(x, y)); - } - } - } - - private static ListTag saveIds(Collection ids) { - ListTag list = new ListTag(); - for (ResourceLocation id : ids) { - list.add(StringTag.valueOf(id.toString())); - } - return list; - } - - private static void loadIds(ListTag list, Set destination, int limit) { - for (int index = 0; index < list.size() && destination.size() < limit; index++) { - ResourceLocation id = parseId(list.getString(index)); - if (id != null) { - destination.add(id); - } - } - } - - private static ResourceLocation parseId(String value) { - if (value == null || value.isBlank() || value.length() > MAX_ID_LENGTH) { - return null; - } - try { - return ResourceLocation.parse(value); - } catch (Exception ignored) { - return null; - } - } - - private static boolean validId(ResourceLocation id) { - return id != null && id.toString().length() <= MAX_ID_LENGTH; - } - - public record IconPosition(int x, int y) { - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/ComputerFileSystem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/ComputerFileSystem.java deleted file mode 100644 index 3cc24eba..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/ComputerFileSystem.java +++ /dev/null @@ -1,220 +0,0 @@ -package com.craisinlord.antarchy.content.computer; - -import net.minecraft.core.HolderLookup; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.StringTag; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -public final class ComputerFileSystem { - public static final int MAX_FILE_SIZE = 16 * 1024; - public static final int MAX_TOTAL_SIZE = 64 * 1024; - public static final int MAX_NODES = 128; - public static final int MAX_PATH_LENGTH = 64; - public static final String ROOT = "/"; - public static final String DOCUMENTS = "/documents"; - public static final String PICTURES = "/pictures"; - public static final String SYSTEM = "/system"; - private static final String FILES_TAG = "Files"; - private static final String PATH_TAG = "Path"; - private static final String TYPE_TAG = "Type"; - private static final String CONTENTS_TAG = "Contents"; - private final Map nodes = new LinkedHashMap<>(); - private int totalBytes; - - public ComputerFileSystem() { - reset(); - } - - public void reset() { - nodes.clear(); - nodes.put(ROOT, ComputerFile.directory(ROOT)); - nodes.put(DOCUMENTS, ComputerFile.directory(DOCUMENTS)); - nodes.put(PICTURES, ComputerFile.directory(PICTURES)); - nodes.put(SYSTEM, ComputerFile.directory(SYSTEM)); - totalBytes = 0; - } - - public ComputerFile get(String path) { - return nodes.get(normalize(path)); - } - - public List list() { - return List.copyOf(nodes.values()); - } - - public List listTextFiles() { - return nodes.values().stream().filter(file -> file.type() == ComputerFile.Type.TEXT).toList(); - } - - public Result createDirectory(String path) { - String normalized = normalize(path); - if (normalized.isEmpty() || ROOT.equals(normalized) || isProtected(normalized) || nodes.containsKey(normalized) || nodes.size() >= MAX_NODES) return Result.failure("invalid_path"); - int slash = normalized.lastIndexOf('/'); - if (slash > 0 && !nodesDirectory(normalized.substring(0, slash))) return Result.failure("missing_directory"); - nodes.put(normalized, ComputerFile.directory(normalized)); - return Result.ok(); - } - - public Result createTextFile(String path, String contents) { - String normalized = normalize(path); - Result validation = validateTextPath(normalized, contents); - if (!validation.successful()) return validation; - if (nodes.containsKey(normalized)) return Result.failure("already_exists"); - if (nodes.size() >= MAX_NODES) return Result.failure("node_limit"); - int size = contents.length(); - if (totalBytes + size > MAX_TOTAL_SIZE) return Result.failure("storage_limit"); - nodes.put(normalized, ComputerFile.text(normalized, contents)); - totalBytes += size; - return Result.ok(); - } - - public Result writeTextFile(String path, String contents) { - String normalized = normalize(path); - Result validation = validateTextPath(normalized, contents); - if (!validation.successful()) return validation; - ComputerFile current = nodes.get(normalized); - if (current == null) return Result.failure("not_found"); - if (current.type() != ComputerFile.Type.TEXT && current.type() != ComputerFile.Type.IMAGE) return Result.failure("not_file"); - int replacement = totalBytes - current.contents().length() + contents.length(); - if (replacement > MAX_TOTAL_SIZE) return Result.failure("storage_limit"); - nodes.put(normalized, ComputerFile.text(normalized, contents)); - totalBytes = replacement; - return Result.ok(); - } - - public Result createOrWriteTextFile(String path, String contents) { - return nodes.containsKey(normalize(path)) ? writeTextFile(path, contents) : createTextFile(path, contents); - } - - public Result move(String source, String destination) { - String from = normalize(source); - String to = normalize(destination); - if (from.isEmpty() || to.isEmpty() || ROOT.equals(from) || ROOT.equals(to) || isProtected(from) || isProtected(to)) return Result.failure("invalid_path"); - ComputerFile file = nodes.get(from); - if (file == null) return Result.failure("not_found"); - if (nodes.containsKey(to)) return Result.failure("already_exists"); - int slash = to.lastIndexOf('/'); - if (slash > 0 && !nodesDirectory(to.substring(0, slash))) return Result.failure("missing_directory"); - if (file.type() == ComputerFile.Type.DIRECTORY && to.startsWith(from + "/")) return Result.failure("invalid_path"); - if (file.type() == ComputerFile.Type.DIRECTORY) { - List descendants = nodes.keySet().stream() - .filter(path -> path.startsWith(from + "/")) - .toList(); - for (String descendant : descendants) { - String movedPath = to + descendant.substring(from.length()); - if (nodes.containsKey(movedPath)) return Result.failure("already_exists"); - } - Map moved = new LinkedHashMap<>(); - moved.put(to, ComputerFile.directory(to)); - for (String descendant : descendants) { - ComputerFile child = nodes.get(descendant); - String movedPath = to + descendant.substring(from.length()); - moved.put(movedPath, child.type() == ComputerFile.Type.DIRECTORY - ? ComputerFile.directory(movedPath) - : ComputerFile.text(movedPath, child.contents())); - } - nodes.keySet().removeIf(path -> path.equals(from) || path.startsWith(from + "/")); - nodes.putAll(moved); - } else { - nodes.remove(from); - nodes.put(to, ComputerFile.text(to, file.contents())); - } - return Result.ok(); - } - - public Result delete(String path) { - String normalized = normalize(path); - if (isProtected(normalized)) return Result.failure("protected"); - ComputerFile file = nodes.get(normalized); - if (file == null) return Result.failure("not_found"); - if (file.type() == ComputerFile.Type.DIRECTORY && nodes.keySet().stream().anyMatch(key -> !key.equals(normalized) && key.startsWith(normalized + "/"))) { - return Result.failure("not_empty"); - } - nodes.remove(normalized); - totalBytes -= file.contents().length(); - return Result.ok(); - } - - public static String normalize(String path) { - if (path == null || path.isBlank()) return ""; - String value = path.trim().replace('\\', '/'); - if (!value.startsWith("/")) value = "/" + value; - while (value.contains("//")) value = value.replace("//", "/"); - if (value.length() > 1 && value.endsWith("/")) value = value.substring(0, value.length() - 1); - return value; - } - - public static boolean isProtected(String path) { - String normalized = normalize(path); - return normalized.equals(SYSTEM) || normalized.startsWith(SYSTEM + "/"); - } - - public void save(CompoundTag tag, HolderLookup.Provider registries) { - ListTag files = new ListTag(); - for (ComputerFile file : nodes.values()) { - if (ROOT.equals(file.path())) continue; - CompoundTag stored = new CompoundTag(); - stored.putString(PATH_TAG, file.path()); - stored.putString(TYPE_TAG, file.type().name()); - if (file.type() == ComputerFile.Type.TEXT || file.type() == ComputerFile.Type.IMAGE) stored.putString(CONTENTS_TAG, file.contents()); - files.add(stored); - } - tag.put(FILES_TAG, files); - } - - public void load(CompoundTag tag, HolderLookup.Provider registries) { - reset(); - ListTag files = tag.getList(FILES_TAG, 10); - for (int index = 0; index < files.size(); index++) { - CompoundTag stored = files.getCompound(index); - String path = normalize(stored.getString(PATH_TAG)); - if (path.isEmpty() || nodes.containsKey(path) || path.length() > MAX_PATH_LENGTH || isProtected(path)) continue; - String type = stored.getString(TYPE_TAG); - if ("DIRECTORY".equals(type)) { - if (nodes.size() < MAX_NODES) nodes.put(path, ComputerFile.directory(path)); - } else if ("TEXT".equals(type) || "IMAGE".equals(type)) { - String contents = stored.getString(CONTENTS_TAG); - if (contents.length() <= MAX_FILE_SIZE && nodes.size() < MAX_NODES && totalBytes + contents.length() <= MAX_TOTAL_SIZE) { - nodes.put(path, "IMAGE".equals(type) ? ComputerFile.image(path, contents) : ComputerFile.text(path, contents)); - totalBytes += contents.length(); - } - } - } - } - - private Result validateTextPath(String path, String contents) { - if (path.isEmpty() || path.length() > MAX_PATH_LENGTH || ROOT.equals(path) || isProtected(path)) return Result.failure("invalid_path"); - if (contents == null || contents.length() > MAX_FILE_SIZE) return Result.failure("file_limit"); - if (path.contains("..") || path.indexOf('\0') >= 0 || path.indexOf('\n') >= 0 || path.indexOf('\r') >= 0) return Result.failure("invalid_path"); - int slash = path.lastIndexOf('/'); - if (slash > 0 && !nodesDirectory(path.substring(0, slash))) return Result.failure("missing_directory"); - return Result.ok(); - } - - private boolean nodesDirectory(String path) { - ComputerFile parent = nodes.get(path); - return parent != null && parent.type() == ComputerFile.Type.DIRECTORY; - } - - public int totalBytes() { - return totalBytes; - } - - public record Result(boolean successful, String error) { - public static Result ok() { return new Result(true, ""); } - public static Result failure(String error) { return new Result(false, error); } - } - - public record ComputerFile(String path, Type type, String contents) { - public static ComputerFile directory(String path) { return new ComputerFile(path, Type.DIRECTORY, ""); } - public static ComputerFile text(String path, String contents) { return path.endsWith(".antpaint") ? image(path, contents) : new ComputerFile(path, Type.TEXT, contents); } - public static ComputerFile image(String path, String contents) { return new ComputerFile(path, Type.IMAGE, contents); } - public enum Type { DIRECTORY, TEXT, IMAGE } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintCanvas.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintCanvas.java deleted file mode 100644 index 1e1ff637..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintCanvas.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.craisinlord.antarchy.content.computer.paint; - -import java.util.ArrayDeque; -import java.util.Arrays; - -public final class AntPaintCanvas { - public static final int WIDTH = 32; - public static final int HEIGHT = 24; - public static final int PIXEL_COUNT = WIDTH * HEIGHT; - public static final int PACKED_LENGTH = (PIXEL_COUNT + 7) / 8; - - private final boolean[] pixels; - - public AntPaintCanvas() { - this.pixels = new boolean[PIXEL_COUNT]; - } - - private AntPaintCanvas(boolean[] pixels) { - this.pixels = pixels; - } - - public boolean get(int x, int y) { - return pixels[index(x, y)]; - } - - public void set(int x, int y, boolean value) { - pixels[index(x, y)] = value; - } - - public boolean draw(int x, int y) { - return setIfChanged(x, y, true); - } - - public boolean erase(int x, int y) { - return setIfChanged(x, y, false); - } - - public void clear() { - Arrays.fill(pixels, false); - } - - public int floodFill(int x, int y, boolean value) { - int start = index(x, y); - boolean original = pixels[start]; - if (original == value) { - return 0; - } - ArrayDeque queue = new ArrayDeque<>(); - boolean[] visited = new boolean[PIXEL_COUNT]; - queue.add(start); - int changed = 0; - while (!queue.isEmpty()) { - int current = queue.removeFirst(); - if (visited[current] || pixels[current] != original) { - continue; - } - visited[current] = true; - pixels[current] = value; - changed++; - int px = current % WIDTH; - int py = current / WIDTH; - if (px > 0) queue.add(current - 1); - if (px + 1 < WIDTH) queue.add(current + 1); - if (py > 0) queue.add(current - WIDTH); - if (py + 1 < HEIGHT) queue.add(current + WIDTH); - } - return changed; - } - - public byte[] pack() { - byte[] packed = new byte[PACKED_LENGTH]; - for (int i = 0; i < PIXEL_COUNT; i++) { - if (pixels[i]) { - packed[i / 8] |= (byte) (1 << (i % 8)); - } - } - return packed; - } - - public static AntPaintCanvas unpack(byte[] packed) { - if (packed == null || packed.length != PACKED_LENGTH) { - throw new IllegalArgumentException("Invalid AntPaint pixel data length"); - } - boolean[] pixels = new boolean[PIXEL_COUNT]; - for (int i = 0; i < PIXEL_COUNT; i++) { - pixels[i] = (packed[i / 8] & (1 << (i % 8))) != 0; - } - return new AntPaintCanvas(pixels); - } - - public AntPaintCanvas copy() { - return new AntPaintCanvas(Arrays.copyOf(pixels, pixels.length)); - } - - public boolean[] copyPixels() { - return Arrays.copyOf(pixels, pixels.length); - } - - private boolean setIfChanged(int x, int y, boolean value) { - int index = index(x, y); - if (pixels[index] == value) { - return false; - } - pixels[index] = value; - return true; - } - - private static int index(int x, int y) { - if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) { - throw new IndexOutOfBoundsException("AntPaint pixel outside canvas"); - } - return y * WIDTH + x; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintFile.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintFile.java deleted file mode 100644 index 3c528337..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintFile.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.craisinlord.antarchy.content.computer.paint; - -import java.util.Objects; - -public record AntPaintFile(String fileId, String filename, AntPaintCanvas canvas, long createdTime, long modifiedTime) { - public AntPaintFile { - Objects.requireNonNull(fileId, "fileId"); - filename = AntPaintFilename.normalize(filename); - Objects.requireNonNull(canvas, "canvas"); - if (fileId.isBlank()) { - throw new IllegalArgumentException("fileId cannot be blank"); - } - } - - public AntPaintFile copy() { - return new AntPaintFile(fileId, filename, canvas.copy(), createdTime, modifiedTime); - } - - public AntPaintFile withCanvas(AntPaintCanvas value, long modified) { - return new AntPaintFile(fileId, filename, value, createdTime, modified); - } - - public AntPaintFile withFilename(String value, long modified) { - return new AntPaintFile(fileId, value, canvas, createdTime, modified); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintFileCodec.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintFileCodec.java deleted file mode 100644 index 960c1acf..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintFileCodec.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.craisinlord.antarchy.content.computer.paint; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -public final class AntPaintFileCodec { - public static final int VERSION = 1; - public static final int MAX_ENCODED_BYTES = 1024; - private static final int MAGIC = 0x41505431; - - private AntPaintFileCodec() { - } - - public static byte[] encode(AntPaintFile file) { - try { - ByteArrayOutputStream output = new ByteArrayOutputStream(MAX_ENCODED_BYTES); - DataOutputStream data = new DataOutputStream(output); - data.writeInt(MAGIC); - data.writeByte(VERSION); - writeString(data, file.fileId()); - writeString(data, file.filename()); - data.writeLong(file.createdTime()); - data.writeLong(file.modifiedTime()); - data.writeByte(AntPaintCanvas.WIDTH); - data.writeByte(AntPaintCanvas.HEIGHT); - data.write(file.canvas().pack()); - data.flush(); - byte[] encoded = output.toByteArray(); - if (encoded.length > MAX_ENCODED_BYTES) { - throw new IllegalArgumentException("AntPaint file exceeds encoded size limit"); - } - return encoded; - } catch (IOException exception) { - throw new IllegalStateException("Unable to encode AntPaint file", exception); - } - } - - public static AntPaintFile decode(byte[] encoded) { - if (encoded == null || encoded.length > MAX_ENCODED_BYTES) { - throw new IllegalArgumentException("Invalid AntPaint file size"); - } - try { - DataInputStream data = new DataInputStream(new ByteArrayInputStream(encoded)); - if (data.readInt() != MAGIC || data.readUnsignedByte() != VERSION) { - throw new IllegalArgumentException("Unsupported AntPaint file format"); - } - String fileId = readString(data, 128); - String filename = readString(data, AntPaintFilename.MAX_LENGTH + AntPaintFilename.EXTENSION.length()); - long created = data.readLong(); - long modified = data.readLong(); - if (data.readUnsignedByte() != AntPaintCanvas.WIDTH || data.readUnsignedByte() != AntPaintCanvas.HEIGHT) { - throw new IllegalArgumentException("Unsupported AntPaint canvas size"); - } - byte[] pixels = data.readNBytes(AntPaintCanvas.PACKED_LENGTH); - if (pixels.length != AntPaintCanvas.PACKED_LENGTH || data.available() != 0) { - throw new IllegalArgumentException("Invalid AntPaint pixel payload"); - } - return new AntPaintFile(fileId, filename, AntPaintCanvas.unpack(pixels), created, modified); - } catch (IOException exception) { - throw new IllegalArgumentException("Invalid AntPaint file data", exception); - } - } - - private static void writeString(DataOutputStream data, String value) throws IOException { - byte[] bytes = value.getBytes(StandardCharsets.UTF_8); - if (bytes.length > 128) { - throw new IllegalArgumentException("AntPaint string exceeds size limit"); - } - data.writeShort(bytes.length); - data.write(bytes); - } - - private static String readString(DataInputStream data, int maxBytes) throws IOException { - int length = data.readUnsignedShort(); - if (length > maxBytes) { - throw new IllegalArgumentException("AntPaint string exceeds size limit"); - } - byte[] bytes = new byte[length]; - data.readFully(bytes); - return new String(bytes, StandardCharsets.UTF_8); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintFilename.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintFilename.java deleted file mode 100644 index 3beefbcb..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintFilename.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.craisinlord.antarchy.content.computer.paint; - -import java.util.Locale; -import java.util.regex.Pattern; - -public final class AntPaintFilename { - public static final int MAX_LENGTH = 32; - public static final String EXTENSION = ".antpaint"; - private static final Pattern SAFE_NAME = Pattern.compile("[A-Za-z0-9 _.-]+"); - - private AntPaintFilename() { - } - - public static boolean isValid(String filename) { - if (filename == null || filename.isBlank() || filename.length() > MAX_LENGTH) { - return false; - } - if (filename.equals(".") || filename.equals("..") || filename.contains("..")) { - return false; - } - return SAFE_NAME.matcher(filename).matches(); - } - - public static String normalize(String filename) { - if (filename == null) { - throw new IllegalArgumentException("Filename cannot be null"); - } - String value = filename.trim(); - if (value.toLowerCase(Locale.ROOT).endsWith(EXTENSION)) { - value = value.substring(0, value.length() - EXTENSION.length()); - } - value = value.trim(); - if (!isValid(value)) { - throw new IllegalArgumentException("Invalid AntPaint filename"); - } - return value + EXTENSION; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintHistory.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintHistory.java deleted file mode 100644 index 9e7b0b58..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintHistory.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.craisinlord.antarchy.content.computer.paint; - -import java.util.ArrayDeque; - -public final class AntPaintHistory { - public static final int MAX_STATES = 32; - - private final ArrayDeque undo = new ArrayDeque<>(); - private final ArrayDeque redo = new ArrayDeque<>(); - - public void record(AntPaintCanvas canvas) { - undo.addLast(canvas.copy()); - while (undo.size() > MAX_STATES) { - undo.removeFirst(); - } - redo.clear(); - } - - public boolean canUndo() { - return !undo.isEmpty(); - } - - public boolean canRedo() { - return !redo.isEmpty(); - } - - public AntPaintCanvas undo(AntPaintCanvas current) { - if (undo.isEmpty()) { - return current; - } - redo.addLast(current.copy()); - return undo.removeLast().copy(); - } - - public AntPaintCanvas redo(AntPaintCanvas current) { - if (redo.isEmpty()) { - return current; - } - undo.addLast(current.copy()); - return redo.removeLast().copy(); - } - - public void clear() { - undo.clear(); - redo.clear(); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintRequests.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintRequests.java deleted file mode 100644 index a2830775..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintRequests.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.craisinlord.antarchy.content.computer.paint; - -import java.util.Objects; - -public final class AntPaintRequests { - private AntPaintRequests() { - } - - public record Save(String computerId, AntPaintFile file) { - public Save { - Objects.requireNonNull(computerId, "computerId"); - Objects.requireNonNull(file, "file"); - } - } - - public record Load(String computerId, String fileId) { - public Load { - Objects.requireNonNull(computerId, "computerId"); - Objects.requireNonNull(fileId, "fileId"); - } - } - - public record List(String computerId) { - public List { - Objects.requireNonNull(computerId, "computerId"); - } - } - - public record Delete(String computerId, String fileId) { - public Delete { - Objects.requireNonNull(computerId, "computerId"); - Objects.requireNonNull(fileId, "fileId"); - } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintResults.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintResults.java deleted file mode 100644 index d5ca9707..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintResults.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.craisinlord.antarchy.content.computer.paint; - -import java.util.List; - -public final class AntPaintResults { - private AntPaintResults() { - } - - public enum Code { - SUCCESS, - UNAUTHENTICATED, - OUT_OF_RANGE, - INVALID_FILENAME, - INVALID_FILE, - FILE_NOT_FOUND, - DUPLICATE_FILE, - STORAGE_FULL, - PAYLOAD_TOO_LARGE, - BUSY, - UNKNOWN_ERROR - } - - public record Save(Code code, String fileId) { - } - - public record Load(Code code, AntPaintFile file) { - } - - public record List(Code code, java.util.List files) { - public List { - files = files == null ? java.util.List.of() : java.util.List.copyOf(files); - } - } - - public record Delete(Code code, String fileId) { - } - - public record AntPaintFileMetadata(String fileId, String filename, long modifiedTime) { - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintTool.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintTool.java deleted file mode 100644 index 68c6088e..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/paint/AntPaintTool.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.craisinlord.antarchy.content.computer.paint; - -public enum AntPaintTool { - PENCIL, - ERASER, - FILL -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalCommand.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalCommand.java deleted file mode 100644 index b4a79272..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalCommand.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.craisinlord.antarchy.content.computer.terminal; - -import java.util.List; - -public record TerminalCommand(String name, List arguments, String rawInput) { - public TerminalCommand { - name = name.toLowerCase(java.util.Locale.ROOT); - arguments = List.copyOf(arguments); - rawInput = rawInput == null ? "" : rawInput; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalCommandParser.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalCommandParser.java deleted file mode 100644 index 330f82fa..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalCommandParser.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.craisinlord.antarchy.content.computer.terminal; - -import java.util.ArrayList; -import java.util.List; - -public final class TerminalCommandParser { - private static final int MAX_INPUT_LENGTH = 256; - - private TerminalCommandParser() { - } - - public static ParseResult parse(String input) { - if (input == null) { - return ParseResult.error("ERROR: EMPTY INPUT"); - } - if (input.length() > MAX_INPUT_LENGTH) { - return ParseResult.error("ERROR: COMMAND TOO LONG"); - } - String trimmed = input.trim(); - if (trimmed.isEmpty()) { - return ParseResult.error("ERROR: EMPTY INPUT"); - } - List tokens = new ArrayList<>(); - StringBuilder token = new StringBuilder(); - Character quote = null; - boolean escaped = false; - for (int index = 0; index < trimmed.length(); index++) { - char character = trimmed.charAt(index); - if (escaped) { - token.append(character); - escaped = false; - } else if (character == '\\') { - escaped = true; - } else if (quote != null) { - if (character == quote) { - quote = null; - } else { - token.append(character); - } - } else if (character == '\'' || character == '"') { - quote = character; - } else if (Character.isWhitespace(character)) { - if (!token.isEmpty()) { - tokens.add(token.toString()); - token.setLength(0); - } - } else { - token.append(character); - } - } - if (escaped) { - token.append('\\'); - } - if (quote != null) { - return ParseResult.error("ERROR: UNTERMINATED QUOTE"); - } - if (!token.isEmpty()) { - tokens.add(token.toString()); - } - if (tokens.isEmpty()) { - return ParseResult.error("ERROR: EMPTY INPUT"); - } - return ParseResult.success(new TerminalCommand(tokens.get(0), tokens.subList(1, tokens.size()), input)); - } - - public record ParseResult(TerminalCommand command, String error) { - public boolean isSuccess() { - return command != null; - } - - public static ParseResult success(TerminalCommand command) { - return new ParseResult(command, null); - } - - public static ParseResult error(String message) { - return new ParseResult(null, message); - } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalCommandService.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalCommandService.java deleted file mode 100644 index 1fbe556b..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalCommandService.java +++ /dev/null @@ -1,207 +0,0 @@ -package com.craisinlord.antarchy.content.computer.terminal; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Locale; -import java.util.Optional; - -public final class TerminalCommandService { - private static final int MAX_ARGUMENT_LENGTH = 128; - private static final List COMMANDS = List.of( - "help", "clear", "pwd", "ls", "cd", "mkdir", "touch", "cat", "write", "rm", "rmdir", "mv", "open" - ); - - public TerminalResult execute(TerminalFileSystem fileSystem, String workingDirectory, String input) { - String currentDirectory = normalizeWorkingDirectory(fileSystem, workingDirectory); - TerminalCommandParser.ParseResult parsed = TerminalCommandParser.parse(input); - if (!parsed.isSuccess()) { - return TerminalResult.error(currentDirectory, parsed.error()); - } - TerminalCommand command = parsed.command(); - if (command.arguments().stream().anyMatch(argument -> argument.length() > MAX_ARGUMENT_LENGTH)) { - return TerminalResult.error(currentDirectory, "ERROR: ARGUMENT TOO LONG"); - } - return switch (command.name()) { - case "help" -> help(currentDirectory, command); - case "clear" -> requireArguments(currentDirectory, command, 0, TerminalResult.clear(currentDirectory)); - case "pwd" -> requireArguments(currentDirectory, command, 0, TerminalResult.success(currentDirectory, currentDirectory)); - case "ls" -> list(fileSystem, currentDirectory, command); - case "cd" -> changeDirectory(fileSystem, currentDirectory, command); - case "mkdir" -> createDirectory(fileSystem, currentDirectory, command); - case "touch" -> createFile(fileSystem, currentDirectory, command); - case "cat" -> readFile(fileSystem, currentDirectory, command); - case "write" -> writeFile(fileSystem, currentDirectory, command); - case "rm" -> removeFile(fileSystem, currentDirectory, command); - case "rmdir" -> removeDirectory(fileSystem, currentDirectory, command); - case "mv" -> move(fileSystem, currentDirectory, command); - case "open" -> open(fileSystem, currentDirectory, command); - default -> TerminalResult.error(currentDirectory, "ERROR: INVALID COMMAND: " + command.name()); - }; - } - - private TerminalResult help(String workingDirectory, TerminalCommand command) { - if (command.arguments().isEmpty()) { - return TerminalResult.success(workingDirectory, - "AVAILABLE COMMANDS", - "HELP CLEAR PWD LS CD MKDIR TOUCH CAT WRITE RM RMDIR MV OPEN"); - } - if (command.arguments().size() != 1) { - return usage(workingDirectory, "help [command]"); - } - return switch (command.arguments().get(0).toLowerCase(Locale.ROOT)) { - case "help" -> TerminalResult.success(workingDirectory, "HELP [COMMAND] // SHOW COMMAND HELP"); - case "clear" -> TerminalResult.success(workingDirectory, "CLEAR // CLEAR TERMINAL OUTPUT"); - case "pwd" -> TerminalResult.success(workingDirectory, "PWD // PRINT WORKING DIRECTORY"); - case "ls" -> TerminalResult.success(workingDirectory, "LS [PATH] // LIST DIRECTORY CONTENTS"); - case "cd" -> TerminalResult.success(workingDirectory, "CD [PATH] // CHANGE WORKING DIRECTORY"); - case "mkdir" -> TerminalResult.success(workingDirectory, "MKDIR // CREATE DIRECTORY"); - case "touch" -> TerminalResult.success(workingDirectory, "TOUCH // CREATE EMPTY TEXT FILE"); - case "cat" -> TerminalResult.success(workingDirectory, "CAT // PRINT TEXT FILE"); - case "write" -> TerminalResult.success(workingDirectory, "WRITE [TEXT] // REPLACE TEXT FILE CONTENTS"); - case "rm" -> TerminalResult.success(workingDirectory, "RM // DELETE TEXT FILE"); - case "rmdir" -> TerminalResult.success(workingDirectory, "RMDIR // DELETE EMPTY DIRECTORY"); - case "mv" -> TerminalResult.success(workingDirectory, "MV // MOVE OR RENAME"); - case "open" -> TerminalResult.success(workingDirectory, "OPEN // OPEN TEXT FILE IN ANTTEXT"); - default -> TerminalResult.error(workingDirectory, "ERROR: NO HELP FOR " + command.arguments().get(0)); - }; - } - - private TerminalResult list(TerminalFileSystem fileSystem, String workingDirectory, TerminalCommand command) { - if (command.arguments().size() > 1) { - return usage(workingDirectory, "ls [path]"); - } - String path = command.arguments().isEmpty() ? workingDirectory : command.arguments().get(0); - Optional entry = find(fileSystem, path, workingDirectory); - if (entry.isEmpty()) { - return missing(workingDirectory, path); - } - if (!entry.get().isDirectory()) { - return TerminalResult.success(workingDirectory, entry.get().name()); - } - List entries = new ArrayList<>(fileSystem.list(path, workingDirectory)); - entries.sort(Comparator.comparing(TerminalFileSystem.Entry::isDirectory).reversed().thenComparing(TerminalFileSystem.Entry::name)); - if (entries.isEmpty()) { - return TerminalResult.success(workingDirectory, "DIRECTORY EMPTY"); - } - return new TerminalResult(TerminalResult.Status.SUCCESS, entries.stream() - .map(value -> (value.isDirectory() ? "[DIR] " : " ") + value.name()).toList(), workingDirectory, false, null); - } - - private TerminalResult changeDirectory(TerminalFileSystem fileSystem, String workingDirectory, TerminalCommand command) { - if (command.arguments().size() > 1) { - return usage(workingDirectory, "cd [path]"); - } - String path = command.arguments().isEmpty() ? TerminalFileSystem.ROOT_PATH : command.arguments().get(0); - Optional entry = find(fileSystem, path, workingDirectory); - if (entry.isEmpty() || !entry.get().isDirectory()) { - return missing(workingDirectory, path); - } - return TerminalResult.success(entry.get().path(), entry.get().path()); - } - - private TerminalResult createDirectory(TerminalFileSystem fileSystem, String workingDirectory, TerminalCommand command) { - if (command.arguments().size() != 1) { - return usage(workingDirectory, "mkdir "); - } - return fileSystem.createDirectory(command.arguments().get(0), workingDirectory) - ? TerminalResult.success(workingDirectory) - : TerminalResult.error(workingDirectory, "ERROR: CANNOT CREATE DIRECTORY"); - } - - private TerminalResult createFile(TerminalFileSystem fileSystem, String workingDirectory, TerminalCommand command) { - if (command.arguments().size() != 1) { - return usage(workingDirectory, "touch "); - } - return fileSystem.createFile(command.arguments().get(0), workingDirectory) - ? TerminalResult.success(workingDirectory) - : TerminalResult.error(workingDirectory, "ERROR: CANNOT CREATE FILE"); - } - - private TerminalResult readFile(TerminalFileSystem fileSystem, String workingDirectory, TerminalCommand command) { - if (command.arguments().size() != 1) { - return usage(workingDirectory, "cat "); - } - Optional contents = fileSystem.readText(command.arguments().get(0), workingDirectory); - return contents.map(value -> TerminalResult.success(workingDirectory, value.split("\\R", -1))) - .orElseGet(() -> missing(workingDirectory, command.arguments().get(0))); - } - - private TerminalResult writeFile(TerminalFileSystem fileSystem, String workingDirectory, TerminalCommand command) { - if (command.arguments().size() < 1 || command.arguments().size() > 2) { - return usage(workingDirectory, "write [text]"); - } - String contents = command.arguments().size() == 2 ? command.arguments().get(1) : ""; - return fileSystem.writeText(command.arguments().get(0), workingDirectory, contents) - ? TerminalResult.success(workingDirectory) - : TerminalResult.error(workingDirectory, "ERROR: CANNOT WRITE FILE"); - } - - private TerminalResult removeFile(TerminalFileSystem fileSystem, String workingDirectory, TerminalCommand command) { - if (command.arguments().size() != 1) { - return usage(workingDirectory, "rm "); - } - return fileSystem.deleteFile(command.arguments().get(0), workingDirectory) - ? TerminalResult.success(workingDirectory) - : TerminalResult.error(workingDirectory, "ERROR: CANNOT DELETE FILE"); - } - - private TerminalResult removeDirectory(TerminalFileSystem fileSystem, String workingDirectory, TerminalCommand command) { - if (command.arguments().size() != 1) { - return usage(workingDirectory, "rmdir "); - } - return fileSystem.deleteEmptyDirectory(command.arguments().get(0), workingDirectory) - ? TerminalResult.success(workingDirectory) - : TerminalResult.error(workingDirectory, "ERROR: DIRECTORY NOT EMPTY OR NOT FOUND"); - } - - private TerminalResult move(TerminalFileSystem fileSystem, String workingDirectory, TerminalCommand command) { - if (command.arguments().size() != 2) { - return usage(workingDirectory, "mv "); - } - return fileSystem.move(command.arguments().get(0), command.arguments().get(1), workingDirectory) - ? TerminalResult.success(workingDirectory) - : TerminalResult.error(workingDirectory, "ERROR: CANNOT MOVE PATH"); - } - - private TerminalResult open(TerminalFileSystem fileSystem, String workingDirectory, TerminalCommand command) { - if (command.arguments().size() != 1) { - return usage(workingDirectory, "open "); - } - Optional entry = find(fileSystem, command.arguments().get(0), workingDirectory); - if (entry.isEmpty() || entry.get().isDirectory()) { - return missing(workingDirectory, command.arguments().get(0)); - } - return TerminalResult.open(workingDirectory, entry.get().path()); - } - - private Optional find(TerminalFileSystem fileSystem, String path, String workingDirectory) { - try { - return fileSystem.find(path, workingDirectory); - } catch (RuntimeException ignored) { - return Optional.empty(); - } - } - - private String normalizeWorkingDirectory(TerminalFileSystem fileSystem, String workingDirectory) { - try { - String normalized = fileSystem.normalize(workingDirectory, TerminalFileSystem.ROOT_PATH); - Optional entry = fileSystem.find(normalized, TerminalFileSystem.ROOT_PATH); - return entry.filter(TerminalFileSystem.Entry::isDirectory).map(TerminalFileSystem.Entry::path).orElse(TerminalFileSystem.ROOT_PATH); - } catch (RuntimeException ignored) { - return TerminalFileSystem.ROOT_PATH; - } - } - - private TerminalResult missing(String workingDirectory, String path) { - return TerminalResult.error(workingDirectory, "ERROR: PATH NOT FOUND: " + path); - } - - private TerminalResult usage(String workingDirectory, String usage) { - return TerminalResult.error(workingDirectory, "USAGE: " + usage); - } - - private TerminalResult requireArguments(String workingDirectory, TerminalCommand command, int count, TerminalResult result) { - return command.arguments().size() == count ? result : usage(workingDirectory, command.name() + " requires " + count + " arguments"); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalFileSystem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalFileSystem.java deleted file mode 100644 index c1ff3701..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalFileSystem.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.craisinlord.antarchy.content.computer.terminal; - -import java.util.List; -import java.util.Optional; - -public interface TerminalFileSystem { - String ROOT_PATH = "/"; - - Optional find(String path, String workingDirectory); - - List list(String path, String workingDirectory); - - boolean createDirectory(String path, String workingDirectory); - - boolean createFile(String path, String workingDirectory); - - Optional readText(String path, String workingDirectory); - - boolean writeText(String path, String workingDirectory, String contents); - - boolean deleteFile(String path, String workingDirectory); - - boolean deleteEmptyDirectory(String path, String workingDirectory); - - boolean move(String source, String destination, String workingDirectory); - - String normalize(String path, String workingDirectory); - - record Entry(String name, String path, EntryType type) { - public boolean isDirectory() { - return type == EntryType.DIRECTORY; - } - } - - enum EntryType { - FILE, - DIRECTORY - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalResult.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalResult.java deleted file mode 100644 index 02304226..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/computer/terminal/TerminalResult.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.craisinlord.antarchy.content.computer.terminal; - -import java.util.List; - -public record TerminalResult(Status status, List lines, String workingDirectory, boolean clearOutput, String openPath) { - public TerminalResult { - status = status == null ? Status.ERROR : status; - lines = List.copyOf(lines); - workingDirectory = workingDirectory == null || workingDirectory.isBlank() ? TerminalFileSystem.ROOT_PATH : workingDirectory; - } - - public static TerminalResult success(String workingDirectory, String... lines) { - return new TerminalResult(Status.SUCCESS, List.of(lines), workingDirectory, false, null); - } - - public static TerminalResult error(String workingDirectory, String... lines) { - return new TerminalResult(Status.ERROR, List.of(lines), workingDirectory, false, null); - } - - public static TerminalResult clear(String workingDirectory) { - return new TerminalResult(Status.SUCCESS, List.of(), workingDirectory, true, null); - } - - public static TerminalResult open(String workingDirectory, String path) { - return new TerminalResult(Status.OPEN, List.of("OPENING " + path), workingDirectory, false, path); - } - - public enum Status { - SUCCESS, - ERROR, - OPEN - } -} 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 4f833207..5f96df3d 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 @@ -38,6 +38,8 @@ public final class CreativeTabContents { } private static final List CATALOG = List.of( + entry("bug_spray", "tools"), + entry("ant_trap", "building_blocks"), entry("ouranwood_log", "building_blocks"), entry("ouranwood_wood", "building_blocks"), entry("mossy_ouranwood_log", "building_blocks"), @@ -395,8 +397,6 @@ public final class CreativeTabContents { entry("lucid_anchor", "tools_and_utilities"), entry("undertrial_spawner", "tools_and_utilities"), entry("undervault", "tools_and_utilities"), - entry("computer", "functional_blocks"), - entry("floppy_disk", "tools_and_utilities"), entry("undertrial_key", "tools_and_utilities"), entry("reverie_bottle", "tools_and_utilities"), entry("glimmer_bottle", "tools_and_utilities"), @@ -641,8 +641,8 @@ public final class CreativeTabContents { } for (String diskId : List.of("antarchy:introduction", "antarchy:chronosphere", "antarchy:toreterror_arena", "antarchy:high_fructose_corn_syrup", "antarchy:elythia", "antarchy:flying_squirrel", "antarchy:cavaryn", "antarchy:thoraxis", "antarchy:temporal_fields", "antarchy:bloodglass", "antarchy:vortex")) { - ItemStack disk = new ItemStack(AntarchyObjects.FLOPPY_DISK.get()); - disk.set(AntarchyObjects.FLOPPY_DISK_COMPONENT.get(), ResourceLocation.parse(diskId)); + ItemStack disk = new ItemStack(com.craisinlord.antos.content.AntOSObjects.FLOPPY_DISK.get()); + disk.set(com.craisinlord.antos.content.AntOSObjects.FLOPPY_DISK_COMPONENT.get(), ResourceLocation.parse(diskId)); output.accept(disk); } } 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..e9175ed5 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 @@ -6,6 +6,7 @@ import com.craisinlord.antarchy.content.gravity.AntarchyGravityTransition; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.EntityType; public final class InvertedMobEffect extends MobEffect { private static final AntarchyGravityTransition EFFECT_TRANSITION = new AntarchyGravityTransition(12); @@ -17,6 +18,14 @@ public final class InvertedMobEffect extends MobEffect { @Override public boolean applyEffectTick(LivingEntity entity, int amplifier) { + // Vex flight steering is authored around vanilla gravity and ground contact. Rotating its + // gravity frame makes the native flight controller drive it into terrain. + if (entity.getType() == EntityType.VEX) { + if (!entity.level().isClientSide()) { + AntarchyGravityApi.clearForcedGravity(entity); + } + return true; + } if (!entity.level().isClientSide()) { if (AntarchyGravityApi.getGravityDirection(entity) != AntarchyGravityDirection.UP || !AntarchyGravityApi.isGravityForced(entity)) { AntarchyGravityApi.setForcedGravityDirection(entity, AntarchyGravityDirection.UP, EFFECT_TRANSITION); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HoverboardEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HoverboardEntity.java index b27dfda6..7ac87777 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HoverboardEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HoverboardEntity.java @@ -2,6 +2,7 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; @@ -67,6 +68,14 @@ public class HoverboardEntity extends PathfinderMob implements GeoEntity { this.setPersistenceRequired(); } + @Override + public void tick() { + super.tick(); + if (!this.level().isClientSide && this.isVehicle() && this.tickCount % 100 == 0) { + this.playSound(AntarchySoundEvents.HOVERBOARD_IDLE.get(), 0.55F, 1.0F); + } + } + @Override public boolean canBeAffected(MobEffectInstance effectInstance) { return false; @@ -139,12 +148,21 @@ public class HoverboardEntity extends PathfinderMob implements GeoEntity { if (!this.isVehicle() && !player.isSecondaryUseActive()) { if (!this.level().isClientSide) { player.startRiding(this); + this.playSound(AntarchySoundEvents.HOVERBOARD_MOUNT.get(), 1.0F, 1.0F); } return InteractionResult.sidedSuccess(this.level().isClientSide); } return super.mobInteract(player, hand); } + @Override + protected void removePassenger(Entity passenger) { + super.removePassenger(passenger); + if (!this.level().isClientSide) { + this.playSound(AntarchySoundEvents.HOVERBOARD_DISMOUNT.get(), 1.0F, 1.0F); + } + } + @Override @Nullable public LivingEntity getControllingPassenger() { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/TermiteEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/TermiteEntity.java index 69a7bcc3..591b0bc9 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/TermiteEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/TermiteEntity.java @@ -16,6 +16,7 @@ import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.Item; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; +import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.RotatedPillarBlock; import net.minecraft.world.level.block.SoundType; @@ -32,6 +33,8 @@ public class TermiteEntity extends BaseAntEntity implements GeoEntity { private static final int WOOD_REPATH_INTERVAL_TICKS = 6; private static final int WOOD_SEARCH_RADIUS_HORIZONTAL = 12; private static final int WOOD_SEARCH_RADIUS_VERTICAL = 4; + private static final int LIGHT_FLEE_SEARCH_RADIUS = 6; + private static final int LIGHT_FLEE_SEARCH_INTERVAL_TICKS = 10; private static final Vec3i[] IMMEDIATE_WOOD_OFFSETS = { new Vec3i(0, 1, 0), new Vec3i(0, 0, -1), @@ -48,6 +51,7 @@ public class TermiteEntity extends BaseAntEntity implements GeoEntity { private int nextWoodBiteTick; private int nextWoodSearchTick; private int nextWoodRepathTick; + private int nextLightFleeSearchTick; public TermiteEntity(EntityType entityType, Level level) { super(entityType, level); @@ -113,6 +117,12 @@ public class TermiteEntity extends BaseAntEntity implements GeoEntity { @Override protected boolean handlePriorityForaging() { + if (this.isBlockLit(this.blockPosition())) { + this.targetWoodPos = null; + this.fleeBlockLight(); + return true; + } + if (!this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || !this.level().getGameRules().getBoolean(AntarchyGameRules.RULE_DO_TERMITE_GREIFING)) { this.targetWoodPos = null; @@ -142,6 +152,45 @@ public class TermiteEntity extends BaseAntEntity implements GeoEntity { return true; } + private void fleeBlockLight() { + if (this.tickCount < this.nextLightFleeSearchTick && !this.getNavigation().isDone()) { + return; + } + this.nextLightFleeSearchTick = this.tickCount + LIGHT_FLEE_SEARCH_INTERVAL_TICKS; + + BlockPos origin = this.blockPosition(); + BlockPos bestPos = null; + int bestLight = this.level().getBrightness(LightLayer.BLOCK, origin); + double bestDistance = -1.0D; + BlockPos.MutableBlockPos candidate = new BlockPos.MutableBlockPos(); + for (int dx = -LIGHT_FLEE_SEARCH_RADIUS; dx <= LIGHT_FLEE_SEARCH_RADIUS; dx++) { + for (int dz = -LIGHT_FLEE_SEARCH_RADIUS; dz <= LIGHT_FLEE_SEARCH_RADIUS; dz++) { + if (dx * dx + dz * dz > LIGHT_FLEE_SEARCH_RADIUS * LIGHT_FLEE_SEARCH_RADIUS) continue; + for (int dy = -2; dy <= 2; dy++) { + candidate.set(origin.getX() + dx, origin.getY() + dy, origin.getZ() + dz); + if (!this.isWalkableStandPos(candidate)) continue; + int light = this.level().getBrightness(LightLayer.BLOCK, candidate); + double distance = candidate.distSqr(origin); + if (light > bestLight || (light == bestLight && distance <= bestDistance)) continue; + bestPos = candidate.immutable(); + bestLight = light; + bestDistance = distance; + } + } + } + + if (bestPos == null) { + this.getNavigation().stop(); + return; + } + Path path = this.getNavigation().createPath(bestPos, 0); + if (path == null || !path.canReach()) { + this.getNavigation().stop(); + return; + } + this.getNavigation().moveTo(bestPos.getX() + 0.5D, bestPos.getY(), bestPos.getZ() + 0.5D, 1.2D); + } + private boolean tryEatNearbyWood() { if (this.tickCount < this.nextWoodBiteTick) { return false; @@ -151,7 +200,7 @@ public class TermiteEntity extends BaseAntEntity implements GeoEntity { for (Vec3i offset : IMMEDIATE_WOOD_OFFSETS) { BlockPos targetPos = basePos.offset(offset); BlockState targetState = this.level().getBlockState(targetPos); - if (!this.isTermiteEdible(targetState)) { + if (this.isBlockLit(targetPos) || !this.isTermiteEdible(targetState)) { continue; } @@ -244,7 +293,12 @@ public class TermiteEntity extends BaseAntEntity implements GeoEntity { } private boolean isValidWoodTarget(BlockPos targetPos) { - return this.isTermiteEdible(this.level().getBlockState(targetPos)); + return !this.isBlockLit(targetPos) && this.isTermiteEdible(this.level().getBlockState(targetPos)); + } + + private boolean isBlockLit(BlockPos pos) { + return AntarchySettings.termitesFearBlockLight() + && this.level().getBrightness(LightLayer.BLOCK, pos) > 0; } private boolean isTermiteEdible(BlockState state) { 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 49129815..46f02b4a 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 @@ -14,6 +14,8 @@ import net.minecraft.sounds.SoundSource; import net.minecraft.network.chat.Component; import net.minecraft.ChatFormatting; import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.core.BlockPos; +import net.minecraft.tags.BlockTags; import net.minecraft.core.particles.DustParticleOptions; import net.minecraft.network.protocol.game.ClientboundClearTitlesPacket; import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; @@ -252,7 +254,7 @@ public class KingEntity extends RoyalBossEntity { return true; } LivingEntity target = this.getTarget(); - if (target == null || this.activeDecree != null || this.royalChargeOpeningDelayTicks > 0 + if (target == null || this.royalChargeOpeningDelayTicks > 0 || this.kingLandingStage != KingLandingStage.AERIAL || !this.attackScheduler.ready("royal_charge", RoyalAttackLane.MOVEMENT)) { return false; @@ -543,6 +545,9 @@ public class KingEntity extends RoyalBossEntity { return; } this.tickRoyalBoundary((ServerLevel) this.level()); + if (this.tickCount % 10 == 0 && this.isRoyalFlying() && this.getDeltaMovement().horizontalDistanceSqr() > 0.01D) { + this.clearLeavesAhead((ServerLevel) this.level()); + } this.tickComeNoCloserIndicator(); this.tickRoyalPunishment(); this.tickPendingExileAnimation(); @@ -762,6 +767,28 @@ public class KingEntity extends RoyalBossEntity { return true; } + private void clearLeavesAhead(ServerLevel level) { + if (!level.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) { + return; + } + Vec3 movement = this.getDeltaMovement().normalize().scale(1.5D); + AABB forward = this.getBoundingBox().move(movement).inflate(0.2D, 0.0D, 0.2D); + BlockPos min = BlockPos.containing(forward.minX, forward.minY, forward.minZ); + BlockPos max = BlockPos.containing(forward.maxX, forward.maxY, forward.maxZ); + BlockPos.MutableBlockPos cursor = new BlockPos.MutableBlockPos(); + for (int y = min.getY(); y <= max.getY(); y++) { + for (int x = min.getX(); x <= max.getX(); x++) { + for (int z = min.getZ(); z <= max.getZ(); z++) { + cursor.set(x, y, z); + if (level.getBlockState(cursor).is(BlockTags.LEAVES)) { + level.destroyBlock(cursor, true, this); + return; + } + } + } + } + } + private void tickKingCombatMovement(LivingEntity target) { if (this.royalChargeActive) { this.getNavigation().stop(); @@ -1102,7 +1129,9 @@ public class KingEntity extends RoyalBossEntity { public RoyalDecree.Evaluation evaluateCloseQuarters(LivingEntity target) { UUID targetId = target.getUUID(); - double distanceSquared = target.distanceToSqr(this); + double dx = target.getX() - this.getX(); + double dz = target.getZ() - this.getZ(); + double distanceSquared = dx * dx + dz * dz; if (distanceSquared <= CLOSE_QUARTERS_RADIUS * CLOSE_QUARTERS_RADIUS) { this.closeQuartersEntered.add(targetId); this.closeQuartersOutsideTicks.remove(targetId); @@ -1719,8 +1748,8 @@ public class KingEntity extends RoyalBossEntity { } @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(); + Vec3 direction = RoyalElementalProjectileEntity.aimDirection( + origin, target, RoyalBeamElement.FIRE); RoyalElementalProjectileEntity fireball = RoyalElementalProjectileEntity.create(level, KingEntity.this, RoyalBeamElement.FIRE, origin, direction); level.addFreshEntity(fireball); @@ -1739,7 +1768,8 @@ public class KingEntity extends RoyalBossEntity { } @Override public void onActive(int elapsedTicks) { Vec3 origin = KingEntity.this.headAnchor(KingEntity.this.royalHead(RoyalHead.Slot.RIGHT)); - Vec3 direction = target.getEyePosition().subtract(origin).normalize(); + Vec3 direction = RoyalElementalProjectileEntity.aimDirection( + origin, target, RoyalBeamElement.ICE); RoyalElementalProjectileEntity iceball = RoyalElementalProjectileEntity.create(level, KingEntity.this, RoyalBeamElement.ICE, origin, direction); level.addFreshEntity(iceball); 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 9952333f..782013f6 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 @@ -10,6 +10,8 @@ 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.time.TimeDilationApi; +import com.craisinlord.antarchy.content.time.TimeDilationFieldEntity; import com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisUndersideManager; import java.util.HashMap; import java.util.Iterator; @@ -73,6 +75,9 @@ public class QueenEntity extends RoyalBossEntity { private static final double CRUSHING_GRAVITY_RADIUS = 18.0D; private static final double CRUSHING_GRAVITY_STRENGTH = 0.12D; private static final int ACCELERATION_COOLDOWN = 500; + private static final int QUEEN_CHRONOSPHERE_COOLDOWN = 700; + private static final int QUEEN_CHRONOSPHERE_DURATION = 200; + private static final double QUEEN_CHRONOSPHERE_RADIUS = 20.0D; private static final int ACCELERATION_DURATION = 140; private static final int BLACK_HOLE_COOLDOWN = 340; private static final double QUEEN_BITE_COOLDOWN_MULTIPLIER = 1.5D; @@ -83,10 +88,10 @@ public class QueenEntity extends RoyalBossEntity { private static final int ACCELERATION_TELEGRAPH_TICKS = 32; private static final int LANDING_TELEGRAPH_TICKS = 30; private static final int LANDING_IMPACT_TICKS = 18; - private static final int GROUND_COMBAT_TICKS = 140; + private static final int GROUND_COMBAT_TICKS = 160; private static final int TAKEOFF_TICKS = 30; - private static final int LANDING_COOLDOWN_MIN = 360; - private static final int LANDING_COOLDOWN_VARIANCE = 240; + private static final int LANDING_COOLDOWN_MIN = 300; + private static final int LANDING_COOLDOWN_VARIANCE = 120; private static final int BLACK_HOLE_FOLLOW_UP_DELAY = 22; private static final int CRUSHING_LANDING_DELAY = 40; private static final int MOMENTUM_VOLLEY_DELAY = MOMENTUM_LOCK_DURATION + 5; @@ -99,12 +104,14 @@ public class QueenEntity extends RoyalBossEntity { private int momentumLockCooldownTicks; private int crushingGravityCooldownTicks; private int accelerationCooldownTicks; + private int queenChronosphereCooldownTicks; private int blackHoleCooldownTicks; private int gravityStompTelegraphTicks; private int blackHoleTelegraphTicks; private int momentumLockTelegraphTicks; private int crushingGravityTelegraphTicks; private int accelerationTelegraphTicks; + private int queenChronosphereTelegraphTicks; @Nullable private Vec3 pendingBlackHoleAnchor; private int queenLandingCooldownTicks = 300; @@ -238,6 +245,11 @@ public class QueenEntity extends RoyalBossEntity { return 1.55D; } + @Override + protected double combatStandoffDistance() { + return Math.min(super.combatStandoffDistance(), 14.0D); + } + @Override protected int maxConcurrentHeadAttacks(Phase phase) { return switch (phase) { @@ -851,6 +863,7 @@ public class QueenEntity extends RoyalBossEntity { if (this.momentumLockCooldownTicks > 0) this.momentumLockCooldownTicks--; if (this.crushingGravityCooldownTicks > 0) this.crushingGravityCooldownTicks--; if (this.accelerationCooldownTicks > 0) this.accelerationCooldownTicks--; + if (this.queenChronosphereCooldownTicks > 0) this.queenChronosphereCooldownTicks--; if (this.blackHoleCooldownTicks > 0) this.blackHoleCooldownTicks--; if (!(this.level() instanceof ServerLevel level)) { @@ -871,7 +884,7 @@ public class QueenEntity extends RoyalBossEntity { String[] candidates = switch (phase) { case ONE -> new String[] {"gravity_stomp", "black_hole"}; case TWO -> new String[] {"gravity_stomp", "black_hole", "momentum_lock", "crushing_gravity"}; - case THREE -> new String[] {"gravity_stomp", "black_hole", "momentum_lock", "crushing_gravity", "acceleration"}; + case THREE -> new String[] {"gravity_stomp", "black_hole", "momentum_lock", "crushing_gravity", "acceleration", "queen_chronosphere"}; }; String forcedAttack = this.pendingPhaseSignature == Phase.TWO ? "momentum_lock" : this.pendingPhaseSignature == Phase.THREE ? "acceleration" : null; @@ -888,12 +901,14 @@ public class QueenEntity extends RoyalBossEntity { case "black_hole" -> BLACK_HOLE_COOLDOWN; case "momentum_lock" -> MOMENTUM_LOCK_COOLDOWN; case "crushing_gravity" -> CRUSHING_GRAVITY_COOLDOWN; + case "queen_chronosphere" -> QUEEN_CHRONOSPHERE_COOLDOWN; default -> ACCELERATION_COOLDOWN; }; RoyalAttackLane lane = "black_hole".equals(selected) ? RoyalAttackLane.CENTER_HEAD : RoyalAttackLane.HAZARD; int actionWindup = this.queenAbilityWindup(selected); int actionAnimationTicks = "momentum_lock".equals(selected) - || "crushing_gravity".equals(selected) || "acceleration".equals(selected) ? 55 : 25; + || "crushing_gravity".equals(selected) || "acceleration".equals(selected) + || "queen_chronosphere".equals(selected) ? 55 : 25; int actionRecovery = this.animationRecovery(actionAnimationTicks, actionWindup, 1, 14); if (!this.beginRoyalAttack(selected, lane, this.cooldown(cooldown), actionWindup, 1, actionRecovery, new com.craisinlord.antarchy.content.entity.royal.attack.RoyalAttackScheduler.Action() { @@ -902,7 +917,8 @@ public class QueenEntity extends RoyalBossEntity { QueenEntity.this.triggerAnim("body_action", "stomp"); } else if ("momentum_lock".equals(selected) || "crushing_gravity".equals(selected) - || "acceleration".equals(selected)) { + || "acceleration".equals(selected) + || "queen_chronosphere".equals(selected)) { QueenEntity.this.triggerAnim("wing_action", "wing_gust"); } else if ("black_hole".equals(selected)) { QueenEntity.this.royalHead(RoyalHead.Slot.CENTER).startShoot(); @@ -965,6 +981,13 @@ public class QueenEntity extends RoyalBossEntity { this.startRoyalAcceleration(); this.queueQueenFollowUp(QueenFollowUp.ACCELERATION_VOLLEY, ACCELERATION_VOLLEY_DELAY); } + case "queen_chronosphere" -> { + this.queenChronosphereCooldownTicks = cooldown; + TimeDilationFieldEntity field = TimeDilationApi.createField(level, this.position(), + QUEEN_CHRONOSPHERE_RADIUS, 0.08D, QUEEN_CHRONOSPHERE_DURATION, this.getUUID()); + field.configureQueenChronosphere(this); + this.startRoyalRecovery(35); + } } } @@ -998,6 +1021,7 @@ public class QueenEntity extends RoyalBossEntity { 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; + case "queen_chronosphere" -> phase == Phase.THREE && this.queenChronosphereCooldownTicks <= 0; default -> false; }; } @@ -1013,6 +1037,7 @@ public class QueenEntity extends RoyalBossEntity { }; case THREE -> switch (id) { case "acceleration" -> 7; + case "queen_chronosphere" -> 6; case "black_hole", "crushing_gravity" -> 5; case "gravity_stomp" -> 4; case "momentum_lock" -> 2; @@ -1084,6 +1109,7 @@ public class QueenEntity extends RoyalBossEntity { case "momentum_lock" -> MOMENTUM_LOCK_TELEGRAPH_TICKS; case "crushing_gravity" -> CRUSHING_GRAVITY_TELEGRAPH_TICKS; case "acceleration" -> ACCELERATION_TELEGRAPH_TICKS; + case "queen_chronosphere" -> 40; default -> 10; }; } @@ -1111,6 +1137,10 @@ public class QueenEntity extends RoyalBossEntity { this.accelerationTelegraphTicks = ACCELERATION_TELEGRAPH_TICKS; this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 1.22F); } + case "queen_chronosphere" -> { + this.queenChronosphereTelegraphTicks = 40; + this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 0.85F); + } } } @@ -1121,13 +1151,14 @@ public class QueenEntity extends RoyalBossEntity { case "momentum_lock" -> this.momentumLockTelegraphTicks = 0; case "crushing_gravity" -> this.crushingGravityTelegraphTicks = 0; case "acceleration" -> this.accelerationTelegraphTicks = 0; + case "queen_chronosphere" -> this.queenChronosphereTelegraphTicks = 0; } } private boolean isQueenAbilityTelegraphActive() { return this.gravityStompTelegraphTicks > 0 || this.blackHoleTelegraphTicks > 0 || this.momentumLockTelegraphTicks > 0 || this.crushingGravityTelegraphTicks > 0 - || this.accelerationTelegraphTicks > 0; + || this.accelerationTelegraphTicks > 0 || this.queenChronosphereTelegraphTicks > 0; } private void clearQueenAbilityTelegraphs() { @@ -1136,6 +1167,7 @@ public class QueenEntity extends RoyalBossEntity { this.momentumLockTelegraphTicks = 0; this.crushingGravityTelegraphTicks = 0; this.accelerationTelegraphTicks = 0; + this.queenChronosphereTelegraphTicks = 0; this.pendingBlackHoleAnchor = null; } @@ -1150,6 +1182,7 @@ public class QueenEntity extends RoyalBossEntity { this.tickMomentumLockTelegraph(level); this.tickCrushingGravityTelegraph(level); this.tickAccelerationTelegraph(level); + this.tickQueenChronosphereTelegraph(level); } private void tickGravityStompTelegraph(ServerLevel level) { @@ -1235,6 +1268,18 @@ public class QueenEntity extends RoyalBossEntity { this.accelerationTelegraphTicks--; } + private void tickQueenChronosphereTelegraph(ServerLevel level) { + if (this.queenChronosphereTelegraphTicks <= 0) return; + int elapsed = 40 - this.queenChronosphereTelegraphTicks; + Vec3 center = this.position().add(0.0D, this.getBbHeight() * 0.5D, 0.0D); + if (this.tickCount % 2 == 0) { + double radius = Mth.lerp(elapsed / 40.0D, 3.0D, QUEEN_CHRONOSPHERE_RADIUS); + this.spawnQueenTelegraphRing(level, center, radius, 96, ParticleTypes.REVERSE_PORTAL); + } + this.playQueenTelegraphBeat(level, this.queenChronosphereTelegraphTicks, 40, 0.5F); + this.queenChronosphereTelegraphTicks--; + } + private void spawnQueenTelegraphSpokes(ServerLevel level, Vec3 center, double radius) { int spokes = 10; int segments = 6; @@ -1524,6 +1569,7 @@ public class QueenEntity extends RoyalBossEntity { tag.putInt("MomentumLockCooldownTicks", this.momentumLockCooldownTicks); tag.putInt("CrushingGravityCooldownTicks", this.crushingGravityCooldownTicks); tag.putInt("AccelerationCooldownTicks", this.accelerationCooldownTicks); + tag.putInt("QueenChronosphereCooldownTicks", this.queenChronosphereCooldownTicks); tag.putInt("BlackHoleCooldownTicks", this.blackHoleCooldownTicks); tag.putInt("QueenLandingCooldownTicks", this.queenLandingCooldownTicks); tag.putString("QueuedQueenFollowUp", this.queuedQueenFollowUp.name()); @@ -1547,6 +1593,7 @@ public class QueenEntity extends RoyalBossEntity { this.momentumLockCooldownTicks = Math.max(0, tag.getInt("MomentumLockCooldownTicks")); this.crushingGravityCooldownTicks = Math.max(0, tag.getInt("CrushingGravityCooldownTicks")); this.accelerationCooldownTicks = Math.max(0, tag.getInt("AccelerationCooldownTicks")); + this.queenChronosphereCooldownTicks = Math.max(0, tag.getInt("QueenChronosphereCooldownTicks")); this.blackHoleCooldownTicks = Math.max(0, tag.getInt("BlackHoleCooldownTicks")); this.queenLandingCooldownTicks = tag.contains("QueenLandingCooldownTicks") ? Math.max(0, tag.getInt("QueenLandingCooldownTicks")) : 300; 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 fea0d22d..a592a18a 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 @@ -850,8 +850,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult Vec3 awayFromTarget = horizontalDistance > 1.0E-4D ? new Vec3(-dx / horizontalDistance, 0.0D, -dz / horizontalDistance) : this.getViewVector(1.0F).multiply(-1.0D, 0.0D, -1.0D).normalize(); - double standoff = Math.max(this.getBbWidth() * 0.55D, - BEAM_MUZZLE_FORWARD - this.biteReach() * 0.65D + 1.0D); + double standoff = this.combatStandoffDistance(); Vec3 wanted = target.position().add(awayFromTarget.scale(standoff)); boolean atStandoff = this.position().multiply(1.0D, 0.0D, 1.0D) .distanceToSqr(wanted.multiply(1.0D, 0.0D, 1.0D)) <= 4.0D; @@ -908,6 +907,11 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult return false; } + protected double combatStandoffDistance() { + return Math.max(this.getBbWidth() * 0.55D, + BEAM_MUZZLE_FORWARD - this.biteReach() * 0.65D + 1.0D); + } + private void tickCombatLocomotionMode(LivingEntity target) { if (!this.isFlyingBoss() || this.managesOwnCombatLocomotion()) { return; 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 index c73b07e6..193a41f2 100644 --- 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 @@ -42,6 +42,11 @@ public class RoyalElementalProjectileEntity extends ThrowableProjectile implemen private static final int ICEBALL = 1; private static final int DREAM_FIREBALL = 2; private static final int MAX_LIFETIME = 100; + private static final float FIREBALL_SPEED = 1.5F; + private static final float ICEBALL_SPEED = 1.2F; + private static final float DREAM_FIREBALL_SPEED = 1.05F; + private static final double PROJECTILE_INERTIA = 0.985D; + private static final float DREAM_FIREBALL_INERTIA = 0.96F; private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); public RoyalElementalProjectileEntity(EntityType type, Level level) { @@ -57,10 +62,38 @@ public class RoyalElementalProjectileEntity extends ThrowableProjectile implemen projectile.setPos(position.x, position.y, position.z); projectile.setAttackType(element == RoyalBeamElement.ICE ? ICEBALL : element == RoyalBeamElement.DREAM_FIRE ? DREAM_FIREBALL : FIREBALL); - projectile.shoot(direction.x, direction.y, direction.z, element == RoyalBeamElement.ICE ? 0.8F : 1.05F, 0.0F); + float speed = element == RoyalBeamElement.ICE ? ICEBALL_SPEED + : element == RoyalBeamElement.DREAM_FIRE ? DREAM_FIREBALL_SPEED : FIREBALL_SPEED; + projectile.shoot(direction.x, direction.y, direction.z, speed, 0.0F); return projectile; } + /** Solves a discrete ballistic lead against the projectile's drag and gravity. */ + public static Vec3 aimDirection(Vec3 origin, LivingEntity target, RoyalBeamElement element) { + double speed = element == RoyalBeamElement.ICE ? ICEBALL_SPEED : FIREBALL_SPEED; + double gravity = element == RoyalBeamElement.ICE ? 0.006D : 0.018D; + double inertia = PROJECTILE_INERTIA; + Vec3 bestDirection = target.getEyePosition().subtract(origin).normalize(); + double bestError = Double.MAX_VALUE; + + for (int ticks = 1; ticks < MAX_LIFETIME; ticks++) { + double dragDistance = (1.0D - Math.pow(inertia, ticks)) / (1.0D - inertia); + Vec3 predictedTarget = target.getEyePosition().add(target.getDeltaMovement().scale(ticks)); + Vec3 displacement = predictedTarget.subtract(origin); + double gravityCompensation = gravity * (ticks - dragDistance) / (1.0D - inertia); + Vec3 initialVelocity = new Vec3( + displacement.x / dragDistance, + (displacement.y + gravityCompensation) / dragDistance, + displacement.z / dragDistance); + double error = Math.abs(initialVelocity.length() - speed); + if (error < bestError) { + bestError = error; + bestDirection = initialVelocity.normalize(); + } + } + return bestDirection; + } + @Override protected void defineSynchedData(SynchedEntityData.Builder builder) { builder.define(ATTACK_TYPE, FIREBALL); @@ -80,11 +113,11 @@ public class RoyalElementalProjectileEntity extends ThrowableProjectile implemen @Override protected double getDefaultGravity() { - return this.isIceball() ? 0.012D : 0.018D; + return this.isIceball() ? 0.006D : 0.018D; } protected float getInertia() { - return this.isIceball() ? 0.985F : 0.96F; + return this.isDreamFireball() ? DREAM_FIREBALL_INERTIA : (float) PROJECTILE_INERTIA; } @Override diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountEntity.java index 9004cc5f..e0e85fea 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountEntity.java @@ -10,7 +10,7 @@ import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamTerrainMode; import com.craisinlord.antarchy.content.effect.RoyalEffectEligibility; import com.craisinlord.antarchy.content.effect.RoyalEffectHooks; import com.craisinlord.antarchy.content.time.TimeDilationApi; -import java.util.UUID; +import net.minecraft.resources.ResourceLocation; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; @@ -34,6 +34,7 @@ import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.Pose; import net.minecraft.world.entity.TamableAnimal; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.control.FlyingMoveControl; import net.minecraft.world.entity.ai.control.MoveControl; @@ -71,6 +72,7 @@ import software.bernie.geckolib.animation.RawAnimation; import software.bernie.geckolib.util.GeckoLibUtil; public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntity, FlyingAnimal { + private static final ResourceLocation GROWTH_HEALTH_MODIFIER = ResourceLocation.fromNamespaceAndPath("antarchy", "royal_mount_growth_health"); public static final int ANIM_IDLE = 0; public static final int ANIM_WALK = 1; public static final int ANIM_FLY = 2; @@ -309,6 +311,9 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit this.navigation = flying ? this.flyingNavigation : this.groundNavigation; this.setNoGravity(flying); } + if (GROWTH_PROGRESS.equals(key)) { + this.refreshDimensions(); + } } public void setFlying(boolean flying) { @@ -350,11 +355,30 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit public void setGrowthProgress(float progress) { float clamped = Mth.clamp(progress, 0.0F, 1.0F); if (this.getGrowthProgress() != clamped) { + float oldHealth = this.getHealth(); this.entityData.set(GROWTH_PROGRESS, clamped); + var maxHealth = this.getAttribute(Attributes.MAX_HEALTH); + if (maxHealth != null) { + maxHealth.removeModifier(GROWTH_HEALTH_MODIFIER); + if (clamped > 0.0F) { + maxHealth.addTransientModifier(new AttributeModifier(GROWTH_HEALTH_MODIFIER, + this.getGrowthScale() - 1.0D, AttributeModifier.Operation.ADD_MULTIPLIED_BASE)); + } + this.setHealth(Math.min(oldHealth, this.getMaxHealth())); + } this.refreshDimensions(); } } + @Override + public boolean hurt(DamageSource source, float amount) { + Entity attacker = source.getEntity(); + if (attacker != null && this.hasPassenger(attacker)) { + return false; + } + return super.hurt(source, amount); + } + @Override public EntityDimensions getDefaultDimensions(Pose pose) { return super.getDefaultDimensions(pose).scale(this.getGrowthScale()); @@ -369,19 +393,37 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack stack = player.getItemInHand(hand); - if (this.isFood(stack)) { + if (stack.is(Items.GOLDEN_APPLE) && !this.isTame()) { + if (!this.level().isClientSide) { + if (!player.getAbilities().instabuild) { + stack.shrink(1); + } + this.tame(player); + this.heal(8.0F); + this.level().broadcastEntityEvent(this, (byte) 7); + } + return InteractionResult.sidedSuccess(this.level().isClientSide); + } + + if (stack.is(Items.ENCHANTED_GOLDEN_APPLE) && this.isTame() && this.isOwnedBy(player)) { if (!this.level().isClientSide) { if (!player.getAbilities().instabuild) { stack.shrink(1); } this.heal(8.0F); this.setGrowthProgress(this.getGrowthProgress() + (1.0F - this.getGrowthProgress()) * 0.1F); - if (!this.isTame() && this.random.nextInt(3) == 0) { - this.tame(player); - this.level().broadcastEntityEvent(this, (byte) 7); - } else { - this.level().broadcastEntityEvent(this, (byte) 6); + this.level().broadcastEntityEvent(this, (byte) 6); + } + return InteractionResult.sidedSuccess(this.level().isClientSide); + } + + if (this.isFood(stack)) { + if (!this.level().isClientSide && this.isTame() && this.isOwnedBy(player) && this.getHealth() < this.getMaxHealth()) { + if (!player.getAbilities().instabuild) { + stack.shrink(1); } + this.heal(8.0F); + this.level().broadcastEntityEvent(this, (byte) 6); } return InteractionResult.sidedSuccess(this.level().isClientSide); } @@ -399,12 +441,7 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit } if (stack.isEmpty() && player.isSecondaryUseActive()) { - if (this.isSaddled()) { - if (!this.level().isClientSide) { - this.setSaddled(false); - this.spawnAtLocation(new ItemStack(Items.SADDLE)); - } - } else if (!this.level().isClientSide) { + if (!this.level().isClientSide) { this.setOrderedToSit(!this.isOrderedToSit()); this.setInSittingPose(this.isOrderedToSit()); this.navigation.stop(); @@ -762,8 +799,10 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit if (!this.hasPassenger(passenger)) { return; } - double yOffset = (this.isFlying() ? 1.55D : 1.35D) * this.getGrowthScale() - 1.0D; - Vec3 back = this.getLookAngle().scale(-0.35D * this.getGrowthScale()); + // Seat near the back of the torso, outside the scaled body instead of inside its growing hitbox. + double yOffset = Math.max(this.getBbHeight() * 0.82D, this.getBbHeight() - passenger.getBbHeight() * 0.65D); + double backDistance = this.getBbWidth() * 0.5D + passenger.getBbWidth() * 0.5D + 0.15D; + Vec3 back = this.getLookAngle().scale(-backDistance); moveFunction.accept(passenger, this.getX() + back.x, this.getY() + yOffset, this.getZ() + back.z); } 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 622ff408..1bc33fbd 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 @@ -11,9 +11,14 @@ public final class StandYourGroundDecree implements RoyalDecree { private final Map anchors = new HashMap<>(); 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()); + this.anchors.computeIfAbsent(target.getUUID(), ignored -> target.position()); } @Override public Evaluation evaluate(ServerLevel level, KingEntity king, LivingEntity target) { + if (target instanceof net.minecraft.server.level.ServerPlayer player && player.isFallFlying()) { + // Gliding carries unavoidable momentum; begin measuring again from the landing point. + this.anchors.put(target.getUUID(), target.position()); + return Evaluation.COMPLIANT; + } Vec3 anchor = this.anchors.computeIfAbsent(target.getUUID(), ignored -> target.position()); return target.position().distanceToSqr(anchor) > ALLOWED_DRIFT * ALLOWED_DRIFT ? Evaluation.VIOLATED : Evaluation.COMPLIANT; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/trades/ComputerScientistTradeManager.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/trades/ComputerScientistTradeManager.java index e67bd15b..55d7b394 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/trades/ComputerScientistTradeManager.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/trades/ComputerScientistTradeManager.java @@ -1,6 +1,6 @@ package com.craisinlord.antarchy.content.entity.trades; -import com.craisinlord.antarchy.content.AntarchyObjects; +import com.craisinlord.antos.content.AntOSObjects; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -118,8 +118,8 @@ public final class ComputerScientistTradeManager extends SimpleJsonResourceReloa ResourceLocation diskId = diskType.equals("random_general") ? GENERAL_DISKS.get(random.nextInt(GENERAL_DISKS.size())) : ResourceLocation.parse(diskType); - ItemStack disk = new ItemStack(AntarchyObjects.FLOPPY_DISK.get(), count); - disk.set(AntarchyObjects.FLOPPY_DISK_COMPONENT.get(), diskId); + ItemStack disk = new ItemStack(AntOSObjects.FLOPPY_DISK.get(), count); + disk.set(AntOSObjects.FLOPPY_DISK_COMPONENT.get(), diskId); return disk; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/trades/PestControlTradeManager.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/trades/PestControlTradeManager.java new file mode 100644 index 00000000..20dfbf7d --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/trades/PestControlTradeManager.java @@ -0,0 +1,76 @@ +package com.craisinlord.antarchy.content.entity.trades; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; +import net.minecraft.util.RandomSource; +import net.minecraft.util.profiling.ProfilerFiller; +import net.minecraft.world.entity.npc.VillagerTrades; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.trading.ItemCost; +import net.minecraft.world.item.trading.MerchantOffer; + +public final class PestControlTradeManager extends SimpleJsonResourceReloadListener { + private static final Gson GSON = new Gson(); + private static volatile List trades = List.of(); + + public PestControlTradeManager() { + super(GSON, "pest_control_trades"); + } + + public static int[] slotsPerLevel() { + return new int[] {2, 2, 2, 1, 1}; + } + + public static VillagerTrades.ItemListing listing(int level, int index) { + return (villager, random) -> trades.stream().filter(entry -> entry.level == level && entry.index == index) + .findFirst().map(entry -> entry.offer(random)).orElse(null); + } + + @Override + protected void apply(Map resources, ResourceManager manager, ProfilerFiller profiler) { + List parsed = new ArrayList<>(); + for (JsonElement resource : resources.values()) { + if (!resource.isJsonObject()) continue; + JsonObject root = resource.getAsJsonObject(); + if (root.has("trades")) { + for (JsonElement element : root.getAsJsonArray("trades")) if (element.isJsonObject()) parsed.add(Entry.parse(element.getAsJsonObject())); + } else parsed.add(Entry.parse(root)); + } + trades = List.copyOf(parsed); + } + + private record Entry(int level, int index, String buy, int buyCount, String sell, int sellCount, + String secondBuy, int secondBuyCount, int maxUses, int xp) { + private MerchantOffer offer(RandomSource random) { + var buyItem = BuiltInRegistries.ITEM.get(ResourceLocation.parse(buy)); + var sellItem = BuiltInRegistries.ITEM.get(ResourceLocation.parse(sell)); + var secondCost = secondBuy == null ? java.util.Optional.empty() + : java.util.Optional.of(new ItemCost(BuiltInRegistries.ITEM.get(ResourceLocation.parse(secondBuy)), secondBuyCount)); + return new MerchantOffer(new ItemCost(buyItem, buyCount), secondCost, new ItemStack(sellItem, sellCount), maxUses, xp, 0.05F); + } + + private static Entry parse(JsonObject json) { + JsonObject buy = json.getAsJsonObject("buy"); + JsonObject sell = json.getAsJsonObject("sell"); + JsonObject second = json.has("second_buy") ? json.getAsJsonObject("second_buy") : null; + return new Entry(json.get("level").getAsInt(), json.get("index").getAsInt(), buy.get("item").getAsString(), + count(buy), sell.get("item").getAsString(), count(sell), second == null ? null : second.get("item").getAsString(), + second == null ? 0 : count(second), json.has("max_uses") ? json.get("max_uses").getAsInt() : 12, + json.has("villager_xp") ? json.get("villager_xp").getAsInt() : 5); + } + + private static int count(JsonObject stack) { + if (stack.has("min") && stack.has("max")) return stack.get("min").getAsInt(); + return stack.has("count") ? stack.get("count").getAsInt() : stack.get("min").getAsInt(); + } + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/guide/ComputerGuideData.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/guide/ComputerGuideData.java deleted file mode 100644 index 53b72158..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/guide/ComputerGuideData.java +++ /dev/null @@ -1,290 +0,0 @@ -package com.craisinlord.antarchy.content.guide; - -import com.craisinlord.antarchy.Antarchy; -import com.craisinlord.antarchy.config.AntarchySettings; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.server.packs.resources.SimplePreparableReloadListener; -import net.minecraft.util.profiling.ProfilerFiller; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -public final class ComputerGuideData extends SimplePreparableReloadListener { - private static final ComputerGuideData INSTANCE = new ComputerGuideData(); - private static final ResourceLocation INTRODUCTION = ResourceLocation.fromNamespaceAndPath("antarchy", "introduction"); - private static volatile Map entries = Map.of(); - private static volatile Map disks = Map.of(); - - private ComputerGuideData() { - } - - public static ComputerGuideData instance() { - return INSTANCE; - } - - public static Entry entry(ResourceLocation id) { - return entries.get(id); - } - - public static Disk disk(ResourceLocation id) { - return disks.get(id); - } - - public static List entriesFor(List diskIds) { - if (AntarchySettings.unlockAllArchives()) { - Map result = new LinkedHashMap<>(); - result.put(INTRODUCTION, introduction()); - result.putAll(entries); - return result.values().stream().sorted(Comparator.comparing(entry -> entry.titleKey().toString())).toList(); - } - Map result = new LinkedHashMap<>(); - for (ResourceLocation diskId : diskIds) { - if (INTRODUCTION.equals(diskId)) { - result.put(INTRODUCTION, introduction()); - continue; - } - Disk disk = disks.get(diskId); - if (disk == null) { - continue; - } - for (ResourceLocation entryId : disk.entries()) { - Entry entry = entries.get(entryId); - if (entry != null) { - result.putIfAbsent(entryId, entry); - } - } - } - return result.values().stream().sorted(Comparator.comparing(entry -> entry.titleKey().toString())).toList(); - } - - private static Entry introduction() { - return new Entry(INTRODUCTION, "article", "general", "guide.antarchy.entry.introduction.title", - "guide.antarchy.entry.introduction.subtitle", List.of("guide.antarchy.entry.introduction.description"), - "", "", "", "", "", "", "", 0, "", "", "", 0.0F, 1.0F); - } - - /** Encodes the server data-pack view so remote clients do not need a duplicate asset copy. */ - public static String encodeNetworkSnapshot() { - JsonObject root = new JsonObject(); - JsonArray entryArray = new JsonArray(); - entries.values().stream().sorted(Comparator.comparing(entry -> entry.id().toString())).forEach(entry -> { - JsonObject object = new JsonObject(); - object.addProperty("id", entry.id().toString()); - object.addProperty("type", entry.type()); - object.addProperty("category", entry.category()); - object.addProperty("title", entry.titleKey()); - object.addProperty("subtitle", entry.subtitleKey()); - JsonArray descriptions = new JsonArray(); - entry.descriptionKeys().forEach(descriptions::add); - object.add("description", descriptions); - object.addProperty("item", entry.itemId()); - object.addProperty("entity", entry.entityId()); - object.addProperty("enchantment", entry.enchantmentId()); - object.addProperty("recipe", entry.recipeId()); - object.addProperty("structure", entry.structureId()); - object.addProperty("structure_tag", entry.structureTagId()); - object.addProperty("dimension", entry.dimensionId()); - object.addProperty("search_radius", entry.searchRadius()); - object.addProperty("cover_item", entry.coverItemId()); - object.addProperty("cover_entity", entry.coverEntityId()); - object.addProperty("cover_potion", entry.coverPotionId()); - object.addProperty("rotation", entry.rotation()); - object.addProperty("render_scale", entry.renderScale()); - entryArray.add(object); - }); - root.add("entries", entryArray); - - JsonArray diskArray = new JsonArray(); - disks.values().stream().sorted(Comparator.comparing(disk -> disk.id().toString())).forEach(disk -> { - JsonObject object = new JsonObject(); - object.addProperty("id", disk.id().toString()); - object.addProperty("category", disk.category()); - object.addProperty("title", disk.titleKey()); - JsonArray diskEntries = new JsonArray(); - disk.entries().forEach(id -> diskEntries.add(id.toString())); - object.add("entries", diskEntries); - object.addProperty("wallpaper", disk.wallpaper()); - diskArray.add(object); - }); - root.add("disks", diskArray); - return root.toString(); - } - - /** Applies the authoritative server snapshot on a multiplayer client. */ - public static void applyNetworkSnapshot(String json) { - try { - JsonObject root = JsonParser.parseString(json).getAsJsonObject(); - Map loadedEntries = new HashMap<>(); - Map loadedDisks = new HashMap<>(); - JsonArray entryArray = root.getAsJsonArray("entries"); - if (entryArray != null) { - for (JsonElement element : entryArray) { - JsonObject object = element.getAsJsonObject(); - parseEntry(ResourceLocation.parse(string(object, "id", "")), object, loadedEntries); - } - } - JsonArray diskArray = root.getAsJsonArray("disks"); - if (diskArray != null) { - for (JsonElement element : diskArray) { - JsonObject object = element.getAsJsonObject(); - parseDisk(ResourceLocation.parse(string(object, "id", "")), object, loadedDisks); - } - } - entries = Map.copyOf(loadedEntries); - disks = Map.copyOf(loadedDisks); - Antarchy.LOGGER.info("Loaded {} computer archive entries and {} disks from the server", entries.size(), disks.size()); - } catch (RuntimeException exception) { - Antarchy.LOGGER.error("Failed to decode computer archive data from the server", exception); - } - } - - @Override - protected LoadedData prepare(ResourceManager resourceManager, ProfilerFiller profiler) { - Map loadedEntries = new HashMap<>(); - Map loadedDisks = new HashMap<>(); - for (Map.Entry resource : resourceManager.listResources("computer/entry", path -> path.getPath().endsWith(".json")).entrySet()) { - ResourceLocation id = resourceId(resource.getKey(), "computer/entry"); - try { - JsonElement json = JsonParser.parseReader(resource.getValue().openAsReader()); - parseEntry(id, json, loadedEntries); - } catch (Exception exception) { - Antarchy.LOGGER.error("Failed to load computer archive entry {}", resource.getKey(), exception); - } - } - for (Map.Entry resource : resourceManager.listResources("computer/disk", path -> path.getPath().endsWith(".json")).entrySet()) { - ResourceLocation id = resourceId(resource.getKey(), "computer/disk"); - try { - JsonElement json = JsonParser.parseReader(resource.getValue().openAsReader()); - parseDisk(id, json, loadedDisks); - } catch (Exception exception) { - Antarchy.LOGGER.error("Failed to load computer archive disk {}", resource.getKey(), exception); - } - } - return new LoadedData(Map.copyOf(loadedEntries), Map.copyOf(loadedDisks)); - } - - @Override - protected void apply(LoadedData data, ResourceManager resourceManager, ProfilerFiller profiler) { - entries = data.entries(); - disks = data.disks(); - } - - private static ResourceLocation resourceId(ResourceLocation path, String directory) { - String prefix = directory + "/"; - String value = path.getPath().startsWith(prefix) ? path.getPath().substring(prefix.length()) : path.getPath(); - if (value.endsWith(".json")) { - value = value.substring(0, value.length() - 5); - } - return ResourceLocation.fromNamespaceAndPath(path.getNamespace(), value); - } - - private static void parseEntry(ResourceLocation id, JsonElement element, Map target) { - if (!element.isJsonObject()) { - return; - } - JsonObject object = element.getAsJsonObject(); - String type = string(object, "type", "article"); - String category = string(object, "category", "general"); - String title = string(object, "title", "guide.antarchy.missing_title"); - String subtitle = string(object, "subtitle", ""); - List description = strings(object.get("description")); - String item = string(object, "item", ""); - String entity = string(object, "entity", ""); - String enchantment = string(object, "enchantment", ""); - String recipe = string(object, "recipe", ""); - String structure = string(object, "structure", ""); - String structureTag = string(object, "structure_tag", ""); - String dimension = string(object, "dimension", ""); - int searchRadius = object.has("search_radius") && object.get("search_radius").isJsonPrimitive() - ? Math.max(0, Math.min(1000, object.get("search_radius").getAsInt())) : 0; - String coverItem = string(object, "cover_item", ""); - String coverEntity = string(object, "cover_entity", ""); - String coverPotion = string(object, "cover_potion", ""); - float rotation = object.has("rotation") && object.get("rotation").isJsonPrimitive() - ? object.get("rotation").getAsFloat() : 0.0F; - float renderScale = object.has("render_scale") && object.get("render_scale").isJsonPrimitive() - ? object.get("render_scale").getAsFloat() : 1.0F; - renderScale = Math.max(0.1F, Math.min(3.0F, renderScale)); - target.put(id, new Entry(id, type, category, title, subtitle, description, item, entity, enchantment, recipe, structure, structureTag, dimension, searchRadius, - coverItem, coverEntity, coverPotion, rotation, renderScale)); - } - - private static void parseDisk(ResourceLocation id, JsonElement element, Map target) { - if (!element.isJsonObject()) { - return; - } - JsonObject object = element.getAsJsonObject(); - String category = string(object, "category", "general"); - String title = string(object, "title", "guide.antarchy.missing_disk_title"); - List entryIds = new ArrayList<>(); - JsonElement entriesElement = object.get("entries"); - if (entriesElement != null && entriesElement.isJsonArray()) { - for (JsonElement entry : entriesElement.getAsJsonArray()) { - if (entry.isJsonPrimitive() && entry.getAsJsonPrimitive().isString()) { - try { - entryIds.add(ResourceLocation.parse(entry.getAsString())); - } catch (Exception ignored) { - } - } - } - } - String wallpaper = string(object, "wallpaper", ""); - target.put(id, new Disk(id, category, title, List.copyOf(entryIds), wallpaper)); - } - - private static String string(JsonObject object, String key, String fallback) { - JsonElement element = object.get(key); - return element != null && element.isJsonPrimitive() ? element.getAsString() : fallback; - } - - private static List strings(JsonElement element) { - if (element == null) { - return List.of(); - } - if (element.isJsonPrimitive()) { - return List.of(element.getAsString()); - } - if (!element.isJsonArray()) { - return List.of(); - } - List values = new ArrayList<>(); - JsonArray array = element.getAsJsonArray(); - for (JsonElement value : array) { - if (value.isJsonPrimitive()) { - values.add(value.getAsString()); - } else if (value.isJsonObject()) { - JsonObject render = value.getAsJsonObject(); - String item = string(render, "item", ""); - String entity = string(render, "entity", ""); - String enchantment = string(render, "enchantment", ""); - String recipe = string(render, "recipe", ""); - if (!item.isBlank()) values.add("@item:" + item); - else if (!entity.isBlank()) values.add("@entity:" + entity); - else if (!enchantment.isBlank()) values.add("@enchantment:" + enchantment); - else if (!recipe.isBlank()) values.add("@recipe:" + recipe); - } - } - return List.copyOf(values); - } - - public record Entry(ResourceLocation id, String type, String category, String titleKey, String subtitleKey, - List descriptionKeys, String itemId, String entityId, String enchantmentId, - String recipeId, String structureId, String structureTagId, String dimensionId, int searchRadius, String coverItemId, - String coverEntityId, String coverPotionId, float rotation, float renderScale) { - } - - public record Disk(ResourceLocation id, String category, String titleKey, List entries, String wallpaper) { - } - - record LoadedData(Map entries, Map disks) { - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/BigBerthaItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/BigBerthaItem.java index 094859a7..8f4ba348 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/BigBerthaItem.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/BigBerthaItem.java @@ -110,8 +110,7 @@ public class BigBerthaItem extends SwordItem implements GeoItem { public InteractionResultHolder use(Level level, Player player, InteractionHand hand) { ItemStack stack = player.getItemInHand(hand); if (player.isShiftKeyDown()) { - cycleMode(level, player, stack); - return InteractionResultHolder.sidedSuccess(stack, level.isClientSide); + return InteractionResultHolder.pass(stack); } BossMode mode = getMode(stack); @@ -390,8 +389,8 @@ public class BigBerthaItem extends SwordItem implements GeoItem { } } - public boolean tryCycleModeWhileCoolingDown(Level level, Player player, ItemStack stack) { - if (player.getMainHandItem() != stack || !player.isShiftKeyDown() || !player.getCooldowns().isOnCooldown(this)) { + public boolean tryCycleModeFromInput(Level level, Player player, ItemStack stack) { + if (player.getMainHandItem() != stack) { return false; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/BugSprayItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/BugSprayItem.java new file mode 100644 index 00000000..472cdd34 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/BugSprayItem.java @@ -0,0 +1,60 @@ +package com.craisinlord.antarchy.content.item; + +import com.craisinlord.antarchy.content.AntarchyObjects; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Mob; +import net.minecraft.tags.EntityTypeTags; +import net.minecraft.tags.TagKey; +import net.minecraft.resources.ResourceLocation; +import com.craisinlord.antarchy.content.entity.ant.BaseAntEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +public final class BugSprayItem extends Item { + private static final TagKey> ANARCHY_ARTHROPODS = TagKey.create( + net.minecraft.core.registries.Registries.ENTITY_TYPE, ResourceLocation.fromNamespaceAndPath("antarchy", "arthropods")); + + public BugSprayItem(Properties properties) { + super(properties); + } + + @Override + public InteractionResultHolder use(Level level, Player player, InteractionHand hand) { + ItemStack stack = player.getItemInHand(hand); + if (!level.isClientSide && level instanceof ServerLevel serverLevel) { + Vec3 look = player.getLookAngle().normalize(); + Vec3 origin = player.getEyePosition().add(look.scale(0.6D)); + var sprayParticle = AntarchyObjects.BUG_SPRAY_PARTICLE.get(); + serverLevel.sendParticles(sprayParticle, origin.x, origin.y, origin.z, 18, + look.x * 0.45D, look.y * 0.45D, look.z * 0.45D, 0.06D); + AABB bounds = new AABB(origin, origin.add(look.scale(7.0D))).inflate(2.2D); + for (Entity entity : level.getEntities(player, bounds, candidate -> candidate instanceof Mob mob + && (mob.getType().is(EntityTypeTags.SENSITIVE_TO_BANE_OF_ARTHROPODS) + || mob.getType().is(ANARCHY_ARTHROPODS) || mob instanceof BaseAntEntity))) { + if (!(entity instanceof Mob mob)) continue; + Vec3 toward = mob.position().subtract(origin); + double distance = toward.length(); + if (distance > 9.0D || distance < 0.001D || toward.normalize().dot(look) < 0.55D) continue; + Vec3 flee = mob.position().subtract(player.position()).normalize(); + mob.getNavigation().moveTo(mob.getX() + flee.x * 6.0D, mob.getY(), mob.getZ() + flee.z * 6.0D, 1.25D); + mob.setTarget(null); + mob.setLastHurtByMob(null); + mob.setDeltaMovement(mob.getDeltaMovement().add(flee.scale(0.55D)).add(0.0D, 0.15D, 0.0D)); + mob.hurtMarked = true; + serverLevel.sendParticles(sprayParticle, mob.getX(), mob.getY() + mob.getBbHeight() * 0.5D, mob.getZ(), 5, 0.12D, 0.12D, 0.12D, 0.02D); + } + level.playSound(null, player.blockPosition(), SoundEvents.FIRE_EXTINGUISH, SoundSource.PLAYERS, 0.7F, 1.2F); + stack.shrink(1); + } + return InteractionResultHolder.sidedSuccess(stack, level.isClientSide); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/ComputerItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/ComputerItem.java deleted file mode 100644 index 78a5c6ee..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/ComputerItem.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.craisinlord.antarchy.content.item; - -import com.craisinlord.antarchy.content.block.ComputerBlock; -import net.minecraft.world.item.BlockItem; - -public final class ComputerItem extends BlockItem { - public ComputerItem(ComputerBlock block, Properties properties) { - super(block, properties); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/FloppyDiskItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/FloppyDiskItem.java deleted file mode 100644 index a8b2d7e2..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/FloppyDiskItem.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.craisinlord.antarchy.content.item; - -import com.craisinlord.antarchy.content.AntarchyObjects; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; - -import java.util.List; - -public final class FloppyDiskItem extends Item { - public FloppyDiskItem(Properties properties) { - super(properties.stacksTo(1)); - } - - public static float categoryModelProperty(ItemStack stack) { - ResourceLocation id = stack.get(AntarchyObjects.FLOPPY_DISK_COMPONENT.get()); - if (id == null) return 0.0F; - var disk = com.craisinlord.antarchy.content.guide.ComputerGuideData.disk(id); - if (disk == null) return 0.0F; - return switch (disk.category()) { - case "elythia" -> 1.0F; - case "cavaryn" -> 2.0F; - case "thoraxis" -> 3.0F; - default -> 0.0F; - }; - } - - @Override - public Component getName(ItemStack stack) { - ResourceLocation id = stack.get(AntarchyObjects.FLOPPY_DISK_COMPONENT.get()); - if (id != null) { - var disk = com.craisinlord.antarchy.content.guide.ComputerGuideData.disk(id); - if (disk != null) { - return Component.translatable(disk.titleKey()); - } - } - return Component.translatable("item.antarchy.floppy_disk"); - } - - @Override - public void appendHoverText(ItemStack stack, TooltipContext context, List tooltip, TooltipFlag flag) { - tooltip.add(Component.translatable("item.antarchy.floppy_disk.tooltip")); - ResourceLocation id = stack.get(AntarchyObjects.FLOPPY_DISK_COMPONENT.get()); - if (id != null) { - var disk = com.craisinlord.antarchy.content.guide.ComputerGuideData.disk(id); - if (disk != null) { - tooltip.add(Component.translatable("guide.antarchy.category." + disk.category())); - } - } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalGuardianSwordAbilities.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalGuardianSwordAbilities.java index 16615bd9..9661d1bd 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalGuardianSwordAbilities.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalGuardianSwordAbilities.java @@ -2,6 +2,7 @@ package com.craisinlord.antarchy.content.item; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.effect.CommandedEntityAccess; +import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.entity.royal.RoyalIceSpikeEntity; import java.util.HashSet; import java.util.Set; @@ -126,21 +127,23 @@ public final class RoyalGuardianSwordAbilities { if (forward.lengthSqr() < 1.0E-5D) forward = new Vec3(0.0D, 0.0D, 1.0D); forward = forward.normalize(); Vec3 side = new Vec3(-forward.z, 0.0D, forward.x); - for (int distanceStep = 1; distanceStep <= 4; distanceStep++) { - double distance = 2.5D + distanceStep * 2.7D; + for (int distanceStep = 1; distanceStep <= 5; distanceStep++) { + double distance = distanceStep * 4.0D; for (int lane = -1; lane <= 1; lane++) { - Vec3 point = primary.position().add(forward.scale(distance)).add(side.scale(lane * 1.8D)); - BlockPos surface = level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BlockPos.containing(point)); - Vec3 spawn = new Vec3(point.x, surface.getY() + 0.1D, point.z); + Vec3 point = owner.position().add(forward.scale(distance)) + .add(side.scale(lane * (distanceStep % 2 == 0 ? 2.0D : 0.0D))); + int groundY = level.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, + net.minecraft.util.Mth.floor(point.x), net.minecraft.util.Mth.floor(point.z)); + Vec3 spawn = new Vec3(point.x, groundY + 0.1D, point.z); RoyalIceSpikeEntity spike = RoyalIceSpikeEntity.create(level, spawn, owner, - (float) AntarchySettings.royalGuardianSwordFrostSpikeDamage(), 1.55D, 100, 60, 1); + (float) AntarchySettings.royalGuardianSwordFrostSpikeDamage(), 2.2D, 100, 0, 0); level.addFreshEntity(spike); } } Vec3 center = primary.position().add(0.0D, 0.8D, 0.0D); level.sendParticles(ParticleTypes.SNOWFLAKE, center.x, center.y, center.z, 70, 1.3D, 1.1D, 1.3D, 0.1D); level.sendParticles(ParticleTypes.SNOWFLAKE, owner.getX(), owner.getY() + 1.0D, owner.getZ(), 18, 0.7D, 0.5D, 0.7D, 0.04D); - level.playSound(null, primary.blockPosition(), SoundEvents.GLASS_BREAK, SoundSource.PLAYERS, 1.0F, 0.6F); + level.playSound(null, primary.blockPosition(), AntarchySoundEvents.KING_ICE_SPIKES.get(), SoundSource.PLAYERS, 0.8F, 0.95F); } private static void chainLightning(ServerLevel level, Player owner, LivingEntity primary) { @@ -187,9 +190,10 @@ public final class RoyalGuardianSwordAbilities { double length = direction.length(); if (length > 0.001D) { Vec3 step = direction.scale(1.0D / length); - for (double d = 0.0D; d < length; d += 1.2D) { + for (double d = 0.0D; d < length; d += 0.35D) { Vec3 point = start.add(step.scale(d)); - level.sendParticles(STORM_GOLD, point.x, point.y, point.z, 2, 0.08D, 0.08D, 0.08D, 0.04D); + level.sendParticles(ParticleTypes.ELECTRIC_SPARK, point.x, point.y, point.z, 1, 0.025D, 0.025D, 0.025D, 0.0D); + level.sendParticles(STORM_GOLD, point.x, point.y, point.z, 1, 0.025D, 0.025D, 0.025D, 0.0D); } } level.sendParticles(ParticleTypes.ELECTRIC_SPARK, end.x, end.y, end.z, 18, 0.25D, 0.4D, 0.25D, 0.08D); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalGuardianSwordItem.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalGuardianSwordItem.java index d56f9d1a..1637ee43 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalGuardianSwordItem.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/item/RoyalGuardianSwordItem.java @@ -77,11 +77,11 @@ public class RoyalGuardianSwordItem extends SwordItem implements GeoItem { public InteractionResultHolder use(net.minecraft.world.level.Level level, Player player, InteractionHand hand) { ItemStack stack = player.getItemInHand(hand); if (!player.isShiftKeyDown()) return InteractionResultHolder.pass(stack); - cycleMode(level, player, stack); - return InteractionResultHolder.sidedSuccess(stack, level.isClientSide); + return InteractionResultHolder.pass(stack); } - private void cycleMode(net.minecraft.world.level.Level level, Player player, ItemStack stack) { + public boolean tryCycleModeFromInput(net.minecraft.world.level.Level level, Player player, ItemStack stack) { + if (player.getMainHandItem() != stack) return false; Mode next = getMode(stack).next(); setMode(stack, next); if (!level.isClientSide) { @@ -89,6 +89,7 @@ public class RoyalGuardianSwordItem extends SwordItem implements GeoItem { Component.translatable(next.translationKey)), true); level.playSound(null, player.blockPosition(), SoundEvents.AMETHYST_BLOCK_CHIME, SoundSource.PLAYERS, 0.8F, 0.8F + next.ordinal() * 0.2F); } + return true; } private static void setMode(ItemStack stack, Mode mode) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGameNetworkHandler.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGameNetworkHandler.java new file mode 100644 index 00000000..bea035cb --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGameNetworkHandler.java @@ -0,0 +1,121 @@ +package com.craisinlord.antarchy.content.network; + +import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.computer.AntarchyGameSavedData; +import com.craisinlord.antarchy.content.computer.blockle.BlockleAnswers; +import com.craisinlord.antarchy.content.computer.blockle.BlockleDictionary; +import com.craisinlord.antarchy.content.computer.blockle.BlockleGame; +import java.util.function.BiConsumer; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.Level; + +/** Handles Antarchy-specific game progress sent by AntOS game extensions. */ +public final class AntarchyGameNetworkHandler { + private static BiConsumer resultSender = (player, result) -> { }; + + private AntarchyGameNetworkHandler() { } + + public static void setResultSender(BiConsumer sender) { + resultSender = sender; + } + + public static void handle(ServerPlayer player, AntarchyGamePayload payload) { + BlockPos pos = payload.pos(); + if (payload.value().length() > 65536 || player.level().isClientSide || !player.serverLevel().hasChunkAt(pos) + || player.distanceToSqr(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D) > 64.0D) return; + + var blockEntity = player.serverLevel().getBlockEntity(pos); + if (!(blockEntity instanceof com.craisinlord.antos.content.block.entity.ComputerBlockEntity computer) + || !computer.canUseFileSystem(player)) { + send(player, payload, false, "", "unauthorized"); + return; + } + String key = AntarchyGameSavedData.key(player.serverLevel().dimension().location(), pos); + AntarchyGameSavedData.GameState state = AntarchyGameSavedData.get(player.server, key); + switch (payload.action()) { + case AntarchyGamePayload.BASILISK_STATE -> basilisk(player, payload, state); + case AntarchyGamePayload.ANTMAN_STATE -> antman(player, payload, state); + case AntarchyGamePayload.BLOCKLE_STATE -> blockle(player, computer, payload, state, false); + case AntarchyGamePayload.BLOCKLE_GUESS -> blockle(player, computer, payload, state, true); + default -> send(player, payload, false, "", "invalid"); + } + } + + private static void basilisk(ServerPlayer player, AntarchyGamePayload payload, AntarchyGameSavedData.GameState state) { + if (!payload.value().isBlank()) { + Integer score = parseScore(payload.value()); + if (score == null) { send(player, payload, false, "", "invalid_score"); return; } + state.basiliskScore = score; + state.basiliskHighScore = Math.max(state.basiliskHighScore, score); + AntarchyGameSavedData.changed(player.server); + } + send(player, payload, true, state.basiliskScore + "\0" + state.basiliskHighScore, ""); + } + + private static void antman(ServerPlayer player, AntarchyGamePayload payload, AntarchyGameSavedData.GameState state) { + if (!payload.value().isBlank()) { + Integer score = parseScore(payload.value()); + if (score == null) { send(player, payload, false, "", "invalid_score"); return; } + state.antmanScore = score; + state.antmanHighScore = Math.max(state.antmanHighScore, score); + AntarchyGameSavedData.changed(player.server); + } + send(player, payload, true, state.antmanScore + "\0" + state.antmanHighScore, ""); + } + + private static Integer parseScore(String value) { + try { return Math.min(1_000_000, Math.max(0, Integer.parseInt(value))); } + catch (NumberFormatException ignored) { return null; } + } + + private static void blockle(ServerPlayer player, + com.craisinlord.antos.content.block.entity.ComputerBlockEntity computer, + AntarchyGamePayload payload, AntarchyGameSavedData.GameState state, boolean submit) { + ResourceLocation disk = ResourceLocation.fromNamespaceAndPath("antarchy", "blockle_game"); + if (!AntarchySettings.unlockAllArchives() && !computer.diskIds().contains(disk)) { + send(player, payload, false, "", "not_installed"); return; + } + ServerLevel overworld = player.server.getLevel(Level.OVERWORLD); + if (overworld == null) { send(player, payload, false, "", "overworld_unavailable"); return; } + long day = overworld.getDayTime() / 24000L; + if (state.blockleDay != day) { + state.blockleDay = day; + state.blockleGuesses.clear(); + AntarchyGameSavedData.changed(player.server); + } + BlockleAnswers.Answer answer = BlockleAnswers.answerForDay(day); + if (answer == null) { send(player, payload, false, "", "answers_unavailable"); return; } + if (submit) { + String guess = payload.value().toLowerCase(java.util.Locale.ROOT); + if (guess.length() != 5 || !guess.chars().allMatch(value -> value >= 'a' && value <= 'z') || !BlockleDictionary.contains(guess)) { + send(player, payload, false, "", "invalid_word"); return; + } + if (state.blockleGuesses.size() >= 6 || state.blockleGuesses.contains(answer.word())) { + send(player, payload, false, "", "game_over"); return; + } + state.blockleGuesses.add(guess); + AntarchyGameSavedData.changed(player.server); + } + send(player, payload, true, encodeBlockle(day, answer, state.blockleGuesses), ""); + } + + private static String encodeBlockle(long day, BlockleAnswers.Answer answer, java.util.List guesses) { + StringBuilder result = new StringBuilder(Long.toString(day)); + boolean solved = false; + for (String guess : guesses) { + result.append('|').append(guess).append(',').append(BlockleGame.evaluate(answer.word(), guess)); + if (guess.equals(answer.word())) solved = true; + } + if (solved || guesses.size() >= 6) result.append('|').append(solved ? "SOLVED" : "FAILED").append('|').append(answer.word()).append('|').append(answer.itemId()); + else result.append('|').append("PLAYING"); + return result.toString(); + } + + private static void send(ServerPlayer player, AntarchyGamePayload payload, boolean success, String data, String error) { + resultSender.accept(player, new AntarchyGameResultPayload(payload.pos(), success, + payload.action() + "\0" + error + "\0" + data)); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGameNetworking.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGameNetworking.java new file mode 100644 index 00000000..82172cee --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGameNetworking.java @@ -0,0 +1,20 @@ +package com.craisinlord.antarchy.content.network; + +import net.minecraft.core.BlockPos; +import java.util.function.Consumer; + +/** Small Antarchy game-progress bridge over the AntOS computer session. */ +public final class AntarchyGameNetworking { + private static Consumer sender = payload -> { }; + private AntarchyGameNetworking() { } + + public static void setSender(Consumer sender) { AntarchyGameNetworking.sender = sender; } + public static void requestBasiliskState(BlockPos pos) { send(pos, AntarchyGamePayload.BASILISK_STATE, ""); } + public static void saveBasiliskScore(BlockPos pos, int score) { send(pos, AntarchyGamePayload.BASILISK_STATE, Integer.toString(Math.max(0, score))); } + public static void requestAntmanState(BlockPos pos) { send(pos, AntarchyGamePayload.ANTMAN_STATE, ""); } + public static void saveAntmanScore(BlockPos pos, int score) { send(pos, AntarchyGamePayload.ANTMAN_STATE, Integer.toString(Math.max(0, score))); } + public static void requestBlockleState(BlockPos pos) { send(pos, AntarchyGamePayload.BLOCKLE_STATE, ""); } + public static void submitBlockleGuess(BlockPos pos, String guess) { send(pos, AntarchyGamePayload.BLOCKLE_GUESS, guess); } + + private static void send(BlockPos pos, int action, String value) { sender.accept(new AntarchyGamePayload(pos, action, value)); } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGamePayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGamePayload.java new file mode 100644 index 00000000..da300daf --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGamePayload.java @@ -0,0 +1,32 @@ +package com.craisinlord.antarchy.content.network; + +import com.craisinlord.antarchy.Antarchy; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record AntarchyGamePayload(BlockPos pos, int action, String value) implements CustomPacketPayload { + public static final int BASILISK_STATE = 16; + public static final int ANTMAN_STATE = 17; + public static final int BLOCKLE_STATE = 18; + public static final int BLOCKLE_GUESS = 19; + public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antarchy_game")); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, AntarchyGamePayload::pos, + ByteBufCodecs.VAR_INT, AntarchyGamePayload::action, + ByteBufCodecs.stringUtf8(65536), AntarchyGamePayload::value, + AntarchyGamePayload::new + ); + + public AntarchyGamePayload(BlockPos pos, int action) { + this(pos, action, ""); + } + + @Override + public Type type() { + return TYPE; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGameResultPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGameResultPayload.java new file mode 100644 index 00000000..e1271351 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntarchyGameResultPayload.java @@ -0,0 +1,24 @@ +package com.craisinlord.antarchy.content.network; + +import com.craisinlord.antarchy.Antarchy; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record AntarchyGameResultPayload(BlockPos pos, boolean success, String data) implements CustomPacketPayload { + public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antarchy_game_result")); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, AntarchyGameResultPayload::pos, + ByteBufCodecs.BOOL, AntarchyGameResultPayload::success, + ByteBufCodecs.stringUtf8(65536), AntarchyGameResultPayload::data, + AntarchyGameResultPayload::new + ); + + @Override + public Type type() { + return TYPE; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailDeletePayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailDeletePayload.java deleted file mode 100644 index a2dceb8d..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailDeletePayload.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record AntmailDeletePayload(BlockPos pos, String messageId, boolean sent) implements CustomPacketPayload { - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antmail_delete")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite(BlockPos.STREAM_CODEC, AntmailDeletePayload::pos, ByteBufCodecs.stringUtf8(64), AntmailDeletePayload::messageId, ByteBufCodecs.BOOL, AntmailDeletePayload::sent, AntmailDeletePayload::new); - @Override public Type type() { return TYPE; } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailDraftPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailDraftPayload.java deleted file mode 100644 index dde362ef..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailDraftPayload.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record AntmailDraftPayload(BlockPos pos, int action, String data) implements CustomPacketPayload { - public static final int SAVE = 0; - public static final int DELETE = 1; - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antmail_draft")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite(BlockPos.STREAM_CODEC, AntmailDraftPayload::pos, ByteBufCodecs.VAR_INT, AntmailDraftPayload::action, ByteBufCodecs.stringUtf8(65536), AntmailDraftPayload::data, AntmailDraftPayload::new); - @Override public Type type() { return TYPE; } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailMessageRequestPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailMessageRequestPayload.java deleted file mode 100644 index 366c07c4..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailMessageRequestPayload.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record AntmailMessageRequestPayload(BlockPos pos, String messageId) implements CustomPacketPayload { - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antmail_message_request")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - BlockPos.STREAM_CODEC, AntmailMessageRequestPayload::pos, - ByteBufCodecs.stringUtf8(64), AntmailMessageRequestPayload::messageId, - AntmailMessageRequestPayload::new - ); - - @Override - public Type type() { - return TYPE; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailNetworking.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailNetworking.java deleted file mode 100644 index ff9a0cc6..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailNetworking.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.content.antmail.AntmailAttachment; -import com.craisinlord.antarchy.content.antmail.AntmailDebug; -import com.craisinlord.antarchy.content.antmail.AntmailDraft; -import com.craisinlord.antarchy.content.antmail.AntmailWire; -import net.minecraft.core.BlockPos; - -import java.util.List; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; - -public final class AntmailNetworking { - private static Consumer sender = payload -> { }; - private static volatile boolean senderConfigured; - private static final AtomicBoolean senderErrorLogged = new AtomicBoolean(); - - private AntmailNetworking() { - } - - public static void setSender(Consumer sender) { - AntmailNetworking.sender = sender; - senderConfigured = sender != null; - } - - public static void setup(BlockPos pos, String username) { - AntmailDebug.log("C2S setup request pos=" + pos + " usernameLength=" + username.length()); - sendPayload(new AntmailSetupPayload(pos, username)); - } - - public static void requestState(BlockPos pos) { - requestState(pos, AntmailStateRequestPayload.INBOX, 0, 0L); - } - - public static void requestState(BlockPos pos, int folder, int page) { - requestState(pos, folder, page, 0L); - } - - public static void requestState(BlockPos pos, int folder, int page, long knownVersion) { - AntmailDebug.log("C2S state request pos=" + pos + " folder=" + folder + " page=" + page + " knownVersion=" + knownVersion); - sendPayload(new AntmailStateRequestPayload(pos, folder, page, knownVersion)); - } - - public static void requestMessage(BlockPos pos, UUID messageId) { - sendPayload(new AntmailMessageRequestPayload(pos, messageId.toString())); - } - - public static void send(BlockPos pos, String recipient, String subject, String body, List attachments) { - sendPayload(new AntmailSendPayload(pos, recipient, subject, body, AntmailWire.encodeAttachments(attachments))); - } - - public static void markRead(BlockPos pos, UUID messageId) { - sendPayload(new AntmailReadPayload(pos, messageId.toString(), true)); - } - - public static void markUnread(BlockPos pos, UUID messageId) { - sendPayload(new AntmailReadPayload(pos, messageId.toString(), false)); - } - - public static void delete(BlockPos pos, UUID messageId, boolean sent) { - sendPayload(new AntmailDeletePayload(pos, messageId.toString(), sent)); - } - - public static void saveDraft(BlockPos pos, AntmailDraft draft) { - sendPayload(new AntmailDraftPayload(pos, AntmailDraftPayload.SAVE, AntmailWire.encodeTag(draft.toTag()))); - } - - public static void deleteDraft(BlockPos pos, UUID draftId) { - sendPayload(new AntmailDraftPayload(pos, AntmailDraftPayload.DELETE, draftId.toString())); - } - - public static void retry(BlockPos pos, UUID messageId) { - sendPayload(new AntmailRetryPayload(pos, messageId.toString())); - } - - private static void sendPayload(Object payload) { - if (!senderConfigured) { - if (senderErrorLogged.compareAndSet(false, true)) AntmailDebug.error("Network sender is not configured; dropping " + payload.getClass().getSimpleName(), new IllegalStateException("AntmailNetworking.setSender was not called")); - } - else sender.accept(payload); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailPayloadTypes.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailPayloadTypes.java deleted file mode 100644 index db991df6..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailPayloadTypes.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; - -import java.util.List; - -public final class AntmailPayloadTypes { - private AntmailPayloadTypes() { - } - - public static List> all() { - return List.of( - AntmailSetupPayload.TYPE, - AntmailStateRequestPayload.TYPE, - AntmailMessageRequestPayload.TYPE, - AntmailSendPayload.TYPE, - AntmailReadPayload.TYPE, - AntmailDeletePayload.TYPE, - AntmailDraftPayload.TYPE, - AntmailRetryPayload.TYPE, - AntmailResultPayload.TYPE - ); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailReadPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailReadPayload.java deleted file mode 100644 index 017e7f6c..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailReadPayload.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record AntmailReadPayload(BlockPos pos, String messageId, boolean read) implements CustomPacketPayload { - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antmail_read")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite(BlockPos.STREAM_CODEC, AntmailReadPayload::pos, ByteBufCodecs.stringUtf8(64), AntmailReadPayload::messageId, ByteBufCodecs.BOOL, AntmailReadPayload::read, AntmailReadPayload::new); - @Override public Type type() { return TYPE; } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailResultPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailResultPayload.java deleted file mode 100644 index 8a4860cc..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailResultPayload.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record AntmailResultPayload(BlockPos pos, int status, String address, String messageId, String detail, String data, long version) implements CustomPacketPayload { - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antmail_result")); - public static final StreamCodec STREAM_CODEC = StreamCodec.of( - (buf, payload) -> { - BlockPos.STREAM_CODEC.encode(buf, payload.pos()); - ByteBufCodecs.VAR_INT.encode(buf, payload.status()); - ByteBufCodecs.stringUtf8(64).encode(buf, payload.address()); - ByteBufCodecs.stringUtf8(64).encode(buf, payload.messageId()); - ByteBufCodecs.stringUtf8(128).encode(buf, payload.detail()); - ByteBufCodecs.stringUtf8(65536).encode(buf, payload.data()); - ByteBufCodecs.VAR_LONG.encode(buf, payload.version()); - }, - buf -> new AntmailResultPayload( - BlockPos.STREAM_CODEC.decode(buf), - ByteBufCodecs.VAR_INT.decode(buf), - ByteBufCodecs.stringUtf8(64).decode(buf), - ByteBufCodecs.stringUtf8(64).decode(buf), - ByteBufCodecs.stringUtf8(128).decode(buf), - ByteBufCodecs.stringUtf8(65536).decode(buf), - ByteBufCodecs.VAR_LONG.decode(buf) - )); - @Override public Type type() { return TYPE; } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailRetryPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailRetryPayload.java deleted file mode 100644 index 71c9d724..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailRetryPayload.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record AntmailRetryPayload(BlockPos pos, String messageId) implements CustomPacketPayload { - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antmail_retry")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite(BlockPos.STREAM_CODEC, AntmailRetryPayload::pos, ByteBufCodecs.stringUtf8(64), AntmailRetryPayload::messageId, AntmailRetryPayload::new); - @Override public Type type() { return TYPE; } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailSendPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailSendPayload.java deleted file mode 100644 index a34221b2..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailSendPayload.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record AntmailSendPayload(BlockPos pos, String recipient, String subject, String body, String attachments) implements CustomPacketPayload { - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antmail_send")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite(BlockPos.STREAM_CODEC, AntmailSendPayload::pos, ByteBufCodecs.stringUtf8(64), AntmailSendPayload::recipient, ByteBufCodecs.stringUtf8(64), AntmailSendPayload::subject, ByteBufCodecs.stringUtf8(16384), AntmailSendPayload::body, ByteBufCodecs.stringUtf8(65536), AntmailSendPayload::attachments, AntmailSendPayload::new); - @Override public Type type() { return TYPE; } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailServerHandler.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailServerHandler.java deleted file mode 100644 index 5230e6c6..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailServerHandler.java +++ /dev/null @@ -1,266 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.content.antmail.AntmailAddress; -import com.craisinlord.antarchy.content.antmail.AntmailDebug; -import com.craisinlord.antarchy.content.antmail.AntmailAttachment; -import com.craisinlord.antarchy.content.antmail.AntmailDeliveryResult; -import com.craisinlord.antarchy.content.antmail.AntmailDraft; -import com.craisinlord.antarchy.content.antmail.AntmailMessage; -import com.craisinlord.antarchy.content.antmail.AntmailMailbox; -import com.craisinlord.antarchy.content.antmail.AntmailServerData; -import com.craisinlord.antarchy.content.antmail.AntmailValidation; -import com.craisinlord.antarchy.content.antmail.AntmailWire; -import com.craisinlord.antarchy.content.block.entity.ComputerBlockEntity; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.level.block.entity.BlockEntity; - -import java.util.List; -import java.util.UUID; -import java.util.function.BiConsumer; - -public final class AntmailServerHandler { - private static BiConsumer resultSender = (player, payload) -> { }; - private static volatile boolean resultSenderConfigured; - - private AntmailServerHandler() { - } - - public static void setResultSender(BiConsumer sender) { - resultSender = sender; - resultSenderConfigured = sender != null; - } - - public static void handle(ServerPlayer player, AntmailSetupPayload payload) { - AntmailDebug.log("C2S setup received player=" + player.getGameProfile().getName() + " pos=" + payload.pos() - + " usernameLength=" + payload.username().length()); - ComputerBlockEntity computer = computer(player, payload.pos()); - if (computer == null || !computer.canUseFileSystem(player)) { - AntmailDebug.log("setup rejected: computer missing, out of reach, unauthenticated, or owned by another user"); - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), "", "", "registration_failed:unauthorized", ""); - return; - } - AntmailServerData data = AntmailServerData.access(player.server); - AntmailServerData.Registration registration = data.register(player.server, player.serverLevel(), payload.pos(), payload.username()); - if (registration.valid()) data.setLastUsedAddress(player, registration.address()); - String mailbox = registration.valid() ? AntmailWire.encodeTag(data.mailboxOrCreate(registration.address()).toTag(false)) : ""; - String detail = registration.valid() ? "registration_success" : "registration_failed:" + registration.reason(); - result(player, payload.pos(), registration.valid() ? AntmailDeliveryResult.Status.DELIVERED.ordinal() : AntmailDeliveryResult.Status.FAILED.ordinal(), registration.valid() ? registration.address().fullAddress() : "", "", detail, mailbox); - } - - public static void handle(ServerPlayer player, AntmailStateRequestPayload payload) { - AntmailDebug.log("state request received player=" + player.getGameProfile().getName() + " pos=" + payload.pos() - + " folder=" + payload.folder() + " page=" + payload.page() + " knownVersion=" + payload.knownVersion()); - ComputerBlockEntity computer = authorizedComputer(player, payload.pos()); - if (computer == null) { - AntmailDebug.log("state request rejected: computer missing, out of reach, unauthenticated, or owned by another user"); - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), "", "", "unauthorized", ""); - return; - } - AntmailServerData data = AntmailServerData.access(player.server); - data.drainAddress(player.server, player.serverLevel(), payload.pos()); - AntmailAddress address = data.addressAt(player.serverLevel().dimension().location(), payload.pos()); - if (address == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.ADDRESS_NOT_FOUND.ordinal(), "", "", "unconfigured", ""); - return; - } - AntmailMailbox mailbox = data.mailboxOrCreate(address); - if (payload.knownVersion() == data.mailboxVersion(address)) { - result(player, payload.pos(), AntmailDeliveryResult.Status.DELIVERED.ordinal(), address.fullAddress(), "", "unchanged", ""); - return; - } - int folder = payload.folder() < AntmailStateRequestPayload.INBOX || payload.folder() > AntmailStateRequestPayload.DRAFTS - ? AntmailStateRequestPayload.INBOX : payload.folder(); - int page = Math.max(0, Math.min(payload.page(), AntmailValidation.MAX_MAILBOX_MESSAGES / AntmailMailbox.PAGE_SIZE)); - try { - String encoded = AntmailWire.encodeTag(mailbox.toPageTag(folder, page)); - result(player, payload.pos(), AntmailDeliveryResult.Status.DELIVERED.ordinal(), address.fullAddress(), "", "", encoded); - } catch (RuntimeException exception) { - AntmailDebug.error("Failed to encode state for " + address.fullAddress() + " at " + payload.pos(), exception); - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), address.fullAddress(), "", "state_encode_failed", ""); - } - } - - public static void handle(ServerPlayer player, AntmailMessageRequestPayload payload) { - ComputerBlockEntity computer = authorizedComputer(player, payload.pos()); - if (computer == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), "", payload.messageId(), "unauthorized", ""); - return; - } - AntmailServerData data = AntmailServerData.access(player.server); - AntmailAddress address = data.addressAt(player.serverLevel().dimension().location(), payload.pos()); - if (address == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.ADDRESS_NOT_FOUND.ordinal(), "", payload.messageId(), "unconfigured", ""); - return; - } - try { - UUID id = UUID.fromString(payload.messageId()); - AntmailMailbox mailbox = data.mailboxOrCreate(address); - AntmailMessage message = mailbox.findInbox(id); - if (message == null) message = mailbox.findSent(id); - if (message == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), address.fullAddress(), payload.messageId(), "not_found", ""); - return; - } - result(player, payload.pos(), AntmailDeliveryResult.Status.DELIVERED.ordinal(), address.fullAddress(), payload.messageId(), "message_detail", AntmailWire.encodeTag(message.toTag())); - } catch (IllegalArgumentException exception) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), address.fullAddress(), payload.messageId(), "invalid_id", ""); - } - } - - public static void handle(ServerPlayer player, AntmailSendPayload payload) { - ComputerBlockEntity computer = authorizedComputer(player, payload.pos()); - if (computer == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), "", "", "unauthorized", ""); - return; - } - AntmailServerData data = AntmailServerData.access(player.server); - AntmailAddress sender = data.addressAt(player.serverLevel().dimension().location(), payload.pos()); - if (sender == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), "", "", "unconfigured", ""); - return; - } - try { - AntmailAddress recipient = AntmailAddress.parse(payload.recipient()); - List attachments = AntmailWire.decodeAttachments(payload.attachments()); - AntmailMessage message = AntmailMessage.create(sender, recipient, payload.subject(), payload.body(), player.serverLevel().getGameTime(), attachments); - AntmailDeliveryResult delivery = data.deliver(player.server, message); - result(player, payload.pos(), delivery.status().ordinal(), sender.fullAddress(), message.id().toString(), delivery.detail(), AntmailWire.encodeTag(data.mailboxOrCreate(sender).toTag(false))); - } catch (RuntimeException exception) { - result(player, payload.pos(), AntmailDeliveryResult.Status.MESSAGE_INVALID.ordinal(), "", "", "invalid_message", ""); - } - } - - public static void handle(ServerPlayer player, AntmailReadPayload payload) { - ComputerBlockEntity computer = authorizedComputer(player, payload.pos()); - if (computer == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), "", payload.messageId(), "unauthorized", ""); - return; - } - AntmailServerData data = AntmailServerData.access(player.server); - AntmailAddress address = data.addressAt(player.serverLevel().dimension().location(), payload.pos()); - if (address == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.ADDRESS_NOT_FOUND.ordinal(), "", payload.messageId(), "unconfigured", ""); - return; - } - try { - UUID id = UUID.fromString(payload.messageId()); - AntmailMailbox mailbox = data.mailboxOrCreate(address); - boolean changed = payload.read() ? mailbox.markRead(id) : markUnread(mailbox, id); - if (changed) data.touchMailbox(address); - result(player, payload.pos(), changed ? AntmailDeliveryResult.Status.DELIVERED.ordinal() : AntmailDeliveryResult.Status.FAILED.ordinal(), address.fullAddress(), payload.messageId(), changed ? "" : "not_found", AntmailWire.encodeTag(mailbox.toTag(false))); - } catch (IllegalArgumentException exception) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), address.fullAddress(), payload.messageId(), "invalid_id", ""); - } - } - - public static void handle(ServerPlayer player, AntmailDeletePayload payload) { - ComputerBlockEntity computer = authorizedComputer(player, payload.pos()); - if (computer == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), "", payload.messageId(), "unauthorized", ""); - return; - } - AntmailServerData data = AntmailServerData.access(player.server); - AntmailAddress address = data.addressAt(player.serverLevel().dimension().location(), payload.pos()); - if (address == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.ADDRESS_NOT_FOUND.ordinal(), "", payload.messageId(), "unconfigured", ""); - return; - } - try { - UUID id = UUID.fromString(payload.messageId()); - AntmailMailbox mailbox = data.mailboxOrCreate(address); - boolean changed = payload.sent() ? mailbox.removeSent(id) : mailbox.removeInbox(id); - if (changed) data.touchMailbox(address); - result(player, payload.pos(), changed ? AntmailDeliveryResult.Status.DELIVERED.ordinal() : AntmailDeliveryResult.Status.FAILED.ordinal(), address.fullAddress(), payload.messageId(), changed ? "" : "not_found", AntmailWire.encodeTag(mailbox.toTag(false))); - } catch (IllegalArgumentException exception) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), address.fullAddress(), payload.messageId(), "invalid_id", ""); - } - } - - public static void handle(ServerPlayer player, AntmailDraftPayload payload) { - ComputerBlockEntity computer = authorizedComputer(player, payload.pos()); - if (computer == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), "", "", "unauthorized", ""); - return; - } - AntmailServerData data = AntmailServerData.access(player.server); - AntmailAddress address = data.addressAt(player.serverLevel().dimension().location(), payload.pos()); - if (address == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.ADDRESS_NOT_FOUND.ordinal(), "", "", "unconfigured", ""); - return; - } - AntmailMailbox mailbox = data.mailboxOrCreate(address); - try { - if (payload.action() == AntmailDraftPayload.SAVE) { - AntmailDraft draft = AntmailDraft.fromTag(AntmailWire.decodeTag(payload.data())); - AntmailDraft stored = new AntmailDraft(draft.id(), address, draft.recipient(), draft.subject(), draft.body(), draft.attachments()); - if (!mailbox.saveDraft(stored)) throw new IllegalArgumentException("draft_limit"); - } else if (payload.action() == AntmailDraftPayload.DELETE) { - if (!mailbox.removeDraft(UUID.fromString(payload.data()))) throw new IllegalArgumentException("not_found"); - } else { - throw new IllegalArgumentException("invalid_action"); - } - data.touchMailbox(address); - result(player, payload.pos(), AntmailDeliveryResult.Status.DELIVERED.ordinal(), address.fullAddress(), "", "draft_saved", AntmailWire.encodeTag(mailbox.toTag(false))); - } catch (RuntimeException exception) { - result(player, payload.pos(), AntmailDeliveryResult.Status.MESSAGE_INVALID.ordinal(), address.fullAddress(), "", "draft_failed", AntmailWire.encodeTag(mailbox.toTag(false))); - } - } - - public static void handle(ServerPlayer player, AntmailRetryPayload payload) { - ComputerBlockEntity computer = authorizedComputer(player, payload.pos()); - if (computer == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.FAILED.ordinal(), "", payload.messageId(), "unauthorized", ""); - return; - } - AntmailServerData data = AntmailServerData.access(player.server); - AntmailAddress sender = data.addressAt(player.serverLevel().dimension().location(), payload.pos()); - if (sender == null) { - result(player, payload.pos(), AntmailDeliveryResult.Status.ADDRESS_NOT_FOUND.ordinal(), "", payload.messageId(), "unconfigured", ""); - return; - } - try { - AntmailDeliveryResult delivery = data.retry(player.server, sender, UUID.fromString(payload.messageId())); - AntmailMailbox mailbox = data.mailboxOrCreate(sender); - result(player, payload.pos(), delivery == null ? AntmailDeliveryResult.Status.MESSAGE_INVALID.ordinal() : delivery.status().ordinal(), sender.fullAddress(), payload.messageId(), delivery == null ? "not_found" : delivery.detail(), AntmailWire.encodeTag(mailbox.toTag(false))); - } catch (IllegalArgumentException exception) { - result(player, payload.pos(), AntmailDeliveryResult.Status.MESSAGE_INVALID.ordinal(), sender.fullAddress(), payload.messageId(), "invalid_id", ""); - } - } - - private static ComputerBlockEntity authorizedComputer(ServerPlayer player, BlockPos pos) { - ComputerBlockEntity computer = computer(player, pos); - return computer != null && computer.canUseFileSystem(player) ? computer : null; - } - - private static boolean markUnread(AntmailMailbox mailbox, UUID id) { - for (com.craisinlord.antarchy.content.antmail.AntmailMessage message : mailbox.inbox()) { - if (message.id().equals(id)) { - message.markUnread(); - return true; - } - } - return false; - } - - private static ComputerBlockEntity computer(ServerPlayer player, BlockPos pos) { - if (!player.serverLevel().hasChunkAt(pos) || player.distanceToSqr(pos.getX() + .5D, pos.getY() + .5D, pos.getZ() + .5D) > 64D) return null; - BlockEntity blockEntity = player.serverLevel().getBlockEntity(pos); - return blockEntity instanceof ComputerBlockEntity computer ? computer : null; - } - - private static void result(ServerPlayer player, BlockPos pos, int status, String address, String messageId, String detail, String data) { - long version = 0L; - try { - if (!address.isBlank()) version = AntmailServerData.access(player.server).mailboxVersion(AntmailAddress.parse(address)); - } catch (IllegalArgumentException ignored) { - } - AntmailDebug.log("sending result player=" + player.getGameProfile().getName() + " pos=" + pos + " status=" + status - + " detail=" + detail + " addressPresent=" + !address.isBlank() + " dataChars=" + data.length() + " version=" + version); - if (!resultSenderConfigured) { - AntmailDebug.error("Result sender is not configured; dropping response at " + pos, new IllegalStateException("AntmailServerHandler.setResultSender was not called")); - return; - } - resultSender.accept(player, new AntmailResultPayload(pos, status, address, messageId, detail, data, version)); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailSetupPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailSetupPayload.java deleted file mode 100644 index 8c93d6ce..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailSetupPayload.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record AntmailSetupPayload(BlockPos pos, String username) implements CustomPacketPayload { - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antmail_setup")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite(BlockPos.STREAM_CODEC, AntmailSetupPayload::pos, ByteBufCodecs.stringUtf8(32), AntmailSetupPayload::username, AntmailSetupPayload::new); - @Override public Type type() { return TYPE; } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailStateRequestPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailStateRequestPayload.java deleted file mode 100644 index 095b54e7..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/AntmailStateRequestPayload.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record AntmailStateRequestPayload(BlockPos pos, int folder, int page, long knownVersion) implements CustomPacketPayload { - public static final int INBOX = 0; - public static final int SENT = 1; - public static final int DRAFTS = 2; - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antmail_state_request")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - BlockPos.STREAM_CODEC, AntmailStateRequestPayload::pos, - ByteBufCodecs.VAR_INT, AntmailStateRequestPayload::folder, - ByteBufCodecs.VAR_INT, AntmailStateRequestPayload::page, - ByteBufCodecs.VAR_LONG, AntmailStateRequestPayload::knownVersion, - AntmailStateRequestPayload::new); - @Override public Type type() { return TYPE; } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerAccessHandler.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerAccessHandler.java deleted file mode 100644 index 7aaa3c8b..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerAccessHandler.java +++ /dev/null @@ -1,455 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.content.block.entity.ComputerBlockEntity; -import com.craisinlord.antarchy.content.computer.ComputerFileSystem; -import com.craisinlord.antarchy.content.computer.terminal.TerminalCommandService; -import com.craisinlord.antarchy.content.computer.terminal.TerminalFileSystem; -import com.craisinlord.antarchy.content.computer.terminal.TerminalResult; -import com.craisinlord.antarchy.config.AntarchySettings; -import com.craisinlord.antarchy.content.antmail.AntmailWire; -import com.craisinlord.antarchy.content.computer.blockle.BlockleAnswers; -import com.craisinlord.antarchy.content.computer.blockle.BlockleDictionary; -import com.craisinlord.antarchy.content.computer.blockle.BlockleGame; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.Level; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.core.registries.Registries; -import net.minecraft.tags.TagKey; -import net.minecraft.world.level.levelgen.structure.Structure; -import net.minecraft.world.level.block.entity.BlockEntity; - -import java.util.function.BiConsumer; - -public final class ComputerAccessHandler { - private static BiConsumer resultSender = (player, result) -> { - }; - - private ComputerAccessHandler() { - } - - public static void setResultSender(BiConsumer sender) { - resultSender = sender; - } - - public static void handle(ServerPlayer player, ComputerAccessPayload payload) { - if (payload.value().length() > 65536 || player.level().isClientSide || !player.serverLevel().hasChunkAt(payload.pos()) || - player.distanceToSqr(payload.pos().getX() + 0.5D, payload.pos().getY() + 0.5D, payload.pos().getZ() + 0.5D) > 64.0D) { - return; - } - BlockEntity blockEntity = player.serverLevel().getBlockEntity(payload.pos()); - if (!(blockEntity instanceof ComputerBlockEntity computer)) { - send(player, payload, ComputerAccessResultPayload.INVALID); - return; - } - switch (payload.action()) { - case ComputerAccessPayload.OPEN -> open(player, computer, payload); - case ComputerAccessPayload.SETUP -> setup(player, computer, payload); - case ComputerAccessPayload.LOGIN -> login(player, computer, payload); - case ComputerAccessPayload.LOGOUT -> { - computer.logout(); - send(player, payload, ComputerAccessResultPayload.READY); - } - case ComputerAccessPayload.CLOSE -> { - computer.releaseUser(player); - send(player, payload, computer.isAuthenticated() ? ComputerAccessResultPayload.SUCCESS : ComputerAccessResultPayload.READY); - } - case ComputerAccessPayload.CHANGE_PASSWORD -> { - boolean changed = computer.setPassword(player, payload.value()); - send(player, payload, changed ? ComputerAccessResultPayload.SUCCESS : ComputerAccessResultPayload.INVALID_PASSWORD); - } - case ComputerAccessPayload.EJECT -> eject(player, computer, payload); - case ComputerAccessPayload.FILE_LIST -> fileList(player, computer, payload); - case ComputerAccessPayload.FILE_OPEN -> fileOpen(player, computer, payload); - case ComputerAccessPayload.FILE_CREATE -> fileCreate(player, computer, payload); - case ComputerAccessPayload.FILE_SAVE -> fileSave(player, computer, payload); - case ComputerAccessPayload.FILE_DELETE -> fileDelete(player, computer, payload); - case ComputerAccessPayload.FILE_MOVE -> fileMove(player, computer, payload); - case ComputerAccessPayload.TERMINAL_COMMAND -> terminalCommand(player, computer, payload); - case ComputerAccessPayload.DESKTOP_STATE -> desktopState(player, computer, payload); - case ComputerAccessPayload.DESKTOP_WALLPAPER -> desktopWallpaper(player, computer, payload); - case ComputerAccessPayload.BASILISK_STATE -> basiliskState(player, computer, payload); - case ComputerAccessPayload.ANTMAN_STATE -> antmanState(player, computer, payload); - case ComputerAccessPayload.BLOCKLE_STATE -> blockleState(player, computer, payload, false); - case ComputerAccessPayload.BLOCKLE_GUESS -> blockleState(player, computer, payload, true); - case ComputerAccessPayload.LOCATE_STRUCTURE -> locateStructure(player, computer, payload); - default -> send(player, payload, ComputerAccessResultPayload.INVALID); - } - } - - private static void open(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (computer.hasActiveUser() && !computer.isAuthenticatedBy(player)) { - send(player, payload, ComputerAccessResultPayload.BUSY); - sendArchive(player, computer, payload); - return; - } - if (!computer.hasPassword()) { - computer.claimUser(player); - send(player, payload, ComputerAccessResultPayload.SETUP_REQUIRED); - } else if (computer.isAuthenticated()) { - computer.claimUser(player); - send(player, payload, ComputerAccessResultPayload.SUCCESS); - } else { - send(player, payload, ComputerAccessResultPayload.READY); - } - sendArchive(player, computer, payload); - } - - private static void sendArchive(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - resultSender.accept(player, new ComputerAccessResultPayload(payload.pos(), ComputerAccessResultPayload.SUCCESS, - computer.hasPassword(), computer.isAuthenticated(), ComputerAccessPayload.ARCHIVE_STATE + "\0\0" - + com.craisinlord.antarchy.content.guide.ComputerGuideData.encodeNetworkSnapshot())); - } - - private static void setup(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.hasPassword() && computer.initializePassword(player, payload.value())) { - send(player, payload, ComputerAccessResultPayload.SUCCESS); - } else { - send(player, payload, computer.hasActiveUser() ? ComputerAccessResultPayload.BUSY : ComputerAccessResultPayload.INVALID_PASSWORD); - } - } - - private static void login(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (computer.hasActiveUser() && !computer.isAuthenticatedBy(player)) { - send(player, payload, ComputerAccessResultPayload.BUSY); - } else if (computer.authenticate(player, payload.value())) { - com.craisinlord.antarchy.content.antmail.AntmailServerData data = com.craisinlord.antarchy.content.antmail.AntmailServerData.access(player.server); - net.minecraft.resources.ResourceLocation dimension = player.serverLevel().dimension().location(); - com.craisinlord.antarchy.content.antmail.AntmailAddress address = data.addressAt(dimension, computer.getBlockPos()); - if (address != null) data.setLastUsedAddress(player, address); - send(player, payload, ComputerAccessResultPayload.SUCCESS); - } else { - send(player, payload, ComputerAccessResultPayload.INVALID_PASSWORD); - } - } - - private static void eject(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - try { - ResourceLocation diskId = ResourceLocation.parse(payload.value()); - boolean ejected = computer.ejectOne(player, diskId); - send(player, payload, ejected ? ComputerAccessResultPayload.SUCCESS : ComputerAccessResultPayload.INVALID); - } catch (Exception ignored) { - send(player, payload, ComputerAccessResultPayload.INVALID); - } - } - - private static void fileList(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.canUseFileSystem(player)) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - StringBuilder data = new StringBuilder(); - for (ComputerFileSystem.ComputerFile file : computer.fileSystem().list()) { - if (!data.isEmpty()) data.append('\n'); - data.append(file.type().name()).append('\t').append(file.path()).append('\t').append(file.contents().length()); - } - sendFile(player, payload, true, data.toString(), ""); - } - - private static void fileOpen(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.canUseFileSystem(player)) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - ComputerFileSystem.ComputerFile file = computer.fileSystem().get(payload.value()); - if (file == null) { - sendFile(player, payload, false, "", "not_found"); - } else if (file.type() != ComputerFileSystem.ComputerFile.Type.TEXT && file.type() != ComputerFileSystem.ComputerFile.Type.IMAGE) { - sendFile(player, payload, false, "", "not_file"); - } else { - sendFile(player, payload, true, file.path() + "\0" + file.contents(), ""); - } - } - - private static void fileCreate(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.canUseFileSystem(player)) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - String[] request = splitFileRequest(payload.value()); - if (request == null) { - sendFile(player, payload, false, "", "invalid_request"); - return; - } - ComputerFileSystem.Result result = computer.fileSystem().createTextFile(request[0], request[1]); - if (result.successful()) computer.setChanged(); - sendFile(player, payload, result.successful(), request[0], result.error()); - } - - private static void fileSave(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.canUseFileSystem(player)) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - String[] request = splitFileRequest(payload.value()); - if (request == null) { - sendFile(player, payload, false, "", "invalid_request"); - return; - } - ComputerFileSystem.Result result = computer.fileSystem().writeTextFile(request[0], request[1]); - if (result.successful()) computer.setChanged(); - sendFile(player, payload, result.successful(), request[0], result.error()); - } - - private static void fileDelete(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.canUseFileSystem(player)) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - ComputerFileSystem.Result result = computer.fileSystem().delete(payload.value()); - if (result.successful()) computer.setChanged(); - sendFile(player, payload, result.successful(), payload.value(), result.error()); - } - - private static void fileMove(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.canUseFileSystem(player)) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - String[] request = splitFileRequest(payload.value()); - if (request == null) { - sendFile(player, payload, false, "", "invalid_request"); - return; - } - ComputerFileSystem.Result result = computer.fileSystem().move(request[0], request[1]); - if (result.successful()) computer.setChanged(); - sendFile(player, payload, result.successful(), request[1], result.error()); - } - - private static void terminalCommand(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - String[] request = splitFileRequest(payload.value()); - if (request == null) { - sendTerminal(player, payload, TerminalResult.error("/", "ERROR: INVALID REQUEST")); - return; - } - TerminalResult result = new TerminalCommandService().execute(new ComputerTerminalFileSystem(computer.fileSystem()), request[0], request[1]); - if (result.status() != TerminalResult.Status.SUCCESS || !result.lines().isEmpty() || result.clearOutput() || result.openPath() != null) computer.setChanged(); - sendTerminal(player, payload, result); - } - - private static void sendTerminal(ServerPlayer player, ComputerAccessPayload payload, TerminalResult result) { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - tag.putString("Directory", result.workingDirectory()); - tag.putBoolean("Clear", result.clearOutput()); - tag.putString("Open", result.openPath() == null ? "" : result.openPath()); - net.minecraft.nbt.ListTag lines = new net.minecraft.nbt.ListTag(); - for (String line : result.lines()) lines.add(net.minecraft.nbt.StringTag.valueOf(line)); - tag.put("Lines", lines); - resultSender.accept(player, new ComputerAccessResultPayload(payload.pos(), result.status() == TerminalResult.Status.ERROR ? ComputerAccessResultPayload.INVALID : ComputerAccessResultPayload.SUCCESS, - true, true, payload.action() + "\0" + AntmailWire.encodeTag(tag))); - } - - private static final class ComputerTerminalFileSystem implements TerminalFileSystem { - private final ComputerFileSystem fileSystem; - - private ComputerTerminalFileSystem(ComputerFileSystem fileSystem) { this.fileSystem = fileSystem; } - - @Override public java.util.Optional find(String path, String workingDirectory) { - ComputerFileSystem.ComputerFile file = fileSystem.get(resolve(path, workingDirectory)); - return file == null ? java.util.Optional.empty() : java.util.Optional.of(new Entry(file.path(), file.path(), file.type() == ComputerFileSystem.ComputerFile.Type.DIRECTORY ? EntryType.DIRECTORY : EntryType.FILE)); - } - @Override public java.util.List list(String path, String workingDirectory) { - String directory = resolve(path, workingDirectory); - return fileSystem.list().stream().filter(file -> { - String parent = file.path().lastIndexOf('/') <= 0 ? "/" : file.path().substring(0, file.path().lastIndexOf('/')); - return parent.equals(directory) && !file.path().equals(directory); - }).map(file -> new Entry(file.path().substring(file.path().lastIndexOf('/') + 1), file.path(), file.type() == ComputerFileSystem.ComputerFile.Type.DIRECTORY ? EntryType.DIRECTORY : EntryType.FILE)).toList(); - } - @Override public boolean createDirectory(String path, String workingDirectory) { return fileSystem.createDirectory(resolve(path, workingDirectory)).successful(); } - @Override public boolean createFile(String path, String workingDirectory) { return fileSystem.createTextFile(resolve(path, workingDirectory), "").successful(); } - @Override public java.util.Optional readText(String path, String workingDirectory) { ComputerFileSystem.ComputerFile file = fileSystem.get(resolve(path, workingDirectory)); return file != null && file.type() == ComputerFileSystem.ComputerFile.Type.TEXT ? java.util.Optional.of(file.contents()) : java.util.Optional.empty(); } - @Override public boolean writeText(String path, String workingDirectory, String contents) { return fileSystem.createOrWriteTextFile(resolve(path, workingDirectory), contents).successful(); } - @Override public boolean deleteFile(String path, String workingDirectory) { return fileSystem.delete(resolve(path, workingDirectory)).successful(); } - @Override public boolean deleteEmptyDirectory(String path, String workingDirectory) { return fileSystem.delete(resolve(path, workingDirectory)).successful(); } - @Override public boolean move(String source, String destination, String workingDirectory) { return fileSystem.move(resolve(source, workingDirectory), resolve(destination, workingDirectory)).successful(); } - @Override public String normalize(String path, String workingDirectory) { return resolve(path, workingDirectory); } - - private String resolve(String path, String workingDirectory) { - if (path == null || path.isBlank()) return ComputerFileSystem.normalize(workingDirectory); - return ComputerFileSystem.normalize(path.startsWith("/") ? path : ComputerFileSystem.normalize(workingDirectory) + "/" + path); - } - } - - private static void desktopState(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.canUseFileSystem(player)) { - sendDesktop(player, payload, false, "unauthorized"); - return; - } - sendDesktop(player, payload, true, AntmailWire.encodeTag(computer.desktopState().save())); - } - - private static void desktopWallpaper(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.canUseFileSystem(player)) { - sendDesktop(player, payload, false, "unauthorized"); - return; - } - try { - boolean changed = computer.selectWallpaper(ResourceLocation.parse(payload.value())); - sendDesktop(player, payload, changed, changed ? "" : "wallpaper_locked"); - } catch (RuntimeException exception) { - sendDesktop(player, payload, false, "invalid_wallpaper"); - } - } - - private static void basiliskState(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.canUseFileSystem(player)) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - if (!payload.value().isBlank()) { - try { - computer.setBasiliskScore(Integer.parseInt(payload.value())); - } catch (NumberFormatException ignored) { - sendFile(player, payload, false, "", "invalid_score"); - return; - } - } - sendFile(player, payload, true, computer.basiliskScore() + "\0" + computer.basiliskHighScore(), ""); - } - - private static void antmanState(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - if (!computer.canUseFileSystem(player)) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - if (!payload.value().isBlank()) { - try { - computer.setAntmanScore(Integer.parseInt(payload.value())); - } catch (NumberFormatException ignored) { - sendFile(player, payload, false, "", "invalid_score"); - return; - } - } - sendFile(player, payload, true, computer.antmanScore() + "\0" + computer.antmanHighScore(), ""); - } - - private static void blockleState(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload, boolean submit) { - if (!computer.canUseFileSystem(player)) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - ResourceLocation disk = ResourceLocation.fromNamespaceAndPath("antarchy", "blockle_game"); - if (!AntarchySettings.unlockAllArchives() && !computer.diskIds().contains(disk)) { - sendFile(player, payload, false, "", "not_installed"); - return; - } - ServerLevel overworld = player.server.getLevel(Level.OVERWORLD); - if (overworld == null) { - sendFile(player, payload, false, "", "overworld_unavailable"); - return; - } - long day = overworld.getDayTime() / 24000L; - computer.resetBlockle(day); - BlockleAnswers.Answer answer = BlockleAnswers.answerForDay(day); - if (answer == null) { - sendFile(player, payload, false, "", "answers_unavailable"); - return; - } - if (submit) { - String guess = payload.value() == null ? "" : payload.value().toLowerCase(java.util.Locale.ROOT); - if (guess.length() != 5 || !guess.chars().allMatch(value -> value >= 'a' && value <= 'z')) { - sendFile(player, payload, false, "", "invalid_word"); - return; - } - if (!BlockleDictionary.contains(guess)) { - sendFile(player, payload, false, "", "invalid_word"); - return; - } - if (computer.blockleGuesses().size() >= 6 || computer.blockleGuesses().stream().anyMatch(value -> value.equals(answer.word()))) { - sendFile(player, payload, false, "", "game_over"); - return; - } - computer.addBlockleGuess(guess); - } - sendFile(player, payload, true, encodeBlockle(day, answer, computer.blockleGuesses()), ""); - } - - private static void locateStructure(ServerPlayer player, ComputerBlockEntity computer, ComputerAccessPayload payload) { - ResourceLocation entryId; - try { - entryId = ResourceLocation.parse(payload.value()); - } catch (RuntimeException exception) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - var entry = com.craisinlord.antarchy.content.guide.ComputerGuideData.entry(entryId); - boolean unlocked = com.craisinlord.antarchy.content.guide.ComputerGuideData.entriesFor(computer.diskIds()).stream() - .anyMatch(candidate -> candidate.id().equals(entryId)); - if (!computer.canUseFileSystem(player) || !unlocked || entry == null || entry.structureId().isBlank() - || entry.structureTagId().isBlank() || entry.dimensionId().isBlank() || entry.searchRadius() <= 0) { - sendFile(player, payload, false, "", "unauthorized"); - return; - } - - ResourceLocation dimensionId; - ResourceLocation structureTagId; - try { - dimensionId = ResourceLocation.parse(entry.dimensionId()); - structureTagId = ResourceLocation.parse(entry.structureTagId()); - } catch (RuntimeException exception) { - sendFile(player, payload, false, "", "dimension_unavailable"); - return; - } - ServerLevel targetLevel = player.server.getLevel(net.minecraft.resources.ResourceKey.create(Registries.DIMENSION, dimensionId)); - if (targetLevel == null) { - sendFile(player, payload, false, "", "dimension_unavailable"); - return; - } - - TagKey structures = TagKey.create(Registries.STRUCTURE, structureTagId); - net.minecraft.core.BlockPos origin = computer.getBlockPos(); - var nearest = targetLevel.findNearestMapStructure(structures, origin, entry.searchRadius(), false); - if (nearest == null) { - sendFile(player, payload, false, "", "not_found"); - return; - } - - sendFile(player, payload, true, nearest.getX() + ", " + nearest.getY() + ", " + nearest.getZ(), ""); - } - - private static String encodeBlockle(long day, BlockleAnswers.Answer answer, java.util.List guesses) { - StringBuilder result = new StringBuilder(Long.toString(day)); - boolean solved = false; - for (String guess : guesses) { - String colors = BlockleGame.evaluate(answer.word(), guess); - if (guess.equals(answer.word())) solved = true; - result.append('|').append(guess).append(',').append(colors); - } - if (solved || guesses.size() >= 6) { - result.append('|').append(solved ? "SOLVED" : "FAILED").append('|').append(answer.word()).append('|').append(answer.itemId()); - } else { - result.append('|').append("PLAYING"); - } - return result.toString(); - } - - private static void sendDesktop(ServerPlayer player, ComputerAccessPayload payload, boolean success, String data) { - BlockEntity blockEntity = player.serverLevel().getBlockEntity(payload.pos()); - boolean hasPassword = blockEntity instanceof ComputerBlockEntity computer && computer.hasPassword(); - boolean authenticated = blockEntity instanceof ComputerBlockEntity computer && computer.isAuthenticated(); - resultSender.accept(player, new ComputerAccessResultPayload(payload.pos(), success ? ComputerAccessResultPayload.SUCCESS : ComputerAccessResultPayload.INVALID, - hasPassword, authenticated, payload.action() + "\0\0" + data)); - } - - private static String[] splitFileRequest(String value) { - if (value == null) return null; - int separator = value.indexOf('\0'); - if (separator < 0) return null; - return new String[]{value.substring(0, separator), value.substring(separator + 1)}; - } - - private static void send(ServerPlayer player, ComputerAccessPayload payload, int result) { - BlockEntity blockEntity = player.serverLevel().getBlockEntity(payload.pos()); - boolean hasPassword = blockEntity instanceof ComputerBlockEntity computer && computer.hasPassword(); - boolean authenticated = blockEntity instanceof ComputerBlockEntity computer && computer.isAuthenticated(); - resultSender.accept(player, new ComputerAccessResultPayload(payload.pos(), result, hasPassword, authenticated)); - } - - private static void sendFile(ServerPlayer player, ComputerAccessPayload payload, boolean success, String data, String error) { - BlockEntity blockEntity = player.serverLevel().getBlockEntity(payload.pos()); - boolean hasPassword = blockEntity instanceof ComputerBlockEntity computer && computer.hasPassword(); - boolean authenticated = blockEntity instanceof ComputerBlockEntity computer && computer.isAuthenticated(); - resultSender.accept(player, new ComputerAccessResultPayload(payload.pos(), success ? ComputerAccessResultPayload.SUCCESS : ComputerAccessResultPayload.INVALID, - hasPassword, authenticated, payload.action() + "\0" + error + "\0" + data)); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerAccessPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerAccessPayload.java deleted file mode 100644 index 8f310b86..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerAccessPayload.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record ComputerAccessPayload(BlockPos pos, int action, String value) implements CustomPacketPayload { - public static final int OPEN = 0; - public static final int SETUP = 1; - public static final int LOGIN = 2; - public static final int LOGOUT = 3; - public static final int CHANGE_PASSWORD = 4; - public static final int EJECT = 5; - public static final int CLOSE = 6; - public static final int FILE_LIST = 7; - public static final int FILE_OPEN = 8; - public static final int FILE_CREATE = 9; - public static final int FILE_SAVE = 10; - public static final int DESKTOP_STATE = 11; - public static final int DESKTOP_WALLPAPER = 12; - public static final int FILE_DELETE = 13; - public static final int FILE_MOVE = 14; - public static final int TERMINAL_COMMAND = 15; - public static final int BASILISK_STATE = 16; - public static final int ANTMAN_STATE = 17; - public static final int BLOCKLE_STATE = 18; - public static final int BLOCKLE_GUESS = 19; - public static final int ARCHIVE_STATE = 20; - public static final int LOCATE_STRUCTURE = 21; - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "computer_access")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - BlockPos.STREAM_CODEC, ComputerAccessPayload::pos, - ByteBufCodecs.VAR_INT, ComputerAccessPayload::action, - ByteBufCodecs.stringUtf8(65536), ComputerAccessPayload::value, - ComputerAccessPayload::new - ); - - public ComputerAccessPayload(BlockPos pos, int action) { - this(pos, action, ""); - } - - @Override - public Type type() { - return TYPE; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerAccessResultPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerAccessResultPayload.java deleted file mode 100644 index 10059c69..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerAccessResultPayload.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import com.craisinlord.antarchy.Antarchy; -import net.minecraft.core.BlockPos; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record ComputerAccessResultPayload(BlockPos pos, int result, boolean hasPassword, boolean authenticated, String data) implements CustomPacketPayload { - public static final int SETUP_REQUIRED = 0; - public static final int READY = 1; - public static final int SUCCESS = 2; - public static final int INVALID_PASSWORD = 3; - public static final int BUSY = 4; - public static final int INVALID = 5; - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "computer_access_result")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - BlockPos.STREAM_CODEC, ComputerAccessResultPayload::pos, - ByteBufCodecs.VAR_INT, ComputerAccessResultPayload::result, - ByteBufCodecs.BOOL, ComputerAccessResultPayload::hasPassword, - ByteBufCodecs.BOOL, ComputerAccessResultPayload::authenticated, - ByteBufCodecs.stringUtf8(65536), ComputerAccessResultPayload::data, - ComputerAccessResultPayload::new - ); - - public ComputerAccessResultPayload(BlockPos pos, int result, boolean hasPassword, boolean authenticated) { - this(pos, result, hasPassword, authenticated, ""); - } - - @Override - public Type type() { - return TYPE; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerNetworking.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerNetworking.java deleted file mode 100644 index 05159994..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/ComputerNetworking.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.craisinlord.antarchy.content.network; - -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceLocation; - -import java.util.function.Consumer; - -public final class ComputerNetworking { - private static Consumer sender = payload -> { - }; - - private ComputerNetworking() { - } - - public static void setSender(Consumer sender) { - ComputerNetworking.sender = sender; - } - - public static void open(BlockPos pos) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.OPEN)); - } - - public static void setup(BlockPos pos, String password) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.SETUP, password)); - } - - public static void login(BlockPos pos, String password) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.LOGIN, password)); - } - - public static void logout(BlockPos pos) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.LOGOUT)); - } - - public static void close(BlockPos pos) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.CLOSE)); - } - - public static void changePassword(BlockPos pos, String password) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.CHANGE_PASSWORD, password)); - } - - public static void eject(BlockPos pos, ResourceLocation diskId) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.EJECT, diskId.toString())); - } - - public static void listFiles(BlockPos pos) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.FILE_LIST)); - } - - public static void openFile(BlockPos pos, String path) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.FILE_OPEN, path)); - } - - public static void createFile(BlockPos pos, String path, String contents) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.FILE_CREATE, path + "\0" + contents)); - } - - public static void saveFile(BlockPos pos, String path, String contents) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.FILE_SAVE, path + "\0" + contents)); - } - - public static void deleteFile(BlockPos pos, String path) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.FILE_DELETE, path)); - } - - public static void moveFile(BlockPos pos, String source, String destination) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.FILE_MOVE, source + "\0" + destination)); - } - - public static void terminalCommand(BlockPos pos, String directory, String command) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.TERMINAL_COMMAND, directory + "\0" + command)); - } - - public static void requestDesktopState(BlockPos pos) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.DESKTOP_STATE)); - } - - public static void selectWallpaper(BlockPos pos, ResourceLocation id) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.DESKTOP_WALLPAPER, id.toString())); - } - - public static void requestBasiliskState(BlockPos pos) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.BASILISK_STATE)); - } - - public static void saveBasiliskScore(BlockPos pos, int score) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.BASILISK_STATE, Integer.toString(Math.max(0, score)))); - } - - public static void requestAntmanState(BlockPos pos) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.ANTMAN_STATE)); - } - - public static void saveAntmanScore(BlockPos pos, int score) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.ANTMAN_STATE, Integer.toString(Math.max(0, score)))); - } - - public static void requestBlockleState(BlockPos pos) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.BLOCKLE_STATE)); - } - - public static void submitBlockleGuess(BlockPos pos, String guess) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.BLOCKLE_GUESS, guess)); - } - - public static void locateStructure(BlockPos pos, ResourceLocation entryId) { - sender.accept(new ComputerAccessPayload(pos, ComputerAccessPayload.LOCATE_STRUCTURE, entryId.toString())); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/RoyalGuardianSwordModeCyclePayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/RoyalGuardianSwordModeCyclePayload.java new file mode 100644 index 00000000..f80a4483 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/RoyalGuardianSwordModeCyclePayload.java @@ -0,0 +1,19 @@ +package com.craisinlord.antarchy.content.network; + +import com.craisinlord.antarchy.Antarchy; +import io.netty.buffer.ByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record RoyalGuardianSwordModeCyclePayload() implements CustomPacketPayload { + public static final Type TYPE = new Type<>( + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "royal_guardian_sword_mode_cycle")); + public static final StreamCodec STREAM_CODEC = + StreamCodec.unit(new RoyalGuardianSwordModeCyclePayload()); + + @Override + public Type type() { + return TYPE; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationFieldEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationFieldEntity.java index 610db543..0b5c166a 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationFieldEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/time/TimeDilationFieldEntity.java @@ -36,6 +36,7 @@ public class TimeDilationFieldEntity extends Entity { private int missingAnchorTicks; private boolean visual = true; private boolean chronosphere; + private boolean queenChronosphere; public TimeDilationFieldEntity(EntityType entityType, Level level) { super(entityType, level); @@ -79,19 +80,25 @@ public class TimeDilationFieldEntity extends Entity { this.chronosphere = true; } + public void configureQueenChronosphere(QueenEntity owner) { + this.ownerId = owner.getUUID(); + this.attachTo(owner); + this.queenChronosphere = true; + } + public boolean isChronosphere() { return this.chronosphere; } public boolean affects(Entity entity) { - if (entity instanceof RoyalBlackHoleEntity || this.isOwnedBy(entity) + if (!this.queenChronosphere && entity instanceof RoyalBlackHoleEntity || this.isOwnedBy(entity) || this.anchorId != null && this.anchorId.equals(entity.getUUID())) { return false; } if (this.chronosphere && !(entity instanceof LivingEntity || entity instanceof Projectile || entity instanceof ItemEntity)) { return false; } - if (this.ownerId != null && this.level() instanceof ServerLevel level + if (!this.queenChronosphere && this.ownerId != null && this.level() instanceof ServerLevel level && level.getEntity(this.ownerId) instanceof QueenEntity) { return !entity.getType().is(AntarchyTags.Entities.QUEEN_DOES_NOT_ATTACK); } @@ -202,6 +209,7 @@ public class TimeDilationFieldEntity extends Entity { this.anchorId = tag.hasUUID("AnchorUuid") ? tag.getUUID("AnchorUuid") : null; this.visual = !tag.contains("Visual") || tag.getBoolean("Visual"); this.chronosphere = tag.getBoolean("Chronosphere"); + this.queenChronosphere = tag.getBoolean("QueenChronosphere"); } @Override @@ -218,5 +226,6 @@ public class TimeDilationFieldEntity extends Entity { } tag.putBoolean("Visual", this.visual); tag.putBoolean("Chronosphere", this.chronosphere); + tag.putBoolean("QueenChronosphere", this.queenChronosphere); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/VillagePoolAdditions.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/VillagePoolAdditions.java index 33d00fb9..679d197c 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/VillagePoolAdditions.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/VillagePoolAdditions.java @@ -1,7 +1,6 @@ package com.craisinlord.antarchy.content.worldgen; import com.craisinlord.antarchy.Antarchy; -import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.mixins.PoiTypesAccessor; import com.craisinlord.integrated_api.mixins.structures.StructurePoolAccessor; import com.google.gson.Gson; @@ -59,7 +58,9 @@ public final class VillagePoolAdditions { ResourceKey.create(Registries.POINT_OF_INTEREST_TYPE, poiId)); Map> stateMap = PoiTypesAccessor.antarchy$getTypeByState(); - for (BlockState state : AntarchyObjects.COMPUTER.get().getStateDefinition().getPossibleStates()) { + net.minecraft.world.level.block.Block computer = BuiltInRegistries.BLOCK.get( + ResourceLocation.fromNamespaceAndPath("antos", "computer")); + for (BlockState state : computer.getStateDefinition().getPossibleStates()) { stateMap.put(state, poi); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/KingsTreeGridFeature.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/KingsTreeGridFeature.java index 5d4c7dbd..1dfec542 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/KingsTreeGridFeature.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/KingsTreeGridFeature.java @@ -144,9 +144,8 @@ public final class KingsTreeGridFeature extends Feature callback) { - if (callback.getReturnValueZ() && player.getAdvancements().getOrStartProgress(advancement).isDone()) AntmailEventData.onAdvancement(player, advancement); - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/PoiTypesMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/PoiTypesMixin.java index ef9e77e9..4e212645 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/PoiTypesMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/PoiTypesMixin.java @@ -1,6 +1,5 @@ package com.craisinlord.antarchy.mixins; -import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.Antarchy; import net.minecraft.core.Holder; import net.minecraft.core.registries.BuiltInRegistries; @@ -23,12 +22,14 @@ public abstract class PoiTypesMixin { private static void antarchy$computerPoi(BlockState state, CallbackInfoReturnable>> callback) { try { - if (!state.is(AntarchyObjects.COMPUTER.get())) { + boolean computer = state.is(BuiltInRegistries.BLOCK.get(ResourceLocation.fromNamespaceAndPath("antos", "computer"))); + boolean antTrap = state.is(BuiltInRegistries.BLOCK.get(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "ant_trap"))); + if (!computer && !antTrap) { return; } ResourceKey key = ResourceKey.create( Registries.POINT_OF_INTEREST_TYPE, - ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "computer")); + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, computer ? "computer" : "pest_control")); BuiltInRegistries.POINT_OF_INTEREST_TYPE.getHolder(key) .ifPresent(holder -> callback.setReturnValue(Optional.of(holder))); } catch (IllegalStateException ignored) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/TemporalContractionLivingRendererMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/TemporalContractionLivingRendererMixin.java index cd597a1a..3968ef2f 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/TemporalContractionLivingRendererMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/TemporalContractionLivingRendererMixin.java @@ -6,18 +6,23 @@ import net.minecraft.client.model.EntityModel; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.layers.RenderLayer; import net.minecraft.world.entity.LivingEntity; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(LivingEntityRenderer.class) public abstract class TemporalContractionLivingRendererMixin> { + @Invoker("addLayer") + protected abstract boolean antarchy$addLayer(RenderLayer layer); + @Inject(method = "", at = @At("RETURN")) private void antarchy$addTemporalContractionLayer(EntityRendererProvider.Context context, M model, float shadowRadius, CallbackInfo callbackInfo) { LivingEntityRenderer renderer = (LivingEntityRenderer) (Object) this; - renderer.addLayer(new TemporalContractionAfterimageLayer<>(renderer)); + this.antarchy$addLayer(new TemporalContractionAfterimageLayer<>(renderer)); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesCandyCaneHookMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesCandyCaneHookMixin.java index e809f64e..e8168256 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesCandyCaneHookMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesCandyCaneHookMixin.java @@ -8,6 +8,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArg; @@ -15,6 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** Handles Alex's Caves' manually-launched Candy Cane Hook. */ @Mixin(targets = "com.github.alexmodguy.alexscaves.server.entity.item.CandyCaneHookEntity") +@Pseudo public abstract class AlexsCavesCandyCaneHookMixin { private boolean antarchy$launchAdjusted; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesDepthChargeMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesDepthChargeMixin.java index 410b00fd..8f0239dc 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesDepthChargeMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesDepthChargeMixin.java @@ -5,11 +5,13 @@ import com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisUndersideManag import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.projectile.Projectile; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; /** Corrects Depth Charge's custom tick, which bypasses ThrowableProjectile.tick. */ @Mixin(targets = "com.github.alexmodguy.alexscaves.server.entity.item.DepthChargeEntity") +@Pseudo public abstract class AlexsCavesDepthChargeMixin { @ModifyArg( method = "tick", diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesTephraMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesTephraMixin.java index 374bb783..0f96c5d6 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesTephraMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesTephraMixin.java @@ -5,11 +5,13 @@ import com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisUndersideManag import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.projectile.Projectile; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; /** Corrects Tephra's explicit -0.1 Y gravity adjustment. */ @Mixin(targets = "com.github.alexmodguy.alexscaves.server.entity.item.TephraEntity") +@Pseudo public abstract class AlexsCavesTephraMixin { @ModifyArg( method = "tick", diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesWaterBoltMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesWaterBoltMixin.java index 329169ae..7bbcccd3 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesWaterBoltMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/alexscaves/AlexsCavesWaterBoltMixin.java @@ -5,11 +5,13 @@ import com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisUndersideManag import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.projectile.Projectile; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; /** Corrects Water Bolt's explicit -0.07 Y gravity adjustment. */ @Mixin(targets = "com.github.alexmodguy.alexscaves.server.entity.item.WaterBoltEntity") +@Pseudo public abstract class AlexsCavesWaterBoltMixin { @ModifyArg( method = "tick", diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/ars_nouveau/ArsNouveauProjectileGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/ars_nouveau/ArsNouveauProjectileGravityMixin.java index d938dd91..fa90dabb 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/ars_nouveau/ArsNouveauProjectileGravityMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/ars_nouveau/ArsNouveauProjectileGravityMixin.java @@ -7,12 +7,14 @@ import com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisUndersideManag import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.projectile.Projectile; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** Handles Ars Nouveau's explicit tickNextPosition gravity adjustment. */ @Mixin(targets = "com.hollingsworth.arsnouveau.common.entity.EntityProjectileSpell") +@Pseudo public abstract class ArsNouveauProjectileGravityMixin { @Inject(method = "tick", at = @At("HEAD")) private void antarchy$prepareArsProjectile(CallbackInfo ci) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/irons_spellbooks/IronsSpellbooksProjectileGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/irons_spellbooks/IronsSpellbooksProjectileGravityMixin.java index 2abf065f..d44dd439 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/irons_spellbooks/IronsSpellbooksProjectileGravityMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/irons_spellbooks/IronsSpellbooksProjectileGravityMixin.java @@ -9,6 +9,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -16,6 +17,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** Handles Iron's Spellbooks' custom travel() gravity path. */ @Mixin(targets = "io.redspace.ironsspellbooks.entity.spells.AbstractMagicProjectile") +@Pseudo public abstract class IronsSpellbooksProjectileGravityMixin { @Shadow public abstract float getSpeed(); @Shadow protected abstract double getDefaultGravity(); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/scguns/ScgunsArrowGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/scguns/ScgunsArrowGravityMixin.java index fbe65aef..94ec1463 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/scguns/ScgunsArrowGravityMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/scguns/ScgunsArrowGravityMixin.java @@ -4,12 +4,14 @@ import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; import com.craisinlord.antarchy.content.worldgen.thoraxis.ThoraxisUndersideManager; import net.minecraft.world.entity.projectile.AbstractArrow; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** Corrects Scorched Guns arrow-derived projectiles with custom tick gravity. */ @Mixin(targets = "top.ribs.scguns.entity.projectile.BrassBoltEntity") +@Pseudo public abstract class ScgunsArrowGravityMixin { @Inject(method = "tick", at = @At("TAIL")) private void antarchy$invertScgunsArrowGravity(CallbackInfo ci) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/scguns/ScgunsProjectileEntityGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/scguns/ScgunsProjectileEntityGravityMixin.java index f76ed2a2..f5e1f051 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/scguns/ScgunsProjectileEntityGravityMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/compat/scguns/ScgunsProjectileEntityGravityMixin.java @@ -10,6 +10,7 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -25,6 +26,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; "top.ribs.scguns.entity.projectile.OsborneSlugProjectileEntity", "top.ribs.scguns.entity.projectile.ShotballProjectileEntity" }) +@Pseudo public abstract class ScgunsProjectileEntityGravityMixin { @Shadow @Nullable protected LivingEntity shooter; @Shadow protected double modifiedGravity; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/time/EntityMoveTimeDilationMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/time/EntityMoveTimeDilationMixin.java index 4db808f1..af8ac9f0 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/time/EntityMoveTimeDilationMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/time/EntityMoveTimeDilationMixin.java @@ -5,6 +5,7 @@ import com.craisinlord.antarchy.content.time.TimeDilationEntityAccess; import com.craisinlord.antarchy.content.time.TimeDilationMath; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.MoverType; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -31,6 +32,9 @@ public abstract class EntityMoveTimeDilationMixin { @ModifyVariable(method = "move", at = @At("HEAD"), argsOnly = true, ordinal = 0) private Vec3 antarchy$scaleTimeDilatedMovement(Vec3 movement) { Entity entity = (Entity) (Object) this; + if (entity instanceof Player && !entity.level().isClientSide) { + return movement; + } double rate = TimeDilationApi.getRate(entity); if (Math.abs(rate - TimeDilationMath.NORMAL_RATE) < 0.001D) { return movement; 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 0bcd2a72..ef3ea3f1 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 @@ -57,7 +57,6 @@ "ServerPlayerRoyalBoundaryMixin", "ProjectileRoyalBoundaryMixin", "RoyalBoundaryOwnerCleanupMixin", - "PlayerAdvancementsMixin", "SpongeAntiwaterMixin", "SquidzookaEnchantMixin", "SquidzookaMultishotMixin", diff --git a/common-1.21.1/src/main/resources/assets/antarchy/animations/computer.animation.json b/common-1.21.1/src/main/resources/assets/antarchy/animations/computer.animation.json deleted file mode 100644 index 1ca9b1f3..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/animations/computer.animation.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "format_version": "1.8.0", - "animations": { - "on_state": { - "loop": true, - "bones": { - "on": {"scale": {"vector": [1, 1, 1]}}, - "white_flash": {"scale": {"vector": [0, 0, 0]}}, - "off": {"scale": {"vector": [0, 0, 0]}}, - "computer_on": {"scale": {"vector": [1, 1, 1]}} - } - }, - "off_state": { - "loop": true, - "bones": { - "on": {"scale": {"vector": [0, 0, 0]}}, - "white_flash": {"scale": {"vector": [0, 0, 0]}}, - "off": {"scale": {"vector": [1, 1, 1]}}, - "computer_on": {"scale": {"vector": [0, 0, 0]}} - } - }, - "turn_on": { - "loop": "hold_on_last_frame", - "animation_length": 0.4583, - "bones": { - "on": {"scale": {"0.0": {"vector": [1, 0, 0]}, "0.125": {"vector": [1, 0, 0]}, "0.2917": {"vector": [1, 1, 1], "easing": "easeInOutCubic"}}}, - "white_flash": {"scale": {"0.0": {"vector": [1, 0, 0]}, "0.0417": {"vector": [1, 0.2, 0.2]}, "0.2083": {"vector": [1, 1, 1], "easing": "easeInOutQuint"}}}, - "off": {"scale": {"0.0": {"vector": [1, 1, 1]}}}, - "computer_on": {"scale": {"0.0": {"vector": [0, 0, 0]}, "0.0417": {"vector": [1, 1, 1]}}} - } - }, - "turn_off": { - "loop": "hold_on_last_frame", - "animation_length": 0.4583, - "bones": { - "on": {"scale": {"0.0": {"vector": [1, 1, 1]}, "0.25": {"vector": [1, 0, 1], "easing": "easeInOutQuint"}}}, - "white_flash": {"scale": {"0.0": {"vector": [1, 1, 0]}, "0.125": {"vector": [1, 1, 0]}, "0.375": {"vector": [1, 0, 0], "easing": "easeInOutQuart"}}}, - "off": {"scale": {"0.0": {"vector": [0, 0, 0]}, "0.0417": {"vector": [1, 1, 1]}}}, - "computer_on": {"scale": {"0.0": {"vector": [1, 1, 1]}, "0.25": {"vector": [1, 1, 1]}, "0.2917": {"vector": [0, 0, 0]}}} - } - } - } -} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/blockstates/ant_trap.json b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/ant_trap.json new file mode 100644 index 00000000..48f6872d --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/ant_trap.json @@ -0,0 +1 @@ +{"variants":{"":{"model":"antarchy:block/ant_trap"}}} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/blockstates/computer.json b/common-1.21.1/src/main/resources/assets/antarchy/blockstates/computer.json deleted file mode 100644 index 0cce1c7f..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/blockstates/computer.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "multipart": [ - { - "apply": { - "model": "antarchy:block/computer" - } - } - ] -} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/computer.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/computer.geo.json deleted file mode 100644 index 94959b9d..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/geo/computer.geo.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "format_version": "1.12.0", - "minecraft:geometry": [ - { - "description": { - "identifier": "geometry.unknown", - "texture_width": 128, - "texture_height": 128, - "visible_bounds_width": 2, - "visible_bounds_height": 2.5, - "visible_bounds_offset": [0, 0.75, 0] - }, - "bones": [ - { - "name": "computer", - "pivot": [-5, 3, 1], - "cubes": [ - { - "origin": [-7, 0, -7], - "size": [14, 4, 14], - "uv": { - "north": {"uv": [14, 14], "uv_size": [14, 4]}, - "east": {"uv": [0, 14], "uv_size": [14, 4]}, - "south": {"uv": [42, 14], "uv_size": [14, 4]}, - "west": {"uv": [28, 14], "uv_size": [14, 4]}, - "up": {"uv": [14, 0], "uv_size": [14, 14]}, - "down": {"uv": [28, 14], "uv_size": [14, -14]} - } - } - ] - }, - { - "name": "computer_on", - "parent": "computer", - "pivot": [0, -1, 0.95], - "cubes": [ - { - "origin": [-6, 2, -7.05], - "size": [3, 1, 0], - "uv": { - "north": {"uv": [97, 14], "uv_size": [3, 1]}, - "east": {"uv": [83, 14], "uv_size": [0, 1]}, - "south": {"uv": [125, 14], "uv_size": [3, 1]}, - "west": {"uv": [111, 14], "uv_size": [0, 1]}, - "up": {"uv": [97, 0], "uv_size": [3, 0]}, - "down": {"uv": [111, 0], "uv_size": [3, 0]} - } - } - ] - }, - { - "name": "cables", - "parent": "computer", - "pivot": [-5, 3, 1], - "cubes": [ - { - "origin": [-2, 1, 5], - "size": [0, 8, 3], - "uv": { - "north": {"uv": [13, 66], "uv_size": [0, 8]}, - "east": {"uv": [0, 66], "uv_size": [3, 8]}, - "south": {"uv": [26, 66], "uv_size": [0, 8]}, - "west": {"uv": [13, 66], "uv_size": [13, 8]}, - "up": {"uv": [13, 53], "uv_size": [0, 13]}, - "down": {"uv": [13, 66], "uv_size": [0, -13]} - } - }, - { - "origin": [2, 1, 5], - "size": [0, 8, 3], - "uv": { - "north": {"uv": [45, 51], "uv_size": [0, 8]}, - "east": {"uv": [32, 51], "uv_size": [3, 8]}, - "south": {"uv": [58, 51], "uv_size": [0, 8]}, - "west": {"uv": [45, 51], "uv_size": [13, 8]}, - "up": {"uv": [45, 38], "uv_size": [0, 13]}, - "down": {"uv": [45, 51], "uv_size": [0, -13]} - } - } - ] - }, - { - "name": "monitor", - "parent": "computer", - "pivot": [0, 3, 0], - "cubes": [ - { - "origin": [-6, 4, -6], - "size": [12, 11, 4], - "uv": { - "north": {"uv": [4, 42], "uv_size": [12, 11]}, - "east": {"uv": [0, 42], "uv_size": [4, 11]}, - "south": {"uv": [20, 42], "uv_size": [12, 11]}, - "west": {"uv": [16, 42], "uv_size": [4, 11]}, - "up": {"uv": [4, 38], "uv_size": [12, 4]} - } - }, - { - "origin": [-5, 4, -5], - "size": [10, 10, 10], - "uv": { - "north": {"uv": [10, 28], "uv_size": [10, 10]}, - "east": {"uv": [0, 28], "uv_size": [10, 10]}, - "south": {"uv": [30, 28], "uv_size": [10, 10]}, - "west": {"uv": [20, 28], "uv_size": [10, 10]}, - "up": {"uv": [10, 18], "uv_size": [10, 10]}, - "down": {"uv": [20, 28], "uv_size": [10, -10]} - } - } - ] - }, - { - "name": "screens", - "parent": "monitor", - "pivot": [0.5, 2.9, 0.5] - }, - { - "name": "on", - "parent": "screens", - "pivot": [0, 9.4, -5.625], - "cubes": [ - { - "origin": [-5.5, 3.9, -5.6], - "size": [11, 11, 0], - "uv": { - "north": {"uv": [77, 33], "uv_size": [17, 17]}, - "east": {"uv": [40, 18], "uv_size": [0, 11]}, - "south": {"uv": [51, 18], "uv_size": [11, 11]}, - "west": {"uv": [51, 18], "uv_size": [0, 11]}, - "up": {"uv": [40, 18], "uv_size": [11, 0]}, - "down": {"uv": [51, 18], "uv_size": [11, 0]} - } - }, - { - "origin": [-5.5, 3.9, -5.65], - "size": [11, 11, 0], - "uv": { - "north": {"uv": [98, 31.5], "uv_size": [17, 17]}, - "east": {"uv": [40, 18], "uv_size": [0, 11]}, - "south": {"uv": [51, 18], "uv_size": [11, 11]}, - "west": {"uv": [51, 18], "uv_size": [0, 11]}, - "up": {"uv": [40, 18], "uv_size": [11, 0]}, - "down": {"uv": [51, 18], "uv_size": [11, 0]} - } - } - ] - }, - { - "name": "off", - "parent": "screens", - "pivot": [0, 9.4, -5.4], - "cubes": [ - { - "origin": [-5.5, 3.9, -5.4], - "size": [11, 11, 0], - "uv": { - "north": {"uv": [77, 50], "uv_size": [17, 17]}, - "east": {"uv": [58, 29], "uv_size": [0, 11]}, - "south": {"uv": [62, 46], "uv_size": [11, 11]}, - "west": {"uv": [69, 29], "uv_size": [0, 11]}, - "up": {"uv": [58, 29], "uv_size": [11, 0]}, - "down": {"uv": [69, 29], "uv_size": [11, 0]} - } - } - ] - }, - { - "name": "white_flash", - "parent": "screens", - "pivot": [0, 9.4, -5.55], - "cubes": [ - { - "origin": [-5.5, 3.9, -5.55], - "size": [11, 11, 0], - "uv": { - "north": {"uv": [56, 0], "uv_size": [11, 11]}, - "east": {"uv": [56, 0], "uv_size": [0, 11]}, - "south": {"uv": [67, 0], "uv_size": [11, 11]}, - "west": {"uv": [67, 0], "uv_size": [0, 11]}, - "up": {"uv": [56, 0], "uv_size": [11, 0]}, - "down": {"uv": [67, 0], "uv_size": [11, 0]} - } - } - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/lang/de_de.json b/common-1.21.1/src/main/resources/assets/antarchy/lang/de_de.json index 9eecf3e6..68d01114 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/lang/de_de.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/lang/de_de.json @@ -963,5 +963,8 @@ "advancements.antarchy.beetle_buddies.title": "Käferkumpel", "advancements.antarchy.beetle_buddies.description": "Zähme einen Herkuleskäfer.", "advancements.antarchy.herculean_task.title": "Herkulesaufgabe", - "advancements.antarchy.herculean_task.description": "Erschlage einen Herkuleskäfer." + "advancements.antarchy.herculean_task.description": "Erschlage einen Herkuleskäfer.", + "subtitles.antarchy.hoverboard_mount": "Hoverboard startet", + "subtitles.antarchy.hoverboard_dismount": "Hoverboard stoppt", + "subtitles.antarchy.hoverboard_idle": "Hoverboard summt" } 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 903dc8d7..7d40bdd8 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 @@ -883,6 +883,10 @@ "advancements.antarchy.water_cannon_craft.description": "Obtain a Water Cannon.", "advancements.antarchy.kill_toreterror.title": "More like Tore-Terrible Aim!", "advancements.antarchy.kill_toreterror.description": "Defeat the Toreterror.", + "advancements.antarchy.down_with_the_king.title": "Down with the King", + "advancements.antarchy.down_with_the_king.description": "Defeat the King.", + "advancements.antarchy.down_with_the_queen.title": "Down with the Queen", + "advancements.antarchy.down_with_the_queen.description": "Defeat the Queen.", "advancements.antarchy.challenge_games.title": "Challenge Games!", "advancements.antarchy.challenge_games.description": "Enter the Ruined Arena.", "advancements.antarchy.bugged_out.title": "Bugged Out", @@ -1441,7 +1445,7 @@ ,"decree.antarchy.kneel": "KNEEL" ,"decree.antarchy.kneel.subtitle": "Crouch within five seconds." ,"decree.antarchy.close_quarters": "CLOSE QUARTERS" - ,"decree.antarchy.close_quarters.subtitle": "Enter the royal circle. Projectiles are forbidden." + ,"decree.antarchy.close_quarters.subtitle": "Reach the King's 16-block circle within 6 seconds. Projectiles are forbidden." ,"decree.antarchy.violated": "DECREE VIOLATED" ,"decree.antarchy.violated.subtitle": "Your hearts are halved for 30. Face the King's judgment." ,"effect.antarchy.royal_vitality_penalty": "Royal Vitality Diminished" @@ -1462,12 +1466,10 @@ ,"menu.antarchy.royal_judgment": "Royal Judgment" ,"enchantment.antarchy.feather_rising": "Feather Rising" ,"enchantment.antarchy.chronosphere": "Chronosphere" - ,"block.antarchy.computer": "Computer" ,"entity.minecraft.villager.antarchy.computer_scientist": "Game Developer" - ,"item.antarchy.computer": "Computer" - ,"item.antarchy.floppy_disk": "Floppy Disk" - ,"item.antarchy.floppy_disk.tooltip": "Put in a computer to find out more" - ,"screen.antarchy.computer": "ANTINTOSH OS" + ,"block.antarchy.ant_trap": "Ant Trap" + ,"item.antarchy.bug_spray": "Bug Spray" + ,"entity.minecraft.villager.antarchy.pest_control": "Pest Control" ,"guide.antarchy.category.general": "GENERAL" ,"guide.antarchy.category.elythia": "ELYTHIA" ,"guide.antarchy.category.thoraxis": "THORAXIS" @@ -1545,21 +1547,13 @@ ,"guide.antarchy.entry.queen.title": "Queen" ,"guide.antarchy.entry.queen.subtitle": "Thoraxis royal entity record" ,"guide.antarchy.entry.queen.description": "Follow a Queen Havoc Trail through Thoraxis's underside to its chamber; the Queen appears when you approach." - ,"screen.antarchy.computer.first_use.title": "INITIAL PASSWORD SETUP" - ,"screen.antarchy.computer.first_use.prompt": "CREATE A PASSWORD TO CONTINUE" - ,"screen.antarchy.computer.first_use.confirm": "CONFIRM PASSWORD" - ,"screen.antarchy.computer.busy": "COMPUTER IN USE" - ,"screen.antarchy.computer.eject_denied": "ACCESS DENIED: SETTINGS REQUIRED" - ,"screen.antarchy.computer.ejected": "DISK EJECTED" - ,"antintosh.antarchy.desktop.archive": "ARCHIVE" - ,"antintosh.antarchy.desktop.settings": "SETTINGS" - ,"antintosh.antarchy.desktop.terminal": "TERMINAL" - ,"antintosh.antarchy.desktop.antpaint": "ANTPAINT" - ,"antintosh.antarchy.desktop.antmail": "ANTMAIL" - ,"antintosh.antarchy.desktop.text_editor": "TEXT EDITOR" - ,"antintosh.antarchy.antmail.compose": "COMPOSE MESSAGE" - ,"antintosh.antarchy.antmail.attach_text": "ATTACH TEXT FILE" - ,"antintosh.antarchy.antmail.attach_image": "ATTACH ANTPAINT IMAGE" - ,"antintosh.antarchy.antmail.save_attachment": "SAVE ATTACHMENT" - ,"antintosh.antarchy.antmail.address": "COMPUTER ADDRESS" + ,"guide.antarchy.entry.prince.title": "Prince" + ,"guide.antarchy.entry.prince.subtitle": "Royal mount record" + ,"guide.antarchy.entry.prince.description": "Prince Eggs hatch into small Princes that grow when fed golden items; they can be tamed, saddled to fly, fire elemental bolts, and command nearby hostile mobs." + ,"guide.antarchy.entry.princess.title": "Princess" + ,"guide.antarchy.entry.princess.subtitle": "Royal mount record" + ,"guide.antarchy.entry.princess.description": "Princess Eggs hatch into small Princesses that grow when fed golden items; they can be tamed, saddled to fly, fire elemental bolts, and create time-dilation fields around enemies." + ,"subtitles.antarchy.hoverboard_mount": "Hoverboard starts" + ,"subtitles.antarchy.hoverboard_dismount": "Hoverboard stops" + ,"subtitles.antarchy.hoverboard_idle": "Hoverboard hums" } diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/block/ant_trap.json b/common-1.21.1/src/main/resources/assets/antarchy/models/block/ant_trap.json new file mode 100644 index 00000000..c98a1c83 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/block/ant_trap.json @@ -0,0 +1,77 @@ +{ + "format_version": "1.9.0", + "credit": "Made with Blockbench", + "texture_size": [32, 32], + "textures": { + "0": "antarchy:block/ant_trap", + "particle": "antarchy:block/ant_trap" + }, + "elements": [ + { + "from": [3, 0, 3], + "to": [13, 1, 13], + "faces": { + "north": {"uv": [9, 6, 14, 6.5], "texture": "#0"}, + "east": {"uv": [9, 6.5, 14, 7], "texture": "#0"}, + "south": {"uv": [9, 7, 14, 7.5], "texture": "#0"}, + "west": {"uv": [9, 7.5, 14, 8], "texture": "#0"}, + "up": {"uv": [5, 5, 0, 0], "texture": "#0"}, + "down": {"uv": [5, 5, 0, 10], "texture": "#0"} + } + }, + { + "from": [4, 1, 4], + "to": [12, 5, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 1, 0]}, + "faces": { + "north": {"uv": [5, 8, 9, 10], "texture": "#0"}, + "east": {"uv": [9, 0, 13, 2], "texture": "#0"}, + "south": {"uv": [9, 2, 13, 4], "texture": "#0"}, + "west": {"uv": [9, 4, 13, 6], "texture": "#0"}, + "up": {"uv": [9, 4, 5, 0], "texture": "#0"}, + "down": {"uv": [9, 4, 5, 8], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "translation": [0, 4, 0], + "scale": [0.5, 0.5, 0.5] + }, + "thirdperson_lefthand": { + "translation": [0, 4, 0], + "scale": [0.5, 0.5, 0.5] + }, + "firstperson_righthand": { + "translation": [0, 6, 0], + "scale": [0.8, 0.8, 0.8] + }, + "firstperson_lefthand": { + "translation": [0, 6, 0], + "scale": [0.8, 0.8, 0.8] + }, + "ground": { + "translation": [0, 1.5, 0], + "scale": [0.4, 0.4, 0.4] + }, + "gui": { + "rotation": [35, -130, 0], + "translation": [0, 3.5, 0] + }, + "head": { + "translation": [0, 14.5, 0] + }, + "fixed": { + "translation": [0, 4, 0] + } + }, + "groups": [ + { + "name": "anttrap", + "origin": [0, 0, 0], + "scope": 0, + "color": 0, + "children": [0, 1] + } + ] +} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/block/computer.json b/common-1.21.1/src/main/resources/assets/antarchy/models/block/computer.json deleted file mode 100644 index 90f14fc1..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/block/computer.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "minecraft:block/cube_all", - "textures": { - "all": "antarchy:block/computer/computer" - } -} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/block/verdant_nyxium.json b/common-1.21.1/src/main/resources/assets/antarchy/models/block/verdant_nyxium.json index 6afbf9dc..09e697b8 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/block/verdant_nyxium.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/block/verdant_nyxium.json @@ -1,7 +1,7 @@ { "parent": "minecraft:block/cube_bottom_top", "textures": { - "bottom": "antarchy:block/typhonite", + "bottom": "antarchy:block/typhonite/typhonite", "side": "antarchy:block/verdant_nyxium", "top": "antarchy:block/verdant_nyxium_top" } diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/item/ant_trap.json b/common-1.21.1/src/main/resources/assets/antarchy/models/item/ant_trap.json new file mode 100644 index 00000000..c6bf80c0 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/item/ant_trap.json @@ -0,0 +1 @@ +{"parent":"antarchy:block/ant_trap"} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/item/bug_spray.json b/common-1.21.1/src/main/resources/assets/antarchy/models/item/bug_spray.json new file mode 100644 index 00000000..2c57a55e --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/item/bug_spray.json @@ -0,0 +1 @@ +{"parent":"minecraft:item/generated","textures":{"layer0":"antarchy:item/bug_spray"},"overrides":[{"predicate":{"minecraft:using_item":1},"model":"antarchy:item/bug_spray_spraying"}]} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/item/bug_spray_spraying.json b/common-1.21.1/src/main/resources/assets/antarchy/models/item/bug_spray_spraying.json new file mode 100644 index 00000000..54c1e225 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/item/bug_spray_spraying.json @@ -0,0 +1 @@ +{"parent":"minecraft:item/generated","textures":{"layer0":"antarchy:item/bug_spray_spraying"}} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/item/computer.json b/common-1.21.1/src/main/resources/assets/antarchy/models/item/computer.json deleted file mode 100644 index 7b1a8ed5..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/item/computer.json +++ /dev/null @@ -1,232 +0,0 @@ -{ - "format_version": "1.21.11", - "credit": "Made with Blockbench", - "texture_size": [128, 128], - "textures": { - "0": "antarchy:item/computer", - "particle": "antarchy:item/computer" - }, - "elements": [ - { - "from": [1, 0, 1], - "to": [15, 4, 15], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -1, 9]}, - "faces": { - "north": {"uv": [1.75, 1.75, 3.5, 2.25], "texture": "#0"}, - "east": {"uv": [0, 1.75, 1.75, 2.25], "texture": "#0"}, - "south": {"uv": [5.25, 1.75, 7, 2.25], "texture": "#0"}, - "west": {"uv": [3.5, 1.75, 5.25, 2.25], "texture": "#0"}, - "up": {"uv": [3.5, 1.75, 1.75, 0], "texture": "#0"}, - "down": {"uv": [5.25, 0, 3.5, 1.75], "texture": "#0"} - } - }, - { - "from": [11, 2, 0.95], - "to": [14, 3, 0.95], - "rotation": {"angle": 0, "axis": "y", "origin": [8, -1, 8.95]}, - "faces": { - "north": {"uv": [12.125, 1.75, 12.5, 1.875], "texture": "#0"}, - "east": {"uv": [10.375, 1.75, 10.375, 1.875], "texture": "#0"}, - "south": {"uv": [15.625, 1.75, 16, 1.875], "texture": "#0"}, - "west": {"uv": [13.875, 1.75, 13.875, 1.875], "texture": "#0"}, - "up": {"uv": [12.5, 0, 12.125, 0], "texture": "#0"}, - "down": {"uv": [14.25, 0, 13.875, 0], "texture": "#0"} - } - }, - { - "from": [10, 1, 13], - "to": [10, 9, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [13, 3, 9]}, - "faces": { - "north": {"uv": [1.625, 8.25, 1.625, 9.25], "texture": "#0"}, - "east": {"uv": [0, 8.25, 0.375, 9.25], "texture": "#0"}, - "south": {"uv": [3.25, 8.25, 3.25, 9.25], "texture": "#0"}, - "west": {"uv": [1.625, 8.25, 3.25, 9.25], "texture": "#0"}, - "up": {"uv": [1.625, 8.25, 1.625, 6.625], "texture": "#0"}, - "down": {"uv": [1.625, 6.625, 1.625, 8.25], "texture": "#0"} - } - }, - { - "from": [6, 1, 13], - "to": [6, 9, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [9, 3, 9]}, - "faces": { - "north": {"uv": [5.625, 6.375, 5.625, 7.375], "texture": "#0"}, - "east": {"uv": [4, 6.375, 4.375, 7.375], "texture": "#0"}, - "south": {"uv": [7.25, 6.375, 7.25, 7.375], "texture": "#0"}, - "west": {"uv": [5.625, 6.375, 7.25, 7.375], "texture": "#0"}, - "up": {"uv": [5.625, 6.375, 5.625, 4.75], "texture": "#0"}, - "down": {"uv": [5.625, 4.75, 5.625, 6.375], "texture": "#0"} - } - }, - { - "from": [2, 4, 2], - "to": [14, 15, 6], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 3, 8]}, - "faces": { - "north": {"uv": [0.5, 5.25, 2, 6.625], "texture": "#0"}, - "east": {"uv": [0, 5.25, 0.5, 6.625], "texture": "#0"}, - "south": {"uv": [2.5, 5.25, 4, 6.625], "texture": "#0"}, - "west": {"uv": [2, 5.25, 2.5, 6.625], "texture": "#0"}, - "up": {"uv": [2, 5.25, 0.5, 4.75], "texture": "#0"} - } - }, - { - "from": [3, 4, 3], - "to": [13, 14, 13], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 3, 9]}, - "faces": { - "north": {"uv": [1.25, 3.5, 2.5, 4.75], "texture": "#0"}, - "east": {"uv": [0, 3.5, 1.25, 4.75], "texture": "#0"}, - "south": {"uv": [3.75, 3.5, 5, 4.75], "texture": "#0"}, - "west": {"uv": [2.5, 3.5, 3.75, 4.75], "texture": "#0"}, - "up": {"uv": [2.5, 3.5, 1.25, 2.25], "texture": "#0"}, - "down": {"uv": [3.75, 2.25, 2.5, 3.5], "texture": "#0"} - } - }, - { - "from": [2.5, 3.9, 2.4], - "to": [13.5, 14.9, 2.4], - "rotation": {"angle": 0, "axis": "y", "origin": [7.5, 2.9, 8.4]}, - "faces": { - "north": {"uv": [9.625, 4.125, 11.75, 6.25], "texture": "#0"}, - "east": {"uv": [5, 2.25, 5, 3.625], "texture": "#0"}, - "south": {"uv": [6.375, 2.25, 7.75, 3.625], "texture": "#0"}, - "west": {"uv": [6.375, 2.25, 6.375, 3.625], "texture": "#0"}, - "up": {"uv": [6.375, 2.25, 5, 2.25], "texture": "#0"}, - "down": {"uv": [7.75, 2.25, 6.375, 2.25], "texture": "#0"} - } - }, - { - "from": [2.5, 3.9, 2.35], - "to": [13.5, 14.9, 2.35], - "rotation": {"angle": 0, "axis": "y", "origin": [7.5, 2.9, 8.35]}, - "faces": { - "north": {"uv": [12.25, 3.9375, 14.375, 6.0625], "texture": "#0"}, - "east": {"uv": [5, 2.25, 5, 3.625], "texture": "#0"}, - "south": {"uv": [6.375, 2.25, 7.75, 3.625], "texture": "#0"}, - "west": {"uv": [6.375, 2.25, 6.375, 3.625], "texture": "#0"}, - "up": {"uv": [6.375, 2.25, 5, 2.25], "texture": "#0"}, - "down": {"uv": [7.75, 2.25, 6.375, 2.25], "texture": "#0"} - } - }, - { - "from": [2.5, 3.9, 2.6], - "to": [13.5, 14.9, 2.6], - "rotation": {"angle": 0, "axis": "y", "origin": [7.5, 2.9, 8.6]}, - "faces": { - "north": {"uv": [9.625, 6.25, 11.75, 8.375], "texture": "#0"}, - "east": {"uv": [7.25, 3.625, 7.25, 5], "texture": "#0"}, - "south": {"uv": [7.75, 5.75, 9.125, 7.125], "texture": "#0"}, - "west": {"uv": [8.625, 3.625, 8.625, 5], "texture": "#0"}, - "up": {"uv": [8.625, 3.625, 7.25, 3.625], "texture": "#0"}, - "down": {"uv": [10, 3.625, 8.625, 3.625], "texture": "#0"} - } - }, - { - "from": [2.5, 3.9, 2.45], - "to": [13.5, 14.9, 2.45], - "rotation": {"angle": 0, "axis": "y", "origin": [7.5, 2.9, 8.45]}, - "faces": { - "north": {"uv": [7, 0, 8.375, 1.375], "texture": "#0"}, - "east": {"uv": [7, 0, 7, 1.375], "texture": "#0"}, - "south": {"uv": [8.375, 0, 9.75, 1.375], "texture": "#0"}, - "west": {"uv": [8.375, 0, 8.375, 1.375], "texture": "#0"}, - "up": {"uv": [8.375, 0, 7, 0], "texture": "#0"}, - "down": {"uv": [9.75, 0, 8.375, 0], "texture": "#0"} - } - } - ], - "groups": [ - { - "name": "computer", - "origin": [13, 3, 9], - "scope": 0, - "color": 0, - "children": [ - 0, - { - "name": "computer_on", - "origin": [8, -1, 8.95], - "scope": 0, - "color": 0, - "children": [1] - }, - { - "name": "cables", - "origin": [13, 3, 9], - "scope": 0, - "color": 0, - "children": [2, 3] - }, - { - "name": "monitor", - "origin": [8, 3, 8], - "scope": 0, - "color": 0, - "children": [ - 4, - 5, - { - "name": "screens", - "origin": [7.5, 2.9, 8.5], - "scope": 0, - "color": 0, - "children": [ - { - "name": "on", - "origin": [8, 9.4, 2.375], - "scope": 0, - "color": 0, - "children": [6, 7] - }, - { - "name": "off", - "origin": [8, 9.4, 2.6], - "scope": 0, - "color": 0, - "children": [8] - }, - { - "name": "white_flash", - "origin": [8, 9.4, 2.45], - "scope": 0, - "color": 0, - "children": [9] - } - ] - } - ] - } - ] - } - ], - "display": { - "thirdperson_righthand": { - "rotation": [75, 45, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "thirdperson_lefthand": { - "rotation": [75, 45, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 45, 0], - "scale": [0.4, 0.4, 0.4] - }, - "firstperson_lefthand": { - "rotation": [0, 225, 0], - "scale": [0.4, 0.4, 0.4] - }, - "gui": { - "rotation": [30, 225, 0], - "scale": [0.625, 0.625, 0.625] - }, - "fixed": { - "rotation": [0, 180, 0], - "scale": [0.5, 0.5, 0.5] - } - } -} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk.json b/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk.json deleted file mode 100644 index 20b0be13..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "parent": "minecraft:item/generated", - "textures": { - "layer0": "antarchy:item/floppy_disk/floppy_disk" - }, - "overrides": [ - { - "predicate": {"antarchy:disk_category": 1.0}, - "model": "antarchy:item/floppy_disk/elythia_floppy_disk" - }, - { - "predicate": {"antarchy:disk_category": 2.0}, - "model": "antarchy:item/floppy_disk/cavaryn_floppy_disk" - }, - { - "predicate": {"antarchy:disk_category": 3.0}, - "model": "antarchy:item/floppy_disk/thoraxis_floppy_disk" - } - ] -} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk/cavaryn_floppy_disk.json b/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk/cavaryn_floppy_disk.json deleted file mode 100644 index 3360a214..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk/cavaryn_floppy_disk.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "minecraft:item/generated", - "textures": { - "layer0": "antarchy:item/floppy_disk/cavaryn_floppy_disk" - } -} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk/elythia_floppy_disk.json b/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk/elythia_floppy_disk.json deleted file mode 100644 index fbe4e65b..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk/elythia_floppy_disk.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "minecraft:item/generated", - "textures": { - "layer0": "antarchy:item/floppy_disk/elythia_floppy_disk" - } -} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk/thoraxis_floppy_disk.json b/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk/thoraxis_floppy_disk.json deleted file mode 100644 index 8bf4e26e..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/models/item/floppy_disk/thoraxis_floppy_disk.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "minecraft:item/generated", - "textures": { - "layer0": "antarchy:item/floppy_disk/thoraxis_floppy_disk" - } -} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/particles/bug_spray.json b/common-1.21.1/src/main/resources/assets/antarchy/particles/bug_spray.json new file mode 100644 index 00000000..ba25042c --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/particles/bug_spray.json @@ -0,0 +1 @@ +{"textures":["antarchy:bug_spray/bug_spray_particle1","antarchy:bug_spray/bug_spray_particle2","antarchy:bug_spray/bug_spray_particle3","antarchy:bug_spray/bug_spray_particle4"]} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds.json b/common-1.21.1/src/main/resources/assets/antarchy/sounds.json index 1a9fee58..5ceebe06 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/sounds.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/sounds.json @@ -3111,6 +3111,27 @@ { "name": "antarchy:mob/princess/fly6" } ] }, + "hoverboard_mount": { + "subtitle": "subtitles.antarchy.hoverboard_mount", + "sounds": [ + { "name": "antarchy:hoverboard/mount1" }, + { "name": "antarchy:hoverboard/mount2" }, + { "name": "antarchy:hoverboard/mount3" }, + { "name": "antarchy:hoverboard/mount4" } + ] + }, + "hoverboard_dismount": { + "subtitle": "subtitles.antarchy.hoverboard_dismount", + "sounds": [ + { "name": "antarchy:hoverboard/dismount1" }, + { "name": "antarchy:hoverboard/dismount2" }, + { "name": "antarchy:hoverboard/dismount3" } + ] + }, + "hoverboard_idle": { + "subtitle": "subtitles.antarchy.hoverboard_idle", + "sounds": [ { "name": "antarchy:hoverboard/idle1" } ] + }, "princess_step": { "subtitle": "subtitles.antarchy.princess_step", "sounds": [ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/dismount1.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/dismount1.ogg new file mode 100644 index 00000000..e15e221b Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/dismount1.ogg differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/dismount2.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/dismount2.ogg new file mode 100644 index 00000000..271c9f9c Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/dismount2.ogg differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/dismount3.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/dismount3.ogg new file mode 100644 index 00000000..969f68d2 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/dismount3.ogg differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/idle1.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/idle1.ogg new file mode 100644 index 00000000..d9c060aa Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/idle1.ogg differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount1.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount1.ogg new file mode 100644 index 00000000..752656ba Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount1.ogg differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount2.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount2.ogg new file mode 100644 index 00000000..4372ee0d Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount2.ogg differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount3.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount3.ogg new file mode 100644 index 00000000..1deea65c Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount3.ogg differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount4.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount4.ogg new file mode 100644 index 00000000..85b87c54 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/hoverboard/mount4.ogg differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/block/ant_trap.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/block/ant_trap.png new file mode 100644 index 00000000..f3dd846e Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/block/ant_trap.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/block/computer/computer.animation.json b/common-1.21.1/src/main/resources/assets/antarchy/textures/block/computer/computer.animation.json deleted file mode 100644 index 062e648c..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/textures/block/computer/computer.animation.json +++ /dev/null @@ -1,158 +0,0 @@ -{ - "format_version": "1.8.0", - "animations": { - "on_state": { - "loop": true, - "bones": { - "on": { - "scale": { - "vector": [1, 1, 1] - } - }, - "white_flash": { - "scale": { - "vector": [0, 0, 0] - } - }, - "off": { - "scale": { - "vector": [0, 0, 0] - } - }, - "computer_on": { - "scale": { - "vector": [1, 1, 1] - } - } - } - }, - "off_state": { - "loop": true, - "bones": { - "on": { - "scale": { - "vector": [0, 0, 0] - } - }, - "white_flash": { - "scale": { - "vector": [0, 0, 0] - } - }, - "off": { - "scale": { - "vector": [1, 1, 1] - } - }, - "computer_on": { - "scale": { - "vector": [0, 0, 0] - } - } - } - }, - "turn_on": { - "loop": "hold_on_last_frame", - "animation_length": 0.4583, - "bones": { - "on": { - "scale": { - "0.0": { - "vector": [1, 0, 0] - }, - "0.125": { - "vector": [1, 0, 0] - }, - "0.2917": { - "vector": [1, 1, 1], - "easing": "easeInOutCubic" - } - } - }, - "white_flash": { - "scale": { - "0.0": { - "vector": [1, 0, 0] - }, - "0.0417": { - "vector": [1, 0.2, 0.2] - }, - "0.2083": { - "vector": [1, 1, 1], - "easing": "easeInOutQuint" - } - } - }, - "off": { - "scale": { - "vector": [1, 1, 1] - } - }, - "computer_on": { - "scale": { - "0.0": { - "vector": [0, 0, 0] - }, - "0.0417": { - "vector": [1, 1, 1] - } - } - } - } - }, - "turn_off": { - "loop": "hold_on_last_frame", - "animation_length": 0.4583, - "bones": { - "on": { - "scale": { - "0.0": { - "vector": [1, 1, 1] - }, - "0.25": { - "vector": [1, 0, 1], - "easing": "easeInOutQuint" - } - } - }, - "white_flash": { - "scale": { - "0.0": { - "vector": [1, 1, 0] - }, - "0.125": { - "vector": [1, 1, 0] - }, - "0.375": { - "vector": [1, 0, 0], - "easing": "easeInOutQuart" - } - } - }, - "off": { - "scale": { - "0.0": { - "vector": [0, 0, 0] - }, - "0.0417": { - "vector": [1, 1, 1] - } - } - }, - "computer_on": { - "scale": { - "0.0": { - "vector": [1, 1, 1] - }, - "0.25": { - "vector": [1, 1, 1] - }, - "0.2917": { - "vector": [0, 0, 0] - } - } - } - } - } - } -} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/block/computer/computer.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/block/computer/computer.png deleted file mode 100644 index e24c294c..00000000 Binary files a/common-1.21.1/src/main/resources/assets/antarchy/textures/block/computer/computer.png and /dev/null differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/block/computer/computer.png.mcmeta b/common-1.21.1/src/main/resources/assets/antarchy/textures/block/computer/computer.png.mcmeta deleted file mode 100644 index 68df5399..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/textures/block/computer/computer.png.mcmeta +++ /dev/null @@ -1,5 +0,0 @@ -{ - "animation": { - "frametime": 5 - } -} \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/villager/profession/pest_control.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/villager/profession/pest_control.png new file mode 100644 index 00000000..ddb6ca14 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/villager/profession/pest_control.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/villager/profession/pest_control.png.mcmeta b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/villager/profession/pest_control.png.mcmeta new file mode 100644 index 00000000..5571aa23 --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/textures/entity/villager/profession/pest_control.png.mcmeta @@ -0,0 +1,5 @@ +{ + "villager": { + "hat": "none" + } +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/ATTRIBUTION.txt b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/ATTRIBUTION.txt deleted file mode 100644 index eba7c488..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/ATTRIBUTION.txt +++ /dev/null @@ -1,7 +0,0 @@ -The pencil, eraser, trash, undo, and redo icons are adapted from Pixelarticons -by Gerrit Halfmann (https://github.com/halfmage/pixelarticons), version 2.4.1. - -The source SVG files are included in this directory. The PNGs were rasterized -at 24x24, recolored to Antarchy green, and given a one-pixel black outline. - -These icons are licensed under the MIT License. See LICENSE-pixelarticons.txt. diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/LICENSE-pixelarticons.txt b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/LICENSE-pixelarticons.txt deleted file mode 100644 index 4be35e8f..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/LICENSE-pixelarticons.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Gerrit Halfmann - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/eraser.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/eraser.png deleted file mode 100644 index c08255a2..00000000 Binary files a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/eraser.png and /dev/null differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/eraser.svg b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/eraser.svg deleted file mode 100644 index 00156f00..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/eraser.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/pencil.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/pencil.png deleted file mode 100644 index 561b0b85..00000000 Binary files a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/pencil.png and /dev/null differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/pencil.svg b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/pencil.svg deleted file mode 100644 index e89ccbd6..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/pencil.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/redo.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/redo.png deleted file mode 100644 index 295aefb5..00000000 Binary files a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/redo.png and /dev/null differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/redo.svg b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/redo.svg deleted file mode 100644 index e3d850e2..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/redo.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/trash.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/trash.png deleted file mode 100644 index b8ba1b21..00000000 Binary files a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/trash.png and /dev/null differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/trash.svg b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/trash.svg deleted file mode 100644 index f67fe4ec..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/trash.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/undo.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/undo.png deleted file mode 100644 index 6ad846e0..00000000 Binary files a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/undo.png and /dev/null differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/undo.svg b/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/undo.svg deleted file mode 100644 index f9fbac20..00000000 --- a/common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint/undo.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/item/bug_spray.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/bug_spray.png new file mode 100644 index 00000000..35c4c912 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/bug_spray.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/item/bug_spray_spraying.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/bug_spray_spraying.png new file mode 100644 index 00000000..571c8a49 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/bug_spray_spraying.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/item/computer.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/computer.png deleted file mode 100644 index 8ebda321..00000000 Binary files a/common-1.21.1/src/main/resources/assets/antarchy/textures/item/computer.png and /dev/null differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle1.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle1.png new file mode 100644 index 00000000..485eeb3d Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle1.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle2.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle2.png new file mode 100644 index 00000000..235f79f0 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle2.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle3.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle3.png new file mode 100644 index 00000000..d8a93af4 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle3.png differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle4.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle4.png new file mode 100644 index 00000000..ef70266c Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/particle/bug_spray/bug_spray_particle4.png differ diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/down_with_the_king.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/down_with_the_king.json new file mode 100644 index 00000000..ea092868 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/down_with_the_king.json @@ -0,0 +1,34 @@ +{ + "parent": "antarchy:visit_elythia", + "criteria": { + "kill_king": { + "conditions": { + "entity": { + "type": "antarchy:king" + } + }, + "trigger": "minecraft:player_killed_entity" + } + }, + "display": { + "announce_to_chat": true, + "description": { + "translate": "advancements.antarchy.down_with_the_king.description" + }, + "frame": "challenge", + "icon": { + "count": 1, + "id": "antarchy:king_spawn_egg" + }, + "show_toast": true, + "title": { + "translate": "advancements.antarchy.down_with_the_king.title" + } + }, + "requirements": [ + [ + "kill_king" + ] + ], + "sends_telemetry_event": true +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/down_with_the_queen.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/down_with_the_queen.json new file mode 100644 index 00000000..82ad17eb --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/down_with_the_queen.json @@ -0,0 +1,34 @@ +{ + "parent": "antarchy:visit_thoraxis", + "criteria": { + "kill_queen": { + "conditions": { + "entity": { + "type": "antarchy:queen" + } + }, + "trigger": "minecraft:player_killed_entity" + } + }, + "display": { + "announce_to_chat": true, + "description": { + "translate": "advancements.antarchy.down_with_the_queen.description" + }, + "frame": "challenge", + "icon": { + "count": 1, + "id": "antarchy:queen_spawn_egg" + }, + "show_toast": true, + "title": { + "translate": "advancements.antarchy.down_with_the_queen.title" + } + }, + "requirements": [ + [ + "kill_queen" + ] + ], + "sends_telemetry_event": true +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/category/cavaryn.json b/common-1.21.1/src/main/resources/data/antarchy/computer/category/cavaryn.json new file mode 100644 index 00000000..f5258b70 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/category/cavaryn.json @@ -0,0 +1,4 @@ +{ + "title": "guide.antarchy.category.cavaryn", + "texture": "antarchy:item/floppy_disk/cavaryn_floppy_disk" +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/category/elythia.json b/common-1.21.1/src/main/resources/data/antarchy/computer/category/elythia.json new file mode 100644 index 00000000..6d88b2ba --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/category/elythia.json @@ -0,0 +1,4 @@ +{ + "title": "guide.antarchy.category.elythia", + "texture": "antarchy:item/floppy_disk/elythia_floppy_disk" +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/category/general.json b/common-1.21.1/src/main/resources/data/antarchy/computer/category/general.json new file mode 100644 index 00000000..e7bf2d6e --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/category/general.json @@ -0,0 +1,4 @@ +{ + "title": "guide.antarchy.category.general", + "texture": "antarchy:item/floppy_disk/floppy_disk" +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/category/thoraxis.json b/common-1.21.1/src/main/resources/data/antarchy/computer/category/thoraxis.json new file mode 100644 index 00000000..73a72371 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/category/thoraxis.json @@ -0,0 +1,4 @@ +{ + "title": "guide.antarchy.category.thoraxis", + "texture": "antarchy:item/floppy_disk/thoraxis_floppy_disk" +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/antman_game.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/antman_game.json index 75f1e29d..0512e5d9 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/antman_game.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/antman_game.json @@ -1,4 +1,5 @@ { + "category": "antarchy:general", "title": "guide.antarchy.disk.antman_game.title", "entries": [] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/basilisk_game.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/basilisk_game.json index b9a5dbcb..25919cac 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/basilisk_game.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/basilisk_game.json @@ -1,5 +1,5 @@ { - "category": "elythia", + "category": "antarchy:elythia", "title": "guide.antarchy.disk.basilisk_game.title", "entries": [] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/blockle_game.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/blockle_game.json index 3d826c18..90163a97 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/blockle_game.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/blockle_game.json @@ -1,4 +1,5 @@ { + "category": "antarchy:general", "title": "guide.antarchy.disk.blockle_game.title", "entries": [] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/bloodglass.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/bloodglass.json index fcb45ca4..8dd99169 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/bloodglass.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/bloodglass.json @@ -1,6 +1,5 @@ { - "category": "thoraxis", + "category": "antarchy:thoraxis", "title": "guide.antarchy.disk.bloodglass.title", - "entries": ["antarchy:bloodglass"], - "wallpaper": "antarchy:bloodglass" + "entries": ["antarchy:bloodglass"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/cavaryn.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/cavaryn.json index c825861b..03ff94b2 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/cavaryn.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/cavaryn.json @@ -1,6 +1,5 @@ { - "category": "cavaryn", + "category": "antarchy:cavaryn", "title": "guide.antarchy.disk.cavaryn.title", - "entries": ["antarchy:cavaryn"], - "wallpaper": "antarchy:cavaryn" + "entries": ["antarchy:cavaryn"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/chronosphere.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/chronosphere.json index 29c1e104..1d5b1419 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/chronosphere.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/chronosphere.json @@ -1,5 +1,5 @@ { - "category": "thoraxis", + "category": "antarchy:thoraxis", "title": "guide.antarchy.disk.chronosphere.title", "entries": ["antarchy:chronosphere"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/elythia.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/elythia.json index d0ad36f8..e3d1c761 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/elythia.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/elythia.json @@ -1,6 +1,5 @@ { - "category": "elythia", + "category": "antarchy:elythia", "title": "guide.antarchy.disk.elythia.title", - "entries": ["antarchy:elythia"], - "wallpaper": "antarchy:elythia" + "entries": ["antarchy:elythia"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/flying_squirrel.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/flying_squirrel.json index ac77c8ca..138c2703 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/flying_squirrel.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/flying_squirrel.json @@ -1,5 +1,5 @@ { - "category": "elythia", + "category": "antarchy:elythia", "title": "guide.antarchy.disk.flying_squirrel.title", "entries": ["antarchy:flying_squirrel"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/high_fructose_corn_syrup.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/high_fructose_corn_syrup.json index 3d3b0142..beffa6c5 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/high_fructose_corn_syrup.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/high_fructose_corn_syrup.json @@ -1,5 +1,5 @@ { - "category": "general", + "category": "antarchy:general", "title": "guide.antarchy.disk.high_fructose_corn_syrup.title", "entries": ["antarchy:high_fructose_corn_syrup"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/king.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/king.json index 4966df7f..6db56880 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/king.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/king.json @@ -1,5 +1,5 @@ { - "category": "elythia", + "category": "antarchy:elythia", "title": "guide.antarchy.disk.king.title", - "entries": ["antarchy:king"] + "entries": ["antarchy:king", "antarchy:prince"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/kraken.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/kraken.json index 2b2d6f7c..fcfc2755 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/kraken.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/kraken.json @@ -1,5 +1,5 @@ { - "category": "general", + "category": "antarchy:general", "title": "guide.antarchy.disk.kraken.title", "entries": ["antarchy:kraken"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/queen.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/queen.json index 39e9f6ed..760ed28b 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/queen.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/queen.json @@ -1,5 +1,5 @@ { - "category": "thoraxis", + "category": "antarchy:thoraxis", "title": "guide.antarchy.disk.queen.title", - "entries": ["antarchy:queen"] + "entries": ["antarchy:queen", "antarchy:princess"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/temporal_fields.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/temporal_fields.json index 826b53af..4d5e0e85 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/temporal_fields.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/temporal_fields.json @@ -1,6 +1,5 @@ { - "category": "thoraxis", + "category": "antarchy:thoraxis", "title": "guide.antarchy.disk.temporal_fields.title", - "entries": ["antarchy:temporal_fields"], - "wallpaper": "antarchy:temporal_fields" + "entries": ["antarchy:temporal_fields"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/thoraxis.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/thoraxis.json index a7e052aa..aa847632 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/thoraxis.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/thoraxis.json @@ -1,6 +1,5 @@ { - "category": "thoraxis", + "category": "antarchy:thoraxis", "title": "guide.antarchy.disk.thoraxis.title", - "entries": ["antarchy:thoraxis", "antarchy:nightmare"], - "wallpaper": "antarchy:thoraxis" + "entries": ["antarchy:thoraxis", "antarchy:nightmare"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/toreterror_arena.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/toreterror_arena.json index 068f6ccd..075db5c3 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/toreterror_arena.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/toreterror_arena.json @@ -1,5 +1,5 @@ { - "category": "elythia", + "category": "antarchy:elythia", "title": "guide.antarchy.disk.toreterror_arena.title", "entries": ["antarchy:toreterror_arena"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/vortex.json b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/vortex.json index 4106610b..9ccd54f7 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/disk/vortex.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/disk/vortex.json @@ -1,6 +1,5 @@ { - "category": "thoraxis", + "category": "antarchy:thoraxis", "title": "guide.antarchy.disk.vortex.title", - "entries": ["antarchy:vortex"], - "wallpaper": "antarchy:vortex" + "entries": ["antarchy:vortex"] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/entry/introduction.json b/common-1.21.1/src/main/resources/data/antarchy/computer/entry/introduction.json index cbd6611e..6594ae95 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer/entry/introduction.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/entry/introduction.json @@ -4,5 +4,5 @@ "title": "guide.antarchy.entry.introduction.title", "subtitle": "guide.antarchy.entry.introduction.subtitle", "description": ["guide.antarchy.entry.introduction.description"], - "cover_item": "antarchy:floppy_disk" + "cover_item": "antos:floppy_disk" } diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/entry/prince.json b/common-1.21.1/src/main/resources/data/antarchy/computer/entry/prince.json new file mode 100644 index 00000000..1aebfeb9 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/entry/prince.json @@ -0,0 +1,9 @@ +{ + "type": "entity", + "category": "elythia", + "title": "guide.antarchy.entry.prince.title", + "subtitle": "guide.antarchy.entry.prince.subtitle", + "description": ["guide.antarchy.entry.prince.description"], + "entity": "antarchy:prince", + "cover_entity": "antarchy:prince" +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer/entry/princess.json b/common-1.21.1/src/main/resources/data/antarchy/computer/entry/princess.json new file mode 100644 index 00000000..e1d43dba --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/computer/entry/princess.json @@ -0,0 +1,9 @@ +{ + "type": "entity", + "category": "thoraxis", + "title": "guide.antarchy.entry.princess.title", + "subtitle": "guide.antarchy.entry.princess.subtitle", + "description": ["guide.antarchy.entry.princess.description"], + "entity": "antarchy:princess", + "cover_entity": "antarchy:princess" +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/computer_scientist_trades/trades.json b/common-1.21.1/src/main/resources/data/antarchy/computer_scientist_trades/trades.json index 27bf53b1..2717b195 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/computer_scientist_trades/trades.json +++ b/common-1.21.1/src/main/resources/data/antarchy/computer_scientist_trades/trades.json @@ -3,9 +3,9 @@ {"level": 1, "index": 0, "buy": {"item": "minecraft:redstone", "min": 12, "max": 16}, "sell": {"item": "minecraft:emerald", "min": 1, "max": 2}}, {"level": 1, "index": 1, "buy": {"item": "antarchy:bluestone", "min": 6, "max": 10}, "sell": {"item": "minecraft:emerald", "min": 1, "max": 2}}, {"level": 1, "index": 2, "buy": {"item": "minecraft:emerald", "min": 2, "max": 4}, "sell": {"item": "antarchy:duct_tape", "min": 1, "max": 2}}, - {"level": 1, "index": 3, "buy": {"item": "antarchy:floppy_disk", "min": 1, "max": 1}, "sell": {"item": "minecraft:emerald", "min": 4, "max": 8}}, - {"level": 2, "index": 0, "buy": {"item": "minecraft:emerald", "min": 4, "max": 8}, "sell": {"item": "antarchy:floppy_disk", "min": 1, "max": 1}, "sell_disk": "random_general"}, - {"level": 2, "index": 1, "buy": {"item": "antarchy:floppy_disk", "min": 12, "max": 20}, "sell": {"item": "antarchy:floppy_disk", "min": 1, "max": 1}, "sell_disk": "antarchy:toreterror_arena"}, + {"level": 1, "index": 3, "buy": {"item": "antos:floppy_disk", "min": 1, "max": 1}, "sell": {"item": "minecraft:emerald", "min": 4, "max": 8}}, + {"level": 2, "index": 0, "buy": {"item": "minecraft:emerald", "min": 4, "max": 8}, "sell": {"item": "antos:floppy_disk", "min": 1, "max": 1}, "sell_disk": "random_general"}, + {"level": 2, "index": 1, "buy": {"item": "antos:floppy_disk", "min": 12, "max": 20}, "sell": {"item": "antos:floppy_disk", "min": 1, "max": 1}, "sell_disk": "antarchy:toreterror_arena"}, {"level": 3, "index": 0, "buy": {"item": "antarchy:vortex_charge", "min": 1, "max": 1}, "sell": {"item": "minecraft:emerald", "min": 10, "max": 10}}, {"level": 3, "index": 1, "buy": {"item": "antarchy:flytrap_goo", "min": 1, "max": 1}, "sell": {"item": "minecraft:emerald", "min": 10, "max": 10}}, {"level": 4, "index": 0, "buy": {"item": "minecraft:emerald", "min": 8, "max": 16}, "sell": {"item": "minecraft:comparator", "min": 1, "max": 2}}, @@ -14,7 +14,7 @@ {"level": 5, "index": 0, "buy": {"item": "minecraft:emerald", "min": 32, "max": 64}, "sell": {"item": "antarchy:uranium_nugget", "min": 1, "max": 1}}, {"level": 5, "index": 1, "buy": {"item": "minecraft:emerald", "min": 32, "max": 64}, "sell": {"item": "antarchy:titanium_nugget", "min": 1, "max": 1}}, {"level": 5, "index": 2, "buy": {"item": "minecraft:emerald", "min": 16, "max": 32}, "sell": {"item": "antarchy:rainbow_sugar", "min": 1, "max": 2}}, - {"level": 5, "index": 3, "buy": {"item": "minecraft:emerald", "min": 24, "max": 40}, "sell": {"item": "antarchy:floppy_disk", "min": 1, "max": 1}, "sell_disk": "antarchy:antman_game", "max_uses": 1, "chance": 0.35}, - {"level": 5, "index": 4, "buy": {"item": "minecraft:emerald", "min": 24, "max": 40}, "sell": {"item": "antarchy:floppy_disk", "min": 1, "max": 1}, "sell_disk": "antarchy:blockle_game", "max_uses": 1, "chance": 0.35} + {"level": 5, "index": 3, "buy": {"item": "minecraft:emerald", "min": 24, "max": 40}, "sell": {"item": "antos:floppy_disk", "min": 1, "max": 1}, "sell_disk": "antarchy:antman_game", "max_uses": 1, "chance": 0.35}, + {"level": 5, "index": 4, "buy": {"item": "minecraft:emerald", "min": 24, "max": 40}, "sell": {"item": "antos:floppy_disk", "min": 1, "max": 1}, "sell_disk": "antarchy:blockle_game", "max_uses": 1, "chance": 0.35} ] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/basilisk_lair/treasure.json b/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/basilisk_lair/treasure.json index 69ebd4dc..cbdff84c 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/basilisk_lair/treasure.json +++ b/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/basilisk_lair/treasure.json @@ -36,13 +36,13 @@ }, { "type": "minecraft:item", - "name": "antarchy:floppy_disk", + "name": "antos:floppy_disk", "weight": 2, "functions": [ { "function": "minecraft:set_components", "components": { - "antarchy:floppy_disk": "antarchy:basilisk_game" + "antos:floppy_disk": "antarchy:basilisk_game" } } ] diff --git a/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/computer_prototype.json b/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/computer_prototype.json index 0d25df8b..48d8c6e9 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/computer_prototype.json +++ b/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/computer_prototype.json @@ -6,65 +6,65 @@ "entries": [ { "type": "minecraft:item", - "name": "antarchy:floppy_disk", + "name": "antos:floppy_disk", "weight": 1, "functions": [ { "function": "minecraft:set_components", "components": { - "antarchy:floppy_disk": "antarchy:chronosphere" + "antos:floppy_disk": "antarchy:chronosphere" } } ] }, { "type": "minecraft:item", - "name": "antarchy:floppy_disk", + "name": "antos:floppy_disk", "weight": 4, "functions": [ { "function": "minecraft:set_components", "components": { - "antarchy:floppy_disk": "antarchy:elythia" + "antos:floppy_disk": "antarchy:elythia" } } ] }, { "type": "minecraft:item", - "name": "antarchy:floppy_disk", + "name": "antos:floppy_disk", "weight": 4, "functions": [ { "function": "minecraft:set_components", "components": { - "antarchy:floppy_disk": "antarchy:flying_squirrel" + "antos:floppy_disk": "antarchy:flying_squirrel" } } ] }, { "type": "minecraft:item", - "name": "antarchy:floppy_disk", + "name": "antos:floppy_disk", "weight": 4, "functions": [ { "function": "minecraft:set_components", "components": { - "antarchy:floppy_disk": "antarchy:cavaryn" + "antos:floppy_disk": "antarchy:cavaryn" } } ] }, { "type": "minecraft:item", - "name": "antarchy:floppy_disk", + "name": "antos:floppy_disk", "weight": 1, "functions": [ { "function": "minecraft:set_components", "components": { - "antarchy:floppy_disk": "antarchy:basilisk_game" + "antos:floppy_disk": "antarchy:basilisk_game" } } ] diff --git a/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/underside_ruins/generic.json b/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/underside_ruins/generic.json index f43f4a1d..96d11aad 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/underside_ruins/generic.json +++ b/common-1.21.1/src/main/resources/data/antarchy/loot_table/chests/underside_ruins/generic.json @@ -1,8 +1,8 @@ {"type":"minecraft:chest","pools":[{"rolls":{"type":"minecraft:uniform","min":5,"max":8},"entries":[ -{"type":"minecraft:item","name":"antarchy:floppy_disk","weight":6,"functions":[{"function":"minecraft:set_components","components":{"antarchy:floppy_disk":"antarchy:thoraxis"}}]}, -{"type":"minecraft:item","name":"antarchy:floppy_disk","weight":5,"functions":[{"function":"minecraft:set_components","components":{"antarchy:floppy_disk":"antarchy:temporal_fields"}}]}, -{"type":"minecraft:item","name":"antarchy:floppy_disk","weight":5,"functions":[{"function":"minecraft:set_components","components":{"antarchy:floppy_disk":"antarchy:bloodglass"}}]}, -{"type":"minecraft:item","name":"antarchy:floppy_disk","weight":5,"functions":[{"function":"minecraft:set_components","components":{"antarchy:floppy_disk":"antarchy:vortex"}}]}, +{"type":"minecraft:item","name":"antos:floppy_disk","weight":6,"functions":[{"function":"minecraft:set_components","components":{"antos:floppy_disk":"antarchy:thoraxis"}}]}, +{"type":"minecraft:item","name":"antos:floppy_disk","weight":5,"functions":[{"function":"minecraft:set_components","components":{"antos:floppy_disk":"antarchy:temporal_fields"}}]}, +{"type":"minecraft:item","name":"antos:floppy_disk","weight":5,"functions":[{"function":"minecraft:set_components","components":{"antos:floppy_disk":"antarchy:bloodglass"}}]}, +{"type":"minecraft:item","name":"antos:floppy_disk","weight":5,"functions":[{"function":"minecraft:set_components","components":{"antos:floppy_disk":"antarchy:vortex"}}]}, {"type":"minecraft:item","name":"minecraft:arrow","weight":16,"functions":[{"function":"minecraft:set_count","count":{"type":"minecraft:uniform","min":10,"max":28}}]}, {"type":"minecraft:item","name":"minecraft:tipped_arrow","weight":9,"functions":[{"function":"minecraft:set_count","count":{"type":"minecraft:uniform","min":2,"max":6}},{"function":"minecraft:set_potion","id":"antarchy:inversion"}]}, {"type":"minecraft:item","name":"minecraft:iron_pickaxe","weight":10},{"type":"minecraft:item","name":"minecraft:iron_sword","weight":8}, diff --git a/common-1.21.1/src/main/resources/data/antarchy/pest_control_trades/trades.json b/common-1.21.1/src/main/resources/data/antarchy/pest_control_trades/trades.json new file mode 100644 index 00000000..14209b7d --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/pest_control_trades/trades.json @@ -0,0 +1 @@ +{"trades":[{"level":1,"index":0,"buy":{"item":"antarchy:raw_bug_meat","count":16},"sell":{"item":"minecraft:emerald","count":1},"max_uses":16,"villager_xp":2},{"level":1,"index":1,"buy":{"item":"antarchy:chitin","count":8},"sell":{"item":"minecraft:emerald","count":2},"max_uses":12,"villager_xp":2},{"level":2,"index":0,"buy":{"item":"minecraft:emerald","count":5},"sell":{"item":"antarchy:bug_spray","count":1},"max_uses":8,"villager_xp":10},{"level":2,"index":1,"buy":{"item":"antarchy:raw_bug_meat","count":12},"sell":{"item":"minecraft:emerald","count":2},"max_uses":16,"villager_xp":5},{"level":3,"index":0,"buy":{"item":"minecraft:emerald","count":4},"second_buy":{"item":"antarchy:chitin","count":4},"sell":{"item":"antarchy:bug_spray","count":1},"max_uses":8,"villager_xp":15},{"level":3,"index":1,"buy":{"item":"antarchy:chitin","count":6},"sell":{"item":"minecraft:emerald","count":3},"max_uses":12,"villager_xp":10},{"level":4,"index":0,"buy":{"item":"minecraft:emerald","count":3},"sell":{"item":"antarchy:bug_spray","count":1},"max_uses":12,"villager_xp":20},{"level":5,"index":0,"buy":{"item":"minecraft:emerald","count":2},"second_buy":{"item":"antarchy:chitin","count":2},"sell":{"item":"antarchy:bug_spray","count":1},"max_uses":16,"villager_xp":30}]} diff --git a/common-1.21.1/src/main/resources/data/antarchy/recipe/ant_trap.json b/common-1.21.1/src/main/resources/data/antarchy/recipe/ant_trap.json new file mode 100644 index 00000000..05b7378f --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/recipe/ant_trap.json @@ -0,0 +1 @@ +{"type":"minecraft:crafting_shaped","pattern":["GS","QQ"],"key":{"G":{"item":"antarchy:flytrap_goo"},"S":{"item":"minecraft:sugar"},"Q":{"item":"minecraft:quartz"}},"result":{"id":"antarchy:ant_trap","count":1}} diff --git a/common-1.21.1/src/main/resources/data/antarchy/recipe/computer.json b/common-1.21.1/src/main/resources/data/antarchy/recipe/computer.json index 6def057f..29f61ce2 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/recipe/computer.json +++ b/common-1.21.1/src/main/resources/data/antarchy/recipe/computer.json @@ -24,6 +24,6 @@ ], "result": { "count": 1, - "id": "antarchy:computer" + "id": "antos:computer" } } diff --git a/common-1.21.1/src/main/resources/data/antarchy/structure/village/computer_scientist_basement.nbt b/common-1.21.1/src/main/resources/data/antarchy/structure/village/computer_scientist_basement.nbt index 4ec1b08a..7900b288 100644 Binary files a/common-1.21.1/src/main/resources/data/antarchy/structure/village/computer_scientist_basement.nbt and b/common-1.21.1/src/main/resources/data/antarchy/structure/village/computer_scientist_basement.nbt differ diff --git a/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/arthropods.json b/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/arthropods.json new file mode 100644 index 00000000..e0f3a117 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/arthropods.json @@ -0,0 +1 @@ +{"replace":false,"values":["antarchy:alpha_mantis","antarchy:bed_bug","antarchy:bomber","antarchy:brutalfly","antarchy:butterfly","antarchy:caterpillar","antarchy:emperor_scorpion","antarchy:flytrap","antarchy:hercules_beetle","antarchy:mantis","antarchy:rolly_polly","antarchy:scorpion","antarchy:spit_bug","antarchy:springbug","antarchy:stink_bug","antarchy:wasp"]} diff --git a/common-1.21.1/src/main/resources/data/antarchy/tags/worldgen/biome/has_structure/trayaurus_lab_biomes.json b/common-1.21.1/src/main/resources/data/antarchy/tags/worldgen/biome/has_structure/trayaurus_lab_biomes.json index b4a27d0f..d78507aa 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/tags/worldgen/biome/has_structure/trayaurus_lab_biomes.json +++ b/common-1.21.1/src/main/resources/data/antarchy/tags/worldgen/biome/has_structure/trayaurus_lab_biomes.json @@ -4,4 +4,4 @@ "antarchy:elythia_meadow", "antarchy:truffalo_forest" ] -} \ No newline at end of file +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/dimensional_tears.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/dimensional_tears.json index f2b49a38..1763b0ce 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/dimensional_tears.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/dimensional_tears.json @@ -12,8 +12,12 @@ "type": "minecraft:height_range", "height": { "type": "minecraft:uniform", - "min_inclusive": { "absolute": 24 }, - "max_inclusive": { "absolute": 170 } + "min_inclusive": { + "absolute": 24 + }, + "max_inclusive": { + "absolute": 170 + } } }, { diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/fallen_ouranwood_tree.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/fallen_ouranwood_tree.json index de592a7f..306faa83 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/fallen_ouranwood_tree.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/fallen_ouranwood_tree.json @@ -1,9 +1,19 @@ { "feature": "antarchy:fallen_ouranwood_tree", "placement": [ - { "type": "minecraft:rarity_filter", "chance": 5 }, - { "type": "minecraft:in_square" }, - { "type": "minecraft:heightmap", "heightmap": "WORLD_SURFACE_WG" }, - { "type": "minecraft:biome" } + { + "type": "minecraft:rarity_filter", + "chance": 5 + }, + { + "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/fungal_mushroom.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/fungal_mushroom.json index a720f1e1..2ca02158 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/fungal_mushroom.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/fungal_mushroom.json @@ -1,9 +1,19 @@ { "feature": "antarchy:fungal_mushroom", "placement": [ - { "type": "minecraft:rarity_filter", "chance": 4 }, - { "type": "minecraft:in_square" }, - { "type": "minecraft:heightmap", "heightmap": "WORLD_SURFACE_WG" }, - { "type": "minecraft:biome" } + { + "type": "minecraft:rarity_filter", + "chance": 4 + }, + { + "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/giant_lily_pad_patch.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch.json index b1b0dd8d..28ec81e3 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch.json @@ -1,9 +1,19 @@ { "feature": "antarchy:giant_lily_pad_patch", "placement": [ - { "type": "minecraft:rarity_filter", "chance": 6 }, - { "type": "minecraft:in_square" }, - { "type": "minecraft:heightmap", "heightmap": "MOTION_BLOCKING_NO_LEAVES" }, - { "type": "minecraft:biome" } + { + "type": "minecraft:rarity_filter", + "chance": 6 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + }, + { + "type": "minecraft:biome" + } ] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_common.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_common.json index 6b49ad1f..153f630d 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_common.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_common.json @@ -1,9 +1,19 @@ { "feature": "antarchy:giant_lily_pad_patch", "placement": [ - { "type": "minecraft:rarity_filter", "chance": 2 }, - { "type": "minecraft:in_square" }, - { "type": "minecraft:heightmap", "heightmap": "MOTION_BLOCKING_NO_LEAVES" }, - { "type": "minecraft:biome" } + { + "type": "minecraft:rarity_filter", + "chance": 2 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + }, + { + "type": "minecraft:biome" + } ] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_meadow.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_meadow.json index 9e0694f1..2a71d4d9 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_meadow.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_meadow.json @@ -1,9 +1,19 @@ { "feature": "antarchy:giant_lily_pad_patch", "placement": [ - { "type": "minecraft:rarity_filter", "chance": 8 }, - { "type": "minecraft:in_square" }, - { "type": "minecraft:heightmap", "heightmap": "MOTION_BLOCKING_NO_LEAVES" }, - { "type": "minecraft:biome" } + { + "type": "minecraft:rarity_filter", + "chance": 8 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + }, + { + "type": "minecraft:biome" + } ] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_peach_forest.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_peach_forest.json index 176eba6c..1752b357 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_peach_forest.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/giant_lily_pad_patch_peach_forest.json @@ -1,9 +1,19 @@ { "feature": "antarchy:giant_lily_pad_patch_peach_forest", "placement": [ - { "type": "minecraft:rarity_filter", "chance": 6 }, - { "type": "minecraft:in_square" }, - { "type": "minecraft:heightmap", "heightmap": "MOTION_BLOCKING_NO_LEAVES" }, - { "type": "minecraft:biome" } + { + "type": "minecraft:rarity_filter", + "chance": 6 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "MOTION_BLOCKING_NO_LEAVES" + }, + { + "type": "minecraft:biome" + } ] } diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_blood_crystal_spires.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_blood_crystal_spires.json index 1b324284..a4dc2f79 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_blood_crystal_spires.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_blood_crystal_spires.json @@ -29,5 +29,3 @@ } ] } - - diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_large_blood_crystal_spires.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_large_blood_crystal_spires.json index e75e392d..1f386190 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_large_blood_crystal_spires.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_large_blood_crystal_spires.json @@ -29,5 +29,3 @@ } ] } - - diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_medium_blood_crystal_spires.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_medium_blood_crystal_spires.json index 39631321..80554ca0 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_medium_blood_crystal_spires.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/lucid_medium_blood_crystal_spires.json @@ -29,5 +29,3 @@ } ] } - - diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ore_magma.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ore_magma.json index acd5b565..51bb28fe 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ore_magma.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ore_magma.json @@ -10,11 +10,15 @@ }, { "type": "minecraft:height_range", - "height": { - "type": "minecraft:uniform", - "max_inclusive": { "absolute": 144 }, - "min_inclusive": { "absolute": 8 } + "height": { + "type": "minecraft:uniform", + "max_inclusive": { + "absolute": 144 + }, + "min_inclusive": { + "absolute": 8 } + } }, { "type": "minecraft:biome" diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ouranwood_trees.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ouranwood_trees.json index 850dde08..023da009 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ouranwood_trees.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ouranwood_trees.json @@ -1,9 +1,19 @@ { "feature": "antarchy:ouranwood_tree_selector", "placement": [ - { "type": "minecraft:count", "count": 1 }, - { "type": "minecraft:in_square" }, - { "type": "minecraft:heightmap", "heightmap": "WORLD_SURFACE_WG" }, - { "type": "minecraft:biome" } + { + "type": "minecraft:count", + "count": 1 + }, + { + "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/ouranwood_trees_sparse.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ouranwood_trees_sparse.json index 61755a74..f596753c 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ouranwood_trees_sparse.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/ouranwood_trees_sparse.json @@ -1,9 +1,19 @@ { "feature": "antarchy:ouranwood_tree_selector_sparse", "placement": [ - { "type": "minecraft:rarity_filter", "chance": 6 }, - { "type": "minecraft:in_square" }, - { "type": "minecraft:heightmap", "heightmap": "WORLD_SURFACE_WG" }, - { "type": "minecraft:biome" } + { + "type": "minecraft:rarity_filter", + "chance": 6 + }, + { + "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/thoraxis_floor_rib_columns.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/thoraxis_floor_rib_columns.json index 6e7c25e7..b972bc92 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/thoraxis_floor_rib_columns.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/thoraxis_floor_rib_columns.json @@ -9,7 +9,9 @@ "type": "minecraft:height_range", "height": { "type": "minecraft:uniform", - "min_inclusive": { "absolute": 32 }, + "min_inclusive": { + "absolute": 32 + }, "max_inclusive": { "absolute": 84 } diff --git a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/thoraxis_floor_spikes.json b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/thoraxis_floor_spikes.json index d3bf833e..2bd6a911 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/thoraxis_floor_spikes.json +++ b/common-1.21.1/src/main/resources/data/antarchy/worldgen/placed_feature/thoraxis_floor_spikes.json @@ -12,7 +12,9 @@ "type": "minecraft:height_range", "height": { "type": "minecraft:uniform", - "min_inclusive": { "absolute": 24 }, + "min_inclusive": { + "absolute": 24 + }, "max_inclusive": { "absolute": 96 } 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 index 5ef5b1e4..2d7e2fc3 100644 --- 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 @@ -12,8 +12,12 @@ "type": "minecraft:height_range", "height": { "type": "minecraft:uniform", - "min_inclusive": { "absolute": 1 }, - "max_inclusive": { "absolute": 1 } + "min_inclusive": { + "absolute": 1 + }, + "max_inclusive": { + "absolute": 1 + } } }, { 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 6f2d2b7d..cb067565 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 @@ -16,8 +16,12 @@ "type": "minecraft:height_range", "height": { "type": "minecraft:uniform", - "min_inclusive": { "absolute": 8 }, - "max_inclusive": { "absolute": 220 } + "min_inclusive": { + "absolute": 8 + }, + "max_inclusive": { + "absolute": 220 + } } }, { diff --git a/common-1.21.1/src/main/resources/data/minecraft/tags/point_of_interest_type/acquirable_job_site.json b/common-1.21.1/src/main/resources/data/minecraft/tags/point_of_interest_type/acquirable_job_site.json index df36bb72..7587066e 100644 --- a/common-1.21.1/src/main/resources/data/minecraft/tags/point_of_interest_type/acquirable_job_site.json +++ b/common-1.21.1/src/main/resources/data/minecraft/tags/point_of_interest_type/acquirable_job_site.json @@ -1,6 +1 @@ -{ - "replace": false, - "values": [ - "antarchy:computer" - ] -} +{"replace":false,"values":["antarchy:pest_control"]} diff --git a/common-1.21.1/src/main/resources/data/minecraft/tags/worldgen/biome/has_structure/bastion_remnant.json b/common-1.21.1/src/main/resources/data/minecraft/tags/worldgen/biome/has_structure/bastion_remnant.json new file mode 100644 index 00000000..5d341ba2 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/minecraft/tags/worldgen/biome/has_structure/bastion_remnant.json @@ -0,0 +1,4 @@ +{ + "replace": false, + "values": [] +} diff --git a/common-1.21.1/src/main/resources/data/minecraft/tags/worldgen/biome/has_structure/desert_pyramid.json b/common-1.21.1/src/main/resources/data/minecraft/tags/worldgen/biome/has_structure/desert_pyramid.json new file mode 100644 index 00000000..5d341ba2 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/minecraft/tags/worldgen/biome/has_structure/desert_pyramid.json @@ -0,0 +1,4 @@ +{ + "replace": false, + "values": [] +} diff --git a/common-1.21.1/src/main/resources/data/minecraft/tags/worldgen/biome/has_structure/end_city.json b/common-1.21.1/src/main/resources/data/minecraft/tags/worldgen/biome/has_structure/end_city.json new file mode 100644 index 00000000..5d341ba2 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/minecraft/tags/worldgen/biome/has_structure/end_city.json @@ -0,0 +1,4 @@ +{ + "replace": false, + "values": [] +} diff --git a/common-1.21.1/src/main/resources/data/minecraft/worldgen/noise/nether/temperature.json b/common-1.21.1/src/main/resources/data/minecraft/worldgen/noise/nether/temperature.json deleted file mode 100644 index ab7b15e6..00000000 --- a/common-1.21.1/src/main/resources/data/minecraft/worldgen/noise/nether/temperature.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "amplitudes": [ - 1.0, - 1.0 - ], - "firstOctave": -7 -} diff --git a/common-1.21.1/src/main/resources/data/minecraft/worldgen/noise/nether/vegetation.json b/common-1.21.1/src/main/resources/data/minecraft/worldgen/noise/nether/vegetation.json deleted file mode 100644 index ab7b15e6..00000000 --- a/common-1.21.1/src/main/resources/data/minecraft/worldgen/noise/nether/vegetation.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "amplitudes": [ - 1.0, - 1.0 - ], - "firstOctave": -7 -} diff --git a/common-1.21.1/src/test/resources/antarchy/computer/fixtures/README.md b/common-1.21.1/src/test/resources/antarchy/computer/fixtures/README.md deleted file mode 100644 index 2301fa00..00000000 --- a/common-1.21.1/src/test/resources/antarchy/computer/fixtures/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Computer contract fixtures - -These fixtures describe expected computer state transitions for validation tooling. They are not runtime datapack content and are not loaded by the game. - -The repository currently has no computer-specific test harness. The fixtures cover first placement, duplicate disk consumption, protection of the built-in introduction module, authenticated ejection through Settings or Trash, rejection without authentication, and physical disk drops when the block is broken. diff --git a/common-1.21.1/src/test/resources/antarchy/computer/fixtures/built_in_introduction_protection.json b/common-1.21.1/src/test/resources/antarchy/computer/fixtures/built_in_introduction_protection.json deleted file mode 100644 index 6383bd49..00000000 --- a/common-1.21.1/src/test/resources/antarchy/computer/fixtures/built_in_introduction_protection.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "case": "built_in_introduction_protection", - "physical_disk_ids": ["antarchy:chronosphere"], - "built_in_modules": ["antarchy:introduction"], - "settings_ejection_candidates": ["antarchy:chronosphere"], - "expected_dropped_disk_ids": ["antarchy:chronosphere"], - "expected_ejectable_ids": ["antarchy:chronosphere"], - "expected_introduction_dropped": false, - "expected_introduction_ejectable": false -} diff --git a/common-1.21.1/src/test/resources/antarchy/computer/fixtures/duplicate_disk.json b/common-1.21.1/src/test/resources/antarchy/computer/fixtures/duplicate_disk.json deleted file mode 100644 index 35ac5ed2..00000000 --- a/common-1.21.1/src/test/resources/antarchy/computer/fixtures/duplicate_disk.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "case": "duplicate_disk", - "initial_physical_disk_ids": ["antarchy:chronosphere"], - "inserted_disk_id": "antarchy:chronosphere", - "expected_physical_disk_ids": ["antarchy:chronosphere"], - "expected_item_consumed": true, - "expected_archive_change": false -} diff --git a/common-1.21.1/src/test/resources/antarchy/computer/fixtures/ejection_and_drop.json b/common-1.21.1/src/test/resources/antarchy/computer/fixtures/ejection_and_drop.json deleted file mode 100644 index 6d6540a6..00000000 --- a/common-1.21.1/src/test/resources/antarchy/computer/fixtures/ejection_and_drop.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "case": "ejection_and_drop", - "physical_disk_ids": ["antarchy:chronosphere", "antarchy:toreterror_arena"], - "ejection": {"authenticated": true, "route": "settings_or_trash", "selected_disk_id": "antarchy:chronosphere", "expected_returned_item_id": "antarchy:floppy_disk", "expected_remaining_physical_disk_ids": ["antarchy:toreterror_arena"]}, - "drop_after_break": {"expected_dropped_disk_ids": ["antarchy:toreterror_arena"], "expected_introduction_dropped": false}, - "rejection": {"authenticated": false, "expected_ejection": false} -} diff --git a/common-1.21.1/src/test/resources/antarchy/computer/fixtures/newly_placed.json b/common-1.21.1/src/test/resources/antarchy/computer/fixtures/newly_placed.json deleted file mode 100644 index 500d082c..00000000 --- a/common-1.21.1/src/test/resources/antarchy/computer/fixtures/newly_placed.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "case": "newly_placed", - "physical_disk_ids": [], - "built_in_modules": ["antarchy:introduction"], - "password": {"state": "unset"}, - "session": {"authenticated": false, "screen_occupied": false}, - "expectations": ["introduction_visible_before_login", "first_use_password_setup_required", "introduction_not_ejectable", "introduction_not_dropped"] -} diff --git a/fabric-1.21.1/build.gradle b/fabric-1.21.1/build.gradle index ec00d835..fa2c87eb 100644 --- a/fabric-1.21.1/build.gradle +++ b/fabric-1.21.1/build.gradle @@ -38,6 +38,8 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version_1_21_1}" modApi "net.fabricmc.fabric-api:fabric-api:${fabric_api_version_1_21_1}" modImplementation "software.bernie.geckolib:geckolib-fabric-1.21.1:${geckolib_version}" + // AntOS is developed beside Antarchy as a separate local project. + modImplementation files("$rootDir/../AntOS/fabric-1.21.1/build/libs/antos-fabric-1.21.1-0.1.0.jar") modCompileOnly("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_fabric}") modLocalRuntime("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_fabric}") modLocalRuntime("dev.architectury:architectury-fabric:${architectury_api_version}") 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 c0b568a8..7380c260 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 @@ -160,34 +160,6 @@ public final class AntarchyFabric implements ModInitializer { Antarchy.init(); BloodCrystalShardItem.SYNC_BLOODGLASS = BloodglassManager::syncBloodglass; registerTradeReloadListener(); - ResourceManagerHelper.get(PackType.SERVER_DATA).registerReloadListener(new IdentifiableResourceReloadListener() { - @Override - public ResourceLocation getFabricId() { - return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "computer_guide"); - } - - @Override - public CompletableFuture reload(PreparableReloadListener.PreparationBarrier barrier, ResourceManager manager, - ProfilerFiller prepareProfiler, ProfilerFiller applyProfiler, - Executor prepareExecutor, Executor applyExecutor) { - return com.craisinlord.antarchy.content.guide.ComputerGuideData.instance().reload( - barrier, manager, prepareProfiler, applyProfiler, prepareExecutor, applyExecutor); - } - }); - ResourceManagerHelper.get(PackType.SERVER_DATA).registerReloadListener(new IdentifiableResourceReloadListener() { - @Override - public ResourceLocation getFabricId() { - return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antmail_events"); - } - - @Override - public CompletableFuture reload(PreparableReloadListener.PreparationBarrier barrier, ResourceManager manager, - ProfilerFiller prepareProfiler, ProfilerFiller applyProfiler, - Executor prepareExecutor, Executor applyExecutor) { - return com.craisinlord.antarchy.content.antmail.AntmailEventData.instance().reload( - barrier, manager, prepareProfiler, applyProfiler, prepareExecutor, applyExecutor); - } - }); ResourceManagerHelper.get(PackType.SERVER_DATA).registerReloadListener(new IdentifiableResourceReloadListener() { @Override public ResourceLocation getFabricId() { @@ -233,6 +205,20 @@ public final class AntarchyFabric implements ModInitializer { return computerScientistDelegate.reload(barrier, manager, prepareProfiler, applyProfiler, prepareExecutor, applyExecutor); } }); + com.craisinlord.antarchy.content.entity.trades.PestControlTradeManager pestControlDelegate = new com.craisinlord.antarchy.content.entity.trades.PestControlTradeManager(); + ResourceManagerHelper.get(PackType.SERVER_DATA).registerReloadListener(new IdentifiableResourceReloadListener() { + @Override + public ResourceLocation getFabricId() { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "pest_control_trades"); + } + + @Override + public CompletableFuture reload(PreparableReloadListener.PreparationBarrier barrier, ResourceManager manager, + ProfilerFiller prepareProfiler, ProfilerFiller applyProfiler, + Executor prepareExecutor, Executor applyExecutor) { + return pestControlDelegate.reload(barrier, manager, prepareProfiler, applyProfiler, prepareExecutor, applyExecutor); + } + }); } private static final TagKey CAVARYN_BIOMES = TagKey.create( 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 44df8be9..23514f50 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 @@ -229,6 +229,10 @@ public final class AntarchyFabricContent { AntarchyFabricSounds.MANTIS_HURT, AntarchyFabricSounds.MANTIS_ATTACK, AntarchyFabricSounds.MANTIS_FLY_LOOP, + AntarchyFabricSounds.MANTICORE_IDLE, + AntarchyFabricSounds.MANTICORE_WALK, + AntarchyFabricSounds.MANTICORE_FLY, + AntarchyFabricSounds.MANTICORE_BITE, AntarchyFabricSounds.GRAVITY_GUN_PICKUP, AntarchyFabricSounds.GRAVITY_GUN_DROP, AntarchyFabricSounds.GRAVITY_GUN_HOLD_LOOP, @@ -352,6 +356,7 @@ public final class AntarchyFabricContent { AntarchyFabricSounds.DIMENSIONAL_TEAR_CREATURE_LEAVES, AntarchyFabricSounds.DIMENSIONAL_TEAR_CLOSE ); + AntarchySoundEvents.bindHoverboardSounds(AntarchyFabricSounds.HOVERBOARD_MOUNT, AntarchyFabricSounds.HOVERBOARD_DISMOUNT, AntarchyFabricSounds.HOVERBOARD_IDLE); AntarchyObjects.setOctopusBomb(AntarchyFabricEntities.OCTOPUS_BOMB); AntarchyObjects.setTentacle(AntarchyFabricEntities.TENTACLE); @@ -402,10 +407,6 @@ public final class AntarchyFabricContent { AntarchyObjects.setCookedCorndog(() -> AntarchyFabricItems.COOKED_CORNDOG.get()); AntarchyObjects.setGlimmerBottle(() -> AntarchyFabricItems.GLIMMER_BOTTLE.get()); AntarchyObjects.setGlimmerVariantComponent(() -> AntarchyFabricMisc.GLIMMER_VARIANT.get()); - AntarchyObjects.setFloppyDiskComponent(() -> AntarchyFabricMisc.FLOPPY_DISK_COMPONENT.get()); - AntarchyObjects.setFloppyDisk(() -> AntarchyFabricItems.FLOPPY_DISK.get()); - AntarchyObjects.setComputer(() -> AntarchyFabricBlocks.COMPUTER.get()); - AntarchyObjects.setComputerBlockEntity(() -> AntarchyFabricBlocks.COMPUTER_BLOCK_ENTITY.get()); AntarchyObjects.setAmericanComponent(() -> AntarchyFabricMisc.AMERICAN.get()); AntarchyObjects.setLumen(() -> AntarchyFabricMisc.LUMEN.get()); AntarchyObjects.setFlowingLumen(() -> AntarchyFabricMisc.FLOWING_LUMEN.get()); @@ -414,6 +415,7 @@ public final class AntarchyFabricContent { AntarchyObjects.setLumenFroglight(() -> AntarchyFabricBlocks.LUMEN_FROGLIGHT.get()); AntarchyObjects.setGlimmeringReed(() -> AntarchyFabricBlocks.GLIMMERING_REED.get()); AntarchyObjects.setPeachLeavesParticle(() -> AntarchyFabricMisc.PEACH_LEAVES_PARTICLE.get()); + AntarchyObjects.setBugSprayParticle(() -> AntarchyFabricMisc.BUG_SPRAY_PARTICLE.get()); AntarchyObjects.setLotusPollen(() -> AntarchyFabricMisc.LOTUS_POLLEN.get()); AntarchyObjects.setNightmareFireFlame(() -> AntarchyFabricMisc.NIGHTMARE_FIRE_FLAME.get()); AntarchyObjects.setLucidBoltImpactSmall(() -> AntarchyFabricMisc.LUCID_BOLT_IMPACT_SMALL.get()); 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 ae9fa330..7ac5117e 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 @@ -189,8 +189,6 @@ public final class AntarchyFabricEvents { }); ServerTickEvents.END_SERVER_TICK.register(server -> { - com.craisinlord.antarchy.content.antmail.AntmailServerData.access(server).drainAvailable(server); - com.craisinlord.antarchy.content.antmail.AntmailEventData.onTick(server); Set activeThisTick = new HashSet<>(); for (ServerLevel level : server.getAllLevels()) { CavarynHordeManager.tick(level); @@ -221,6 +219,15 @@ public final class AntarchyFabricEvents { factories -> factories.add(ComputerScientistTradeManager.listing(tradeLevel, tradeIndex))); } } + int[] pestControlSlots = com.craisinlord.antarchy.content.entity.trades.PestControlTradeManager.slotsPerLevel(); + for (int level = 1; level <= pestControlSlots.length; level++) { + final int tradeLevel = level; + for (int index = 0; index < pestControlSlots[level - 1]; index++) { + final int tradeIndex = index; + TradeOfferHelper.registerVillagerOffers(AntarchyFabricMisc.PEST_CONTROL.get(), tradeLevel, + factories -> factories.add(com.craisinlord.antarchy.content.entity.trades.PestControlTradeManager.listing(tradeLevel, tradeIndex))); + } + } TradeOfferHelper.registerVillagerOffers(VillagerProfession.FARMER, 1, factories -> factories.add((trader, random) -> new MerchantOffer( new ItemCost(AntarchyFabricItems.CORN.get(), 20), diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java index a1f3f6b7..dbccf137 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java @@ -1,8 +1,7 @@ package com.craisinlord.antarchy.fabric.client; import com.craisinlord.antarchy.Antarchy; -import com.craisinlord.antarchy.content.client.AntarchyClientHooks; -import com.craisinlord.antarchy.content.client.screen.ComputerScreen; +import com.craisinlord.antarchy.content.client.game.AntarchyComputerGames; import com.craisinlord.antarchy.fabric.network.AntarchyFabricClientNetworking; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; @@ -12,7 +11,6 @@ import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.resources.PreparableReloadListener; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.client.Minecraft; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; @@ -23,7 +21,15 @@ public final class AntarchyFabricClient implements ClientModInitializer { AntarchyFabricClientNetworking.register(); AntarchyFabricClientNetworking.bootstrapMultipartClient(); AntarchyFabricClientBootstrap.register(); - AntarchyClientHooks.setComputerOpener(pos -> Minecraft.getInstance().setScreen(new ComputerScreen(pos))); + AntarchyComputerGames.register(); + ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new IdentifiableResourceReloadListener() { + @Override public ResourceLocation getFabricId() { return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "antos_computer_data"); } + @Override public CompletableFuture reload(PreparableReloadListener.PreparationBarrier barrier, ResourceManager manager, + ProfilerFiller prepareProfiler, ProfilerFiller applyProfiler, Executor prepareExecutor, Executor applyExecutor) { + return com.craisinlord.antos.content.guide.ComputerGuideData.instance().reload( + barrier, manager, prepareProfiler, applyProfiler, prepareExecutor, applyExecutor); + } + }); ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new IdentifiableResourceReloadListener() { @Override public ResourceLocation getFabricId() { 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 cdba72f8..d5d4d020 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 @@ -103,10 +103,6 @@ public final class AntarchyFabricClientBootstrap { (net.minecraft.world.level.block.entity.BlockEntityType) AntarchyFabricBlocks.UNDERVAULT_BLOCK_ENTITY.get(), (BlockEntityRendererProvider) UnderVaultRenderer::new ); - BlockEntityRendererRegistry.register( - (net.minecraft.world.level.block.entity.BlockEntityType) AntarchyFabricBlocks.COMPUTER_BLOCK_ENTITY.get(), - (BlockEntityRendererProvider) ComputerRenderer::new - ); EntityRendererRegistry.register(AntarchyFabricEntities.EASTER_BUNNY.get(), context -> withTemporalGeoLayer(new EasterBunnyRenderer(context))); EntityRendererRegistry.register(AntarchyFabricEntities.FLYING_SQUIRREL.get(), context -> withTemporalGeoLayer(new FlyingSquirrelRenderer(context))); @@ -205,7 +201,7 @@ public final class AntarchyFabricClientBootstrap { EntityModelLayerRegistry.registerModelLayer(PeachBoatRenderer.chestBoatLayer(), ChestBoatModel::createBodyModel); } - private static > R withTemporalGeoLayer(R renderer) { + private static > R withTemporalGeoLayer(R renderer) { renderer.addRenderLayer(new TemporalContractionGeoLayer<>(renderer)); return renderer; } @@ -328,6 +324,7 @@ public final class AntarchyFabricClientBootstrap { registry.register(AntarchyFabricMisc.STINKY_GAS.get(), HypnoticGasParticle.Provider::new); registry.register(AntarchyFabricMisc.STINKY_FLY.get(), FireflyParticle.Provider::new); registry.register(AntarchyFabricMisc.PEACH_LEAVES_PARTICLE.get(), PeachLeavesParticle.Provider::new); + registry.register(AntarchyFabricMisc.BUG_SPRAY_PARTICLE.get(), com.craisinlord.antarchy.content.client.particle.BugSprayParticle.Provider::new); registry.register(AntarchyFabricMisc.LOTUS_POLLEN.get(), com.craisinlord.antarchy.content.client.particle.LotusPollenParticle.Provider::new); registry.register(AntarchyFabricMisc.HYPNOTIC_GAS.get(), HypnoticGasParticle.Provider::new); registry.register(AntarchyFabricMisc.HYPNOTIC_GAS_DOWN.get(), sprites -> new HypnoticGasParticle.Provider(sprites, true)); @@ -516,11 +513,6 @@ public final class AntarchyFabricClientBootstrap { return cage.getItemState(stack); } ); - ItemProperties.register( - AntarchyFabricItems.FLOPPY_DISK.get(), - ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "disk_category"), - (stack, level, entity, seed) -> com.craisinlord.antarchy.content.item.FloppyDiskItem.categoryModelProperty(stack) - ); } @SuppressWarnings({"unchecked", "rawtypes"}) diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/BigBerthaClientHandler.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/BigBerthaClientHandler.java index 0a3cd5d3..85c90ef5 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/BigBerthaClientHandler.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/BigBerthaClientHandler.java @@ -1,7 +1,9 @@ package com.craisinlord.antarchy.fabric.client; import com.craisinlord.antarchy.content.item.BigBerthaItem; +import com.craisinlord.antarchy.content.item.RoyalGuardianSwordItem; import com.craisinlord.antarchy.content.network.BigBerthaModeCyclePayload; +import com.craisinlord.antarchy.content.network.RoyalGuardianSwordModeCyclePayload; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.minecraft.client.Minecraft; @@ -22,7 +24,9 @@ public final class BigBerthaClientHandler { return; } - if (!(mc.player.getMainHandItem().getItem() instanceof BigBerthaItem)) { + boolean bigBertha = mc.player.getMainHandItem().getItem() instanceof BigBerthaItem; + boolean royalGuardianSword = mc.player.getMainHandItem().getItem() instanceof RoyalGuardianSwordItem; + if (!bigBertha && !royalGuardianSword) { lastUseDown = false; return; } @@ -31,8 +35,9 @@ public final class BigBerthaClientHandler { if (useDown && !lastUseDown && mc.player.isShiftKeyDown() - && mc.player.getCooldowns().isOnCooldown(mc.player.getMainHandItem().getItem())) { - ClientPlayNetworking.send(new BigBerthaModeCyclePayload()); + ) { + if (bigBertha) ClientPlayNetworking.send(new BigBerthaModeCyclePayload()); + else ClientPlayNetworking.send(new RoyalGuardianSwordModeCyclePayload()); } lastUseDown = useDown; } diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricClientNetworking.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricClientNetworking.java index 656e5566..165a2527 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricClientNetworking.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricClientNetworking.java @@ -36,12 +36,9 @@ public final class AntarchyFabricClientNetworking { } public static void register() { - ClientPlayNetworking.registerGlobalReceiver(AntmailResultPayload.TYPE, (payload, context) -> - context.client().execute(() -> com.craisinlord.antarchy.content.client.AntmailClientState.update(payload))); - ClientPlayNetworking.registerGlobalReceiver(ComputerAccessResultPayload.TYPE, (payload, context) -> - context.client().execute(() -> com.craisinlord.antarchy.content.client.ComputerAccessClientState.update(payload))); - com.craisinlord.antarchy.content.network.ComputerNetworking.setSender(ServerPlayNetworking::send); - com.craisinlord.antarchy.content.network.AntmailNetworking.setSender(ServerPlayNetworking::send); + ClientPlayNetworking.registerGlobalReceiver(AntarchyGameResultPayload.TYPE, (payload, context) -> + context.client().execute(() -> com.craisinlord.antarchy.content.client.AntarchyGameClientState.update(payload))); + com.craisinlord.antarchy.content.network.AntarchyGameNetworking.setSender(ClientPlayNetworking::send); ClientPlayNetworking.registerGlobalReceiver(GravityStatePayload.TYPE, (payload, context) -> context.client().execute(() -> AntarchyFabricNetworking.handleGravityState(context.player(), payload))); ClientPlayNetworking.registerGlobalReceiver(BloodglassStatePayload.TYPE, (payload, context) -> diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java index ded60b8c..58626021 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java @@ -49,9 +49,7 @@ public final class AntarchyFabricNetworking { public static void register() { registerPayloadTypes(); registerServerReceivers(); - com.craisinlord.antarchy.content.network.ComputerAccessHandler.setResultSender(ServerPlayNetworking::send); - com.craisinlord.antarchy.content.network.AntmailServerHandler.setResultSender(ServerPlayNetworking::send); - com.craisinlord.antarchy.content.network.ComputerNetworking.setSender(ServerPlayNetworking::send); + com.craisinlord.antarchy.content.network.AntarchyGameNetworkHandler.setResultSender(ServerPlayNetworking::send); } public static void bootstrapMultipartCommon() { @@ -75,8 +73,7 @@ public final class AntarchyFabricNetworking { } private static void registerPayloadTypes() { - PayloadTypeRegistry.playS2C().register(ComputerAccessResultPayload.TYPE, ComputerAccessResultPayload.STREAM_CODEC); - PayloadTypeRegistry.playS2C().register(AntmailResultPayload.TYPE, AntmailResultPayload.STREAM_CODEC); + PayloadTypeRegistry.playS2C().register(AntarchyGameResultPayload.TYPE, AntarchyGameResultPayload.STREAM_CODEC); PayloadTypeRegistry.playS2C().register(GravityStatePayload.TYPE, GravityStatePayload.STREAM_CODEC); PayloadTypeRegistry.playS2C().register(BloodglassStatePayload.TYPE, BloodglassStatePayload.STREAM_CODEC); PayloadTypeRegistry.playS2C().register(TigerEyeCamouflageStatePayload.TYPE, TigerEyeCamouflageStatePayload.STREAM_CODEC); @@ -97,6 +94,8 @@ public final class AntarchyFabricNetworking { PayloadTypeRegistry.playC2S().register(RoyalMountVerticalPayload.TYPE, RoyalMountVerticalPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(GravityGunScrollPayload.TYPE, GravityGunScrollPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(BigBerthaModeCyclePayload.TYPE, BigBerthaModeCyclePayload.STREAM_CODEC); + PayloadTypeRegistry.playC2S().register(com.craisinlord.antarchy.content.network.RoyalGuardianSwordModeCyclePayload.TYPE, + com.craisinlord.antarchy.content.network.RoyalGuardianSwordModeCyclePayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(ToggleTigerEyeCamouflagePayload.TYPE, ToggleTigerEyeCamouflagePayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(ToggleRoyalInversionPayload.TYPE, ToggleRoyalInversionPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(com.craisinlord.antarchy.content.network.ActivateRoyalBoundaryPayload.TYPE, com.craisinlord.antarchy.content.network.ActivateRoyalBoundaryPayload.STREAM_CODEC); @@ -111,36 +110,12 @@ public final class AntarchyFabricNetworking { PayloadTypeRegistry.playC2S().register(HerculesBeetleMountedChargePayload.TYPE, HerculesBeetleMountedChargePayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(MultipartAttackPayload.TYPE, MultipartAttackPayload.STREAM_CODEC); PayloadTypeRegistry.playC2S().register(MultipartInteractPayload.TYPE, MultipartInteractPayload.STREAM_CODEC); - PayloadTypeRegistry.playC2S().register(ComputerAccessPayload.TYPE, ComputerAccessPayload.STREAM_CODEC); - PayloadTypeRegistry.playC2S().register(AntmailSetupPayload.TYPE, AntmailSetupPayload.STREAM_CODEC); - PayloadTypeRegistry.playC2S().register(AntmailStateRequestPayload.TYPE, AntmailStateRequestPayload.STREAM_CODEC); - PayloadTypeRegistry.playC2S().register(AntmailMessageRequestPayload.TYPE, AntmailMessageRequestPayload.STREAM_CODEC); - PayloadTypeRegistry.playC2S().register(AntmailSendPayload.TYPE, AntmailSendPayload.STREAM_CODEC); - PayloadTypeRegistry.playC2S().register(AntmailReadPayload.TYPE, AntmailReadPayload.STREAM_CODEC); - PayloadTypeRegistry.playC2S().register(AntmailDeletePayload.TYPE, AntmailDeletePayload.STREAM_CODEC); - PayloadTypeRegistry.playC2S().register(AntmailDraftPayload.TYPE, AntmailDraftPayload.STREAM_CODEC); - PayloadTypeRegistry.playC2S().register(AntmailRetryPayload.TYPE, AntmailRetryPayload.STREAM_CODEC); + PayloadTypeRegistry.playC2S().register(AntarchyGamePayload.TYPE, AntarchyGamePayload.STREAM_CODEC); } private static void registerServerReceivers() { - ServerPlayNetworking.registerGlobalReceiver(ComputerAccessPayload.TYPE, (payload, context) -> - context.server().execute(() -> ComputerAccessHandler.handle(context.player(), payload))); - ServerPlayNetworking.registerGlobalReceiver(AntmailSetupPayload.TYPE, (payload, context) -> - context.server().execute(() -> AntmailServerHandler.handle(context.player(), payload))); - ServerPlayNetworking.registerGlobalReceiver(AntmailStateRequestPayload.TYPE, (payload, context) -> - context.server().execute(() -> AntmailServerHandler.handle(context.player(), payload))); - ServerPlayNetworking.registerGlobalReceiver(AntmailMessageRequestPayload.TYPE, (payload, context) -> - context.server().execute(() -> AntmailServerHandler.handle(context.player(), payload))); - ServerPlayNetworking.registerGlobalReceiver(AntmailSendPayload.TYPE, (payload, context) -> - context.server().execute(() -> AntmailServerHandler.handle(context.player(), payload))); - ServerPlayNetworking.registerGlobalReceiver(AntmailReadPayload.TYPE, (payload, context) -> - context.server().execute(() -> AntmailServerHandler.handle(context.player(), payload))); - ServerPlayNetworking.registerGlobalReceiver(AntmailDeletePayload.TYPE, (payload, context) -> - context.server().execute(() -> AntmailServerHandler.handle(context.player(), payload))); - ServerPlayNetworking.registerGlobalReceiver(AntmailDraftPayload.TYPE, (payload, context) -> - context.server().execute(() -> AntmailServerHandler.handle(context.player(), payload))); - ServerPlayNetworking.registerGlobalReceiver(AntmailRetryPayload.TYPE, (payload, context) -> - context.server().execute(() -> AntmailServerHandler.handle(context.player(), payload))); + ServerPlayNetworking.registerGlobalReceiver(AntarchyGamePayload.TYPE, (payload, context) -> + context.server().execute(() -> AntarchyGameNetworkHandler.handle(context.player(), payload))); ServerPlayNetworking.registerGlobalReceiver(GravityGunPrimaryPayload.TYPE, (payload, context) -> context.server().execute(() -> handleGravityGunPrimary(context.player(), payload))); ServerPlayNetworking.registerGlobalReceiver(PortalGunPrimaryPayload.TYPE, (payload, context) -> @@ -155,6 +130,8 @@ public final class AntarchyFabricNetworking { context.server().execute(() -> handleGravityGunScroll(context.player(), payload))); ServerPlayNetworking.registerGlobalReceiver(BigBerthaModeCyclePayload.TYPE, (payload, context) -> context.server().execute(() -> handleBigBerthaModeCycle(context.player(), payload))); + ServerPlayNetworking.registerGlobalReceiver(com.craisinlord.antarchy.content.network.RoyalGuardianSwordModeCyclePayload.TYPE, + (payload, context) -> context.server().execute(() -> handleRoyalGuardianSwordModeCycle(context.player()))); ServerPlayNetworking.registerGlobalReceiver(ToggleTigerEyeCamouflagePayload.TYPE, (payload, context) -> context.server().execute(() -> handleTigerEyeCamouflageToggle(context.player()))); ServerPlayNetworking.registerGlobalReceiver(ToggleRoyalInversionPayload.TYPE, (payload, context) -> @@ -322,7 +299,14 @@ public final class AntarchyFabricNetworking { if (!(player.getMainHandItem().getItem() instanceof BigBerthaItem bigBerthaItem)) { return; } - bigBerthaItem.tryCycleModeWhileCoolingDown(player.serverLevel(), player, player.getMainHandItem()); + bigBerthaItem.tryCycleModeFromInput(player.serverLevel(), player, player.getMainHandItem()); + } + + private static void handleRoyalGuardianSwordModeCycle(ServerPlayer player) { + if (!(player.getMainHandItem().getItem() instanceof com.craisinlord.antarchy.content.item.RoyalGuardianSwordItem sword)) { + return; + } + sword.tryCycleModeFromInput(player.serverLevel(), player, player.getMainHandItem()); } private static void handleDiamondMinecartInput(ServerPlayer player, DiamondMinecartInputPayload payload) { diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricBlocks.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricBlocks.java index b10eb392..391615cc 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricBlocks.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricBlocks.java @@ -6,7 +6,6 @@ import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.block.*; import com.craisinlord.antarchy.content.block.entity.AntNestBlockEntity; import com.craisinlord.antarchy.content.block.entity.CritterCageBlockEntity; -import com.craisinlord.antarchy.content.block.entity.ComputerBlockEntity; import com.craisinlord.antarchy.content.block.entity.DreamCampfireBlockEntity; import com.craisinlord.antarchy.content.block.entity.HushweedBlockEntity; import com.craisinlord.antarchy.content.block.entity.LucidAnchorBlockEntity; @@ -1066,6 +1065,11 @@ public final class AntarchyFabricBlocks { public static final DeferredBlock TERMITE_NEST = BLOCKS.register("termite_nest", () -> new AntNestBlock(AntarchyFabricEntities.TERMITE, AntarchyFabricBlocks::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.DIRT).noLootTable())); + public static final DeferredBlock ANT_TRAP = BLOCKS.register("ant_trap", + () -> new com.craisinlord.antarchy.content.block.AntTrapBlock( + () -> java.util.List.of(AntarchyFabricEntities.RED_ANT.get(), AntarchyFabricEntities.BROWN_ANT.get(), AntarchyFabricEntities.RAINBOW_ANT.get(), AntarchyFabricEntities.TERMITE.get()), + AntarchyFabricBlocks::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_PRESSURE_PLATE).noOcclusion())); + public static final DeferredBlock URANIUM_ORE = BLOCKS.register("uranium_ore", () -> createOre(Blocks.EMERALD_ORE, 4, 8, MapColor.COLOR_YELLOW)); @@ -1212,8 +1216,6 @@ public final class AntarchyFabricBlocks { public static final DeferredBlock UPPER = BLOCKS.register("upper", () -> new UpperBlock(AntarchyFabricBlocks::upperBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.HOPPER))); - public static final DeferredBlock COMPUTER = BLOCKS.register("computer", - () -> new com.craisinlord.antarchy.content.block.ComputerBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.IRON_BLOCK).noOcclusion())); public static final DeferredBlock ANTIMETAL_RAIL = BLOCKS.register("antimetal_rail", () -> new com.craisinlord.antarchy.content.block.AntimetalRailBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.RAIL))); @@ -1456,7 +1458,8 @@ public final class AntarchyFabricBlocks { RED_ANT_NEST.get(), BROWN_ANT_NEST.get(), RAINBOW_ANT_NEST.get(), - TERMITE_NEST.get() + TERMITE_NEST.get(), + ANT_TRAP.get() ).build(null)); @@ -1531,11 +1534,6 @@ public final class AntarchyFabricBlocks { (pos, state) -> new DimensionalTearMarkerBlockEntity(pos, state, AntarchyFabricBlocks::dimensionalTearMarkerBlockEntityType), DIMENSIONAL_TEAR_MARKER.get() ).build(null)); - public static final DeferredHolder, BlockEntityType> COMPUTER_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("computer", - () -> BlockEntityType.Builder.of( - (pos, state) -> new ComputerBlockEntity(pos, state, AntarchyFabricBlocks::computerBlockEntityType), - COMPUTER.get() - ).build(null)); public static final DeferredHolder, BlockEntityType> QUEEN_TRAIL_SPAWN_MARKER_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("queen_trail_spawn_marker", () -> BlockEntityType.Builder.of( (pos, state) -> new QueenTrailSpawnMarkerBlockEntity(pos, state, AntarchyFabricBlocks::queenTrailSpawnMarkerBlockEntityType), @@ -1576,10 +1574,6 @@ public final class AntarchyFabricBlocks { return UPPER_BLOCK_ENTITY.get(); } - private static BlockEntityType computerBlockEntityType() { - return COMPUTER_BLOCK_ENTITY.get(); - } - private static BlockEntityType vortexLensBlockEntityType() { return VORTEX_LENS_BLOCK_ENTITY.get(); } 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 e3062ff3..1d4cfde0 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 @@ -86,7 +86,6 @@ public final class AntarchyFabricItems { public static final DeferredItem NIGHTMARE_SCALE = ITEMS.registerSimpleItem("nightmare_scale", new Item.Properties().rarity(Rarity.RARE).fireResistant()); - public static final DeferredItem FLOPPY_DISK = ITEMS.register("floppy_disk", () -> new com.craisinlord.antarchy.content.item.FloppyDiskItem(new Item.Properties())); public static final DeferredItem MUSIC_DISC_UNDERSIDE = ITEMS.registerSimpleItem("music_disc_underside", new Item.Properties().stacksTo(1).rarity(Rarity.RARE) @@ -100,8 +99,6 @@ public final class AntarchyFabricItems { public static final DeferredItem DUPLICATOR_LOG_ITEM = ITEMS.registerSimpleBlockItem(AntarchyFabricBlocks.DUPLICATOR_LOG); - public static final DeferredItem COMPUTER_ITEM = ITEMS.register("computer", - () -> new ComputerItem(AntarchyFabricBlocks.COMPUTER.get(), new Item.Properties())); public static final DeferredItem OURANWOOD_LOG_ITEM = ITEMS.registerSimpleBlockItem(AntarchyFabricBlocks.OURANWOOD_LOG); @@ -509,6 +506,11 @@ public final class AntarchyFabricItems { public static final DeferredItem RAINBOW_ANT_NEST_ITEM = ITEMS.registerSimpleBlockItem(AntarchyFabricBlocks.RAINBOW_ANT_NEST); public static final DeferredItem TERMITE_NEST_ITEM = ITEMS.registerSimpleBlockItem(AntarchyFabricBlocks.TERMITE_NEST); + public static final DeferredItem ANT_TRAP_ITEM = ITEMS.registerSimpleBlockItem(AntarchyFabricBlocks.ANT_TRAP); + + public static final DeferredItem BUG_SPRAY = ITEMS.register("bug_spray", + () -> new com.craisinlord.antarchy.content.item.BugSprayItem(new Item.Properties().stacksTo(16))); + public static final DeferredItem URANIUM_ORE_ITEM = ITEMS.registerSimpleBlockItem(AntarchyFabricBlocks.URANIUM_ORE, new Item.Properties().rarity(Rarity.UNCOMMON)); 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 9066e779..f7d3b19a 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 @@ -135,7 +135,7 @@ public final class AntarchyFabricMisc { public static final DeferredHolder COMPUTER_POI = POI_TYPES.register("computer", () -> new PoiType( - java.util.Set.copyOf(AntarchyFabricBlocks.COMPUTER.get().getStateDefinition().getPossibleStates()), + java.util.Set.copyOf(net.minecraft.world.level.block.Block.byItem(com.craisinlord.antos.content.AntOSObjects.COMPUTER_ITEM.get()).getStateDefinition().getPossibleStates()), 1, 1)); @@ -148,6 +148,13 @@ public final class AntarchyFabricMisc { com.google.common.collect.ImmutableSet.of(), SoundEvents.VILLAGER_WORK_LIBRARIAN)); + public static final DeferredHolder PEST_CONTROL_POI = POI_TYPES.register("pest_control", + () -> new PoiType(java.util.Set.copyOf(AntarchyFabricBlocks.ANT_TRAP.get().getStateDefinition().getPossibleStates()), 1, 1)); + + public static final DeferredHolder PEST_CONTROL = VILLAGER_PROFESSIONS.register("pest_control", + () -> new VillagerProfession("pest_control", holder -> holder.value() == PEST_CONTROL_POI.get(), + holder -> holder.value() == PEST_CONTROL_POI.get(), com.google.common.collect.ImmutableSet.of(), com.google.common.collect.ImmutableSet.of(), SoundEvents.VILLAGER_WORK_FLETCHER)); + public static final DeferredRegister ARMOR_MATERIALS = DeferredRegister.create(Registries.ARMOR_MATERIAL, Antarchy.MODID); @@ -212,13 +219,6 @@ public final class AntarchyFabricMisc { .networkSynchronized(com.craisinlord.antarchy.content.entity.glimmer.GlimmerVariant.STREAM_CODEC) .build()); - public static final DeferredHolder, net.minecraft.core.component.DataComponentType> FLOPPY_DISK_COMPONENT = - DATA_COMPONENT_TYPES.register("floppy_disk", - () -> net.minecraft.core.component.DataComponentType.builder() - .persistent(net.minecraft.resources.ResourceLocation.CODEC) - .networkSynchronized(net.minecraft.resources.ResourceLocation.STREAM_CODEC) - .build()); - public static final DeferredHolder, net.minecraft.core.component.DataComponentType> AMERICAN = DATA_COMPONENT_TYPES.register("american", @@ -358,6 +358,8 @@ public final class AntarchyFabricMisc { public static final DeferredHolder, SimpleParticleType> DREAM_FIRE_FLAME = PARTICLE_TYPES.register("dream_fire_flame", () -> simpleParticleType()); + public static final DeferredHolder, SimpleParticleType> BUG_SPRAY_PARTICLE = PARTICLE_TYPES.register("bug_spray", + () -> simpleParticleType()); public static final DeferredHolder, SimpleParticleType> NIGHTMARE_FIRE_FLAME = PARTICLE_TYPES.register("nightmare_fire_flame", () -> simpleParticleType()); diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSounds.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSounds.java index 29eb0a49..dfdc91bb 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSounds.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSounds.java @@ -305,6 +305,14 @@ public final class AntarchyFabricSounds { public static final DeferredHolder MANTIS_FLY_LOOP = registerSoundEvent("mantis_fly_loop"); + public static final DeferredHolder MANTICORE_IDLE = registerSoundEvent("manticore_idle"); + + public static final DeferredHolder MANTICORE_WALK = registerSoundEvent("manticore_walk"); + + public static final DeferredHolder MANTICORE_FLY = registerSoundEvent("manticore_fly"); + + public static final DeferredHolder MANTICORE_BITE = registerSoundEvent("manticore_bite"); + public static final DeferredHolder GRAVITY_GUN_PICKUP = registerSoundEvent("gravity_gun_pickup"); @@ -576,6 +584,9 @@ public final class AntarchyFabricSounds { public static final DeferredHolder PRINCESS_SHOOT = registerSoundEvent("princess_shoot"); public static final DeferredHolder PRINCESS_FLY = registerSoundEvent("princess_fly"); public static final DeferredHolder PRINCESS_STEP = registerSoundEvent("princess_step"); + public static final DeferredHolder HOVERBOARD_MOUNT = registerSoundEvent("hoverboard_mount"); + public static final DeferredHolder HOVERBOARD_DISMOUNT = registerSoundEvent("hoverboard_dismount"); + public static final DeferredHolder HOVERBOARD_IDLE = registerSoundEvent("hoverboard_idle"); diff --git a/fabric-1.21.1/src/main/resources/fabric.mod.json b/fabric-1.21.1/src/main/resources/fabric.mod.json index 03dbd314..ec2c4832 100644 --- a/fabric-1.21.1/src/main/resources/fabric.mod.json +++ b/fabric-1.21.1/src/main/resources/fabric.mod.json @@ -35,6 +35,7 @@ "minecraft": "~${minecraft_version}", "java": ">=21", "fabric-api": "*", + "antos": "*", "integrated_api": "*", "geckolib": "*", "sizeable_foliage": "*" diff --git a/neoforge-1.21.1/build.gradle b/neoforge-1.21.1/build.gradle index 593a1e7b..365eadf6 100644 --- a/neoforge-1.21.1/build.gradle +++ b/neoforge-1.21.1/build.gradle @@ -46,6 +46,9 @@ neoForge { } dependencies { + // AntOS is developed beside Antarchy as a separate local project. + compileOnly(files("$rootDir/../AntOS/neoforge-1.21.1/build/libs/antos-neoforge-1.21.1-0.1.0.jar")) + runtimeOnly(files("$rootDir/../AntOS/neoforge-1.21.1/build/libs/antos-neoforge-1.21.1-0.1.0.jar")) compileOnly("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_neoforge}") runtimeOnly("curse.maven:intapi-${intapi_curseforge_id}:${intapi_curseforge_file_id_neoforge}") implementation "software.bernie.geckolib:geckolib-neoforge-1.21.1:${geckolib_version}" 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 ca44e19c..66422232 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 @@ -701,14 +701,14 @@ public final class AntarchyMobsConfig { b.push("royalMounts"); ROYAL_EGG_HATCH_CHANCE = b.comment("Chance denominator for a royal egg advancing one hatch stage on a random tick.").defineInRange("eggHatchChance", 3, 1, 100000); ROYAL_BOLT_DAMAGE = b.comment("Direct damage dealt by a Prince or Princess royal bolt.").defineInRange("boltDamage", 6.0D, 0.0D, 1024.0D); - PRINCE_HEALTH = b.comment("Prince base max health.").defineInRange("princeHealth", 120.0D, 1.0D, 32768.0D); + PRINCE_HEALTH = b.comment("Prince base max health.").defineInRange("princeHealth", 360.0D, 1.0D, 32768.0D); PRINCE_ATTACK_DAMAGE = b.comment("Prince bite damage.").defineInRange("princeAttackDamage", 14.0D, 0.0D, 1024.0D); PRINCE_MOVEMENT_SPEED = b.comment("Prince grounded movement speed.").defineInRange("princeMovementSpeed", 0.28D, 0.0D, 10.0D); PRINCE_FLYING_SPEED = b.comment("Prince flying movement speed.").defineInRange("princeFlyingSpeed", 0.9D, 0.0D, 10.0D); PRINCE_ARMOR = b.comment("Prince armor value.").defineInRange("princeArmor", 10.0D, 0.0D, 1024.0D); PRINCE_KNOCKBACK_RESISTANCE = b.comment("Prince knockback resistance.").defineInRange("princeKnockbackResistance", 0.6D, 0.0D, 1.0D); PRINCE_FOLLOW_RANGE = b.comment("Prince owner and target range.").defineInRange("princeFollowRange", 48.0D, 1.0D, 256.0D); - PRINCESS_HEALTH = b.comment("Princess base max health.").defineInRange("princessHealth", 110.0D, 1.0D, 32768.0D); + PRINCESS_HEALTH = b.comment("Princess base max health.").defineInRange("princessHealth", 330.0D, 1.0D, 32768.0D); PRINCESS_ATTACK_DAMAGE = b.comment("Princess bite damage.").defineInRange("princessAttackDamage", 10.0D, 0.0D, 1024.0D); PRINCESS_MOVEMENT_SPEED = b.comment("Princess grounded movement speed.").defineInRange("princessMovementSpeed", 0.28D, 0.0D, 10.0D); PRINCESS_FLYING_SPEED = b.comment("Princess flying movement speed.").defineInRange("princessFlyingSpeed", 0.95D, 0.0D, 10.0D); 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 3882d215..49770204 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 @@ -247,6 +247,7 @@ public class AntarchyNeoforge { AntarchyNeoforgeSounds.DIMENSIONAL_TEAR_CREATURE_LEAVES, AntarchyNeoforgeSounds.DIMENSIONAL_TEAR_CLOSE ); + AntarchySoundEvents.bindHoverboardSounds(AntarchyNeoforgeSounds.HOVERBOARD_MOUNT, AntarchyNeoforgeSounds.HOVERBOARD_DISMOUNT, AntarchyNeoforgeSounds.HOVERBOARD_IDLE); bindCommonObjects(); ScorpionWhipTetherSync.setSink((player, targetId) -> PacketDistributor.sendToPlayersTrackingEntityAndSelf( player, @@ -288,13 +289,9 @@ public class AntarchyNeoforge { AntarchyNeoforgeCreativeModeTabs.register(modEventBus); AntarchyNeoforgeEntityAttributes.register(modEventBus); AntarchyNeoforgePayloadHandlers.register(modEventBus); - com.craisinlord.antarchy.content.network.ComputerNetworking.setSender(payload -> + com.craisinlord.antarchy.content.network.AntarchyGameNetworking.setSender(payload -> net.neoforged.neoforge.network.PacketDistributor.sendToServer(payload)); - com.craisinlord.antarchy.content.network.AntmailNetworking.setSender(payload -> - net.neoforged.neoforge.network.PacketDistributor.sendToServer((net.minecraft.network.protocol.common.custom.CustomPacketPayload) payload)); - com.craisinlord.antarchy.content.network.ComputerAccessHandler.setResultSender((player, payload) -> - net.neoforged.neoforge.network.PacketDistributor.sendToPlayer(player, payload)); - com.craisinlord.antarchy.content.network.AntmailServerHandler.setResultSender((player, payload) -> + com.craisinlord.antarchy.content.network.AntarchyGameNetworkHandler.setResultSender((player, payload) -> net.neoforged.neoforge.network.PacketDistributor.sendToPlayer(player, payload)); Antarchy.init(); } @@ -483,10 +480,6 @@ public class AntarchyNeoforge { AntarchyObjects.setCookedCorndog(() -> AntarchyNeoforgeItems.COOKED_CORNDOG.get()); AntarchyObjects.setGlimmerBottle(() -> AntarchyNeoforgeItems.GLIMMER_BOTTLE.get()); AntarchyObjects.setGlimmerVariantComponent(() -> AntarchyNeoforgeMisc.GLIMMER_VARIANT.get()); - AntarchyObjects.setFloppyDiskComponent(() -> AntarchyNeoforgeMisc.FLOPPY_DISK_COMPONENT.get()); - AntarchyObjects.setFloppyDisk(() -> AntarchyNeoforgeItems.FLOPPY_DISK.get()); - AntarchyObjects.setComputer(() -> AntarchyNeoforgeBlocks.COMPUTER.get()); - AntarchyObjects.setComputerBlockEntity(() -> AntarchyNeoforgeBlocks.COMPUTER_BLOCK_ENTITY.get()); AntarchyObjects.setAmericanComponent(() -> AntarchyNeoforgeMisc.AMERICAN.get()); AntarchyObjects.setLumen(() -> AntarchyNeoforgeMisc.LUMEN.get()); AntarchyObjects.setFlowingLumen(() -> AntarchyNeoforgeMisc.FLOWING_LUMEN.get()); @@ -495,6 +488,7 @@ public class AntarchyNeoforge { AntarchyObjects.setLumenFroglight(() -> AntarchyNeoforgeBlocks.LUMEN_FROGLIGHT.get()); AntarchyObjects.setGlimmeringReed(() -> AntarchyNeoforgeBlocks.GLIMMERING_REED.get()); AntarchyObjects.setPeachLeavesParticle(() -> AntarchyNeoforgeMisc.PEACH_LEAVES_PARTICLE.get()); + AntarchyObjects.setBugSprayParticle(() -> AntarchyNeoforgeMisc.BUG_SPRAY_PARTICLE.get()); AntarchyObjects.setLotusPollen(() -> AntarchyNeoforgeMisc.LOTUS_POLLEN.get()); AntarchyObjects.setNightmareFireFlame(() -> AntarchyNeoforgeMisc.NIGHTMARE_FIRE_FLAME.get()); AntarchyObjects.setLucidBoltImpactSmall(() -> AntarchyNeoforgeMisc.LUCID_BOLT_IMPACT_SMALL.get()); 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 7b61efb8..089dad02 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 @@ -11,6 +11,8 @@ import com.craisinlord.antarchy.content.time.TimeDilationCommand; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.event.RegisterCommandsEvent; +import net.minecraft.commands.Commands; +import net.minecraft.network.chat.Component; @EventBusSubscriber(modid = Antarchy.MODID) public final class AntarchyNeoforgeEvents { diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyToolsConfig.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyToolsConfig.java index 02bbb003..942f04a6 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyToolsConfig.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyToolsConfig.java @@ -540,10 +540,10 @@ public final class AntarchyToolsConfig { BLOOD_CRYSTAL_LEGGINGS_DEFENSE = b.comment("Armor defense value for Blood Crystal Leggings. Default: 5 (iron).").defineInRange("leggingsDefense", 5, 0, 30); BLOOD_CRYSTAL_BOOTS_DEFENSE = b.comment("Armor defense value for Blood Crystal Boots. Default: 2 (iron).").defineInRange("bootsDefense", 2, 0, 30); BLOOD_CRYSTAL_ARMOR_TOUGHNESS = b.comment("Armor toughness for all Blood Crystal armor pieces. Default: 0.0 (iron).").defineInRange("armorToughness", 0.0, 0.0, 20.0); - BLOOD_CRYSTAL_HELMET_DURABILITY = b.comment("Max durability of Blood Crystal Helmet. Default: 77 (gold).").defineInRange("helmetDurability", 77, 1, 2000); - BLOOD_CRYSTAL_CHESTPLATE_DURABILITY = b.comment("Max durability of Blood Crystal Chestplate. Default: 112 (gold).").defineInRange("chestplateDurability", 112, 1, 2000); - BLOOD_CRYSTAL_LEGGINGS_DURABILITY = b.comment("Max durability of Blood Crystal Leggings. Default: 105 (gold).").defineInRange("leggingsDurability", 105, 1, 2000); - BLOOD_CRYSTAL_BOOTS_DURABILITY = b.comment("Max durability of Blood Crystal Boots. Default: 91 (gold).").defineInRange("bootsDurability", 91, 1, 2000); + BLOOD_CRYSTAL_HELMET_DURABILITY = b.comment("Max durability of Blood Crystal Helmet. Default: 92.").defineInRange("helmetDurability", 92, 1, 2000); + BLOOD_CRYSTAL_CHESTPLATE_DURABILITY = b.comment("Max durability of Blood Crystal Chestplate. Default: 134.").defineInRange("chestplateDurability", 134, 1, 2000); + BLOOD_CRYSTAL_LEGGINGS_DURABILITY = b.comment("Max durability of Blood Crystal Leggings. Default: 126.").defineInRange("leggingsDurability", 126, 1, 2000); + BLOOD_CRYSTAL_BOOTS_DURABILITY = b.comment("Max durability of Blood Crystal Boots. Default: 109.").defineInRange("bootsDurability", 109, 1, 2000); b.pop(); 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 37a79002..03d2bb6e 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 @@ -2,8 +2,7 @@ package com.craisinlord.antarchy.neoforge.client; import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.content.client.GoopedHudRenderer; -import com.craisinlord.antarchy.content.client.AntarchyClientHooks; -import com.craisinlord.antarchy.content.client.screen.ComputerScreen; +import com.craisinlord.antarchy.content.client.game.AntarchyComputerGames; import com.craisinlord.antarchy.content.client.HordeHudRenderer; import com.craisinlord.antarchy.content.client.TigerEyeClientHooks; import com.craisinlord.antarchy.content.client.hud.BloodglassHudRenderer; @@ -60,6 +59,7 @@ import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent; import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; import net.neoforged.neoforge.client.event.EntityRenderersEvent; import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.neoforge.client.event.RegisterGuiLayersEvent; import net.neoforged.neoforge.client.gui.VanillaGuiLayers; import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions; @@ -93,6 +93,11 @@ public final class AntarchyNeoForgeClient { private AntarchyNeoForgeClient() { } + @SubscribeEvent + public static void clientSetup(FMLClientSetupEvent event) { + event.enqueueWork(AntarchyComputerGames::register); + } + @SubscribeEvent public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) { event.registerBlockEntityRenderer(AntarchyNeoforgeBlocks.DREAM_CAMPFIRE_BLOCK_ENTITY.get(), CampfireRenderer::new); @@ -101,7 +106,6 @@ public final class AntarchyNeoForgeClient { event.registerBlockEntityRenderer(AntarchyNeoforgeBlocks.CRITTER_CAGE_BLOCK_ENTITY.get(), CritterCageRenderer::new); event.registerBlockEntityRenderer(AntarchyNeoforgeBlocks.UNDERTRIAL_SPAWNER_BLOCK_ENTITY.get(), UndertrialSpawnerRenderer::new); event.registerBlockEntityRenderer(AntarchyNeoforgeBlocks.UNDERVAULT_BLOCK_ENTITY.get(), UnderVaultRenderer::new); - event.registerBlockEntityRenderer(AntarchyNeoforgeBlocks.COMPUTER_BLOCK_ENTITY.get(), ComputerRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.EASTER_BUNNY.get(), context -> withParalyzedGeoLayer(new EasterBunnyRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.FLYING_SQUIRREL.get(), context -> withParalyzedGeoLayer(new FlyingSquirrelRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.CATERPILLAR.get(), context -> withParalyzedGeoLayer(new CaterpillarRenderer(context))); @@ -205,7 +209,6 @@ public final class AntarchyNeoForgeClient { renderer.addLayer(new GoopedLivingLayer(renderer)); renderer.addLayer(new GlimmeringLivingLayer(renderer)); renderer.addLayer(new com.craisinlord.antarchy.content.client.renderer.RoyalIndicatorLivingLayer<>(renderer)); - renderer.addLayer(new RoyalAssailantAxeAfterimageLayer(renderer)); renderer.addLayer(new BrutalflyElytraLayer(renderer)); renderer.addLayer(new com.craisinlord.antarchy.content.client.renderer.ManticoreWingsLayer(renderer)); renderer.addLayer(new FallenKingCrownLayer(renderer)); @@ -326,6 +329,7 @@ public final class AntarchyNeoForgeClient { event.registerSpriteSet(AntarchyNeoforgeMisc.STINKY_GAS.get(), HypnoticGasParticle.Provider::new); event.registerSpriteSet(AntarchyNeoforgeMisc.STINKY_FLY.get(), FireflyParticle.Provider::new); event.registerSpriteSet(AntarchyNeoforgeMisc.PEACH_LEAVES_PARTICLE.get(), PeachLeavesParticle.Provider::new); + event.registerSpriteSet(AntarchyNeoforgeMisc.BUG_SPRAY_PARTICLE.get(), com.craisinlord.antarchy.content.client.particle.BugSprayParticle.Provider::new); event.registerSpriteSet(AntarchyNeoforgeMisc.LOTUS_POLLEN.get(), com.craisinlord.antarchy.content.client.particle.LotusPollenParticle.Provider::new); event.registerSpriteSet(AntarchyNeoforgeMisc.HYPNOTIC_GAS.get(), HypnoticGasParticle.Provider::new); event.registerSpriteSet(AntarchyNeoforgeMisc.HYPNOTIC_GAS_DOWN.get(), sprites -> new HypnoticGasParticle.Provider(sprites, true)); @@ -605,7 +609,6 @@ public final class AntarchyNeoForgeClient { @SubscribeEvent public static void onClientSetup(FMLClientSetupEvent event) { event.enqueueWork(() -> { - AntarchyClientHooks.setComputerOpener(pos -> Minecraft.getInstance().setScreen(new ComputerScreen(pos))); TigerEyeClientHooks.setCamouflageKeyTextSupplier(() -> AntarchyKeyBindings.TIGERS_EYE_CAMOUFLAGE.getTranslatedKeyMessage()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.UNDERTRIAL_SPAWNER.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.UNDERVAULT.get(), RenderType.cutout()); @@ -715,12 +718,12 @@ public final class AntarchyNeoForgeClient { ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.GLOWCAP_MUSHROOM.get(), RenderType.cutout()); registerUltimateBowProperties(); registerUltimateCrossbowProperties(); - registerFloppyDiskProperties(); }); } @SubscribeEvent public static void registerClientReloadListeners(RegisterClientReloadListenersEvent event) { + event.registerReloadListener(com.craisinlord.antos.content.guide.ComputerGuideData.instance()); event.registerReloadListener(new net.minecraft.server.packs.resources.SimplePreparableReloadListener() { @Override protected Void prepare(net.minecraft.server.packs.resources.ResourceManager resourceManager, net.minecraft.util.profiling.ProfilerFiller profiler) { @@ -734,14 +737,6 @@ public final class AntarchyNeoForgeClient { }); } - private static void registerFloppyDiskProperties() { - ItemProperties.register( - AntarchyNeoforgeItems.FLOPPY_DISK.get(), - ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "disk_category"), - (stack, level, entity, seed) -> com.craisinlord.antarchy.content.item.FloppyDiskItem.categoryModelProperty(stack) - ); - } - private static void registerUltimateBowProperties() { ItemProperties.register( AntarchyNeoforgeItems.ULTIMATE_BOW.get(), diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/BigBerthaClientHandler.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/BigBerthaClientHandler.java index cea5c426..34fa5930 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/BigBerthaClientHandler.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/BigBerthaClientHandler.java @@ -2,7 +2,9 @@ package com.craisinlord.antarchy.neoforge.client; import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.content.item.BigBerthaItem; +import com.craisinlord.antarchy.content.item.RoyalGuardianSwordItem; import com.craisinlord.antarchy.content.network.BigBerthaModeCyclePayload; +import com.craisinlord.antarchy.content.network.RoyalGuardianSwordModeCyclePayload; import net.minecraft.client.Minecraft; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; @@ -25,7 +27,9 @@ public final class BigBerthaClientHandler { return; } - if (!(mc.player.getMainHandItem().getItem() instanceof BigBerthaItem)) { + boolean bigBertha = mc.player.getMainHandItem().getItem() instanceof BigBerthaItem; + boolean royalGuardianSword = mc.player.getMainHandItem().getItem() instanceof RoyalGuardianSwordItem; + if (!bigBertha && !royalGuardianSword) { lastUseDown = false; return; } @@ -34,8 +38,9 @@ public final class BigBerthaClientHandler { if (useDown && !lastUseDown && mc.player.isShiftKeyDown() - && mc.player.getCooldowns().isOnCooldown(mc.player.getMainHandItem().getItem())) { - PacketDistributor.sendToServer(new BigBerthaModeCyclePayload()); + ) { + if (bigBertha) PacketDistributor.sendToServer(new BigBerthaModeCyclePayload()); + else PacketDistributor.sendToServer(new RoyalGuardianSwordModeCyclePayload()); } lastUseDown = useDown; } diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/network/AntarchyGravityNetworking.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/network/AntarchyGravityNetworking.java index cf76f499..b6899ab9 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/network/AntarchyGravityNetworking.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/network/AntarchyGravityNetworking.java @@ -7,6 +7,7 @@ import com.craisinlord.antarchy.content.item.EyeOfTheStormItem; import com.craisinlord.antarchy.content.item.GravityGunItem; import com.craisinlord.antarchy.content.item.PortalGunItem; import com.craisinlord.antarchy.content.network.BigBerthaModeCyclePayload; +import com.craisinlord.antarchy.content.network.RoyalGuardianSwordModeCyclePayload; import com.craisinlord.antarchy.content.network.EyeOfStormPrimaryPayload; import com.craisinlord.antarchy.content.network.GravityGunPrimaryPayload; import com.craisinlord.antarchy.content.network.GravityGunScrollPayload; @@ -54,6 +55,10 @@ public final class AntarchyGravityNetworking { BigBerthaModeCyclePayload.TYPE, BigBerthaModeCyclePayload.STREAM_CODEC, AntarchyGravityNetworking::handleBigBerthaModeCycle + ).playToServer( + RoyalGuardianSwordModeCyclePayload.TYPE, + RoyalGuardianSwordModeCyclePayload.STREAM_CODEC, + AntarchyGravityNetworking::handleRoyalGuardianSwordModeCycle ).playToServer( com.craisinlord.antarchy.content.network.DiamondMinecartInputPayload.TYPE, com.craisinlord.antarchy.content.network.DiamondMinecartInputPayload.STREAM_CODEC, @@ -149,7 +154,17 @@ public final class AntarchyGravityNetworking { return; } - bigBerthaItem.tryCycleModeWhileCoolingDown(serverPlayer.serverLevel(), serverPlayer, serverPlayer.getMainHandItem()); + bigBerthaItem.tryCycleModeFromInput(serverPlayer.serverLevel(), serverPlayer, serverPlayer.getMainHandItem()); + }); + } + + private static void handleRoyalGuardianSwordModeCycle(RoyalGuardianSwordModeCyclePayload payload, IPayloadContext context) { + context.enqueueWork(() -> { + if (!(context.player() instanceof ServerPlayer serverPlayer) + || !(serverPlayer.getMainHandItem().getItem() instanceof com.craisinlord.antarchy.content.item.RoyalGuardianSwordItem sword)) { + return; + } + sword.tryCycleModeFromInput(serverPlayer.serverLevel(), serverPlayer, serverPlayer.getMainHandItem()); }); } 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 a58be766..8f860f1f 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 @@ -263,6 +263,14 @@ public final class AntarchyNeoForgeEvents { .add(ComputerScientistTradeManager.listing(level, index)); } } + } else if (event.getType() == AntarchyNeoforgeMisc.PEST_CONTROL.get()) { + int[] slots = com.craisinlord.antarchy.content.entity.trades.PestControlTradeManager.slotsPerLevel(); + for (int level = 1; level <= slots.length; level++) { + for (int index = 0; index < slots[level - 1]; index++) { + event.getTrades().computeIfAbsent(level, ignored -> new java.util.ArrayList<>()) + .add(com.craisinlord.antarchy.content.entity.trades.PestControlTradeManager.listing(level, index)); + } + } } else if (event.getType() == VillagerProfession.FARMER) { event.getTrades().get(1).add(emeraldForItems(AntarchyObjects.CORN.get(), 20, 16, 2)); } else if (event.getType() == VillagerProfession.BUTCHER) { @@ -323,8 +331,6 @@ public final class AntarchyNeoForgeEvents { static void tickCavarynHordes(ServerTickEvent.Post event) { - com.craisinlord.antarchy.content.antmail.AntmailServerData.access(event.getServer()).drainAvailable(event.getServer()); - com.craisinlord.antarchy.content.antmail.AntmailEventData.onTick(event.getServer()); for (ServerLevel level : event.getServer().getAllLevels()) { CavarynHordeManager.tick(level); com.craisinlord.antarchy.content.horde.CavarynCreatureSpawner.tick(level); @@ -394,8 +400,7 @@ public final class AntarchyNeoForgeEvents { static void registerReloadListeners(AddReloadListenerEvent event) { event.addListener(new DrTrayaurusTradeManager()); event.addListener(new ComputerScientistTradeManager()); - event.addListener(com.craisinlord.antarchy.content.guide.ComputerGuideData.instance()); - event.addListener(com.craisinlord.antarchy.content.antmail.AntmailEventData.instance()); + event.addListener(new com.craisinlord.antarchy.content.entity.trades.PestControlTradeManager()); event.addListener(com.craisinlord.antarchy.content.computer.blockle.BlockleAnswers.instance()); } static void handleStartTracking(PlayerEvent.StartTracking event) { diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java index 0a1101c1..12ec828b 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java @@ -6,7 +6,6 @@ import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.block.*; import com.craisinlord.antarchy.content.block.entity.AntNestBlockEntity; import com.craisinlord.antarchy.content.block.entity.CritterCageBlockEntity; -import com.craisinlord.antarchy.content.block.entity.ComputerBlockEntity; import com.craisinlord.antarchy.content.block.entity.DimensionalTearMarkerBlockEntity; import com.craisinlord.antarchy.content.block.entity.DreamCampfireBlockEntity; import com.craisinlord.antarchy.content.block.entity.HushweedBlockEntity; @@ -632,6 +631,11 @@ public final class AntarchyNeoforgeBlocks { () -> new AntNestBlock(AntarchyNeoforgeEntites.RAINBOW_ANT, AntarchyNeoforgeItems::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.DIRT).noLootTable())); public static final DeferredBlock TERMITE_NEST = BLOCKS.register("termite_nest", () -> new AntNestBlock(AntarchyNeoforgeEntites.TERMITE, AntarchyNeoforgeItems::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.DIRT).noLootTable())); + + public static final DeferredBlock ANT_TRAP = BLOCKS.register("ant_trap", + () -> new com.craisinlord.antarchy.content.block.AntTrapBlock( + () -> java.util.List.of(AntarchyNeoforgeEntites.RED_ANT.get(), AntarchyNeoforgeEntites.BROWN_ANT.get(), AntarchyNeoforgeEntites.RAINBOW_ANT.get(), AntarchyNeoforgeEntites.TERMITE.get()), + AntarchyNeoforgeItems::antNestBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_PRESSURE_PLATE).noOcclusion())); public static final DeferredBlock URANIUM_ORE = BLOCKS.register("uranium_ore", () -> createOre(Blocks.EMERALD_ORE, 4, 8, MapColor.COLOR_YELLOW)); public static final DeferredBlock DEEPSLATE_URANIUM_ORE = BLOCKS.register("deepslate_uranium_ore", @@ -717,8 +721,6 @@ public final class AntarchyNeoforgeBlocks { () -> new com.craisinlord.antarchy.content.block.AntimetalRailBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.RAIL))); public static final DeferredBlock UPPER = BLOCKS.register("upper", () -> new UpperBlock(AntarchyNeoforgeBlocks::upperBlockEntityType, BlockBehaviour.Properties.ofFullCopy(Blocks.HOPPER))); - public static final DeferredBlock COMPUTER = BLOCKS.register("computer", - () -> new com.craisinlord.antarchy.content.block.ComputerBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.IRON_BLOCK).noOcclusion())); public static final DeferredBlock ANTIMETAL_POWERED_RAIL = BLOCKS.register("antimetal_powered_rail", () -> new com.craisinlord.antarchy.content.block.AntimetalPoweredRailBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.POWERED_RAIL))); public static final DeferredBlock ANTIMETAL_DETECTOR_RAIL = BLOCKS.register("antimetal_detector_rail", @@ -884,7 +886,8 @@ public final class AntarchyNeoforgeBlocks { RED_ANT_NEST.get(), BROWN_ANT_NEST.get(), RAINBOW_ANT_NEST.get(), - TERMITE_NEST.get() + TERMITE_NEST.get(), + ANT_TRAP.get() ).build(null)); public static final DeferredHolder, BlockEntityType> DREAM_CAMPFIRE_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("dream_campfire", () -> BlockEntityType.Builder.of( @@ -951,11 +954,6 @@ public final class AntarchyNeoforgeBlocks { (pos, state) -> new DimensionalTearMarkerBlockEntity(pos, state, AntarchyNeoforgeBlocks::dimensionalTearMarkerBlockEntityType), DIMENSIONAL_TEAR_MARKER.get() ).build(null)); - public static final DeferredHolder, BlockEntityType> COMPUTER_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("computer", - () -> BlockEntityType.Builder.of( - (pos, state) -> new ComputerBlockEntity(pos, state, AntarchyNeoforgeBlocks::computerBlockEntityType), - COMPUTER.get() - ).build(null)); public static final DeferredHolder, BlockEntityType> QUEEN_TRAIL_SPAWN_MARKER_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("queen_trail_spawn_marker", () -> BlockEntityType.Builder.of( (pos, state) -> new QueenTrailSpawnMarkerBlockEntity(pos, state, AntarchyNeoforgeBlocks::queenTrailSpawnMarkerBlockEntityType), @@ -1054,10 +1052,6 @@ public final class AntarchyNeoforgeBlocks { return UPPER_BLOCK_ENTITY.get(); } - private static BlockEntityType computerBlockEntityType() { - return COMPUTER_BLOCK_ENTITY.get(); - } - private static BlockEntityType vortexLensBlockEntityType() { return VORTEX_LENS_BLOCK_ENTITY.get(); } 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 cfbc793b..71df7403 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 @@ -92,7 +92,6 @@ public final class AntarchyNeoforgeItems { () -> Ingredient.of(AntarchyNeoforgeItems.QUEEN_SCALE.get()) ); - public static final DeferredItem FLOPPY_DISK = ITEMS.register("floppy_disk", () -> new com.craisinlord.antarchy.content.item.FloppyDiskItem(new Item.Properties())); public static final DeferredItem NIGHTMARE_SCALE = ITEMS.registerSimpleItem("nightmare_scale", new Item.Properties().rarity(Rarity.RARE).fireResistant()); @@ -206,8 +205,6 @@ public final class AntarchyNeoforgeItems { // Block items public static final DeferredItem DUPLICATOR_LOG_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.DUPLICATOR_LOG); - public static final DeferredItem COMPUTER_ITEM = ITEMS.register("computer", - () -> new ComputerItem(AntarchyNeoforgeBlocks.COMPUTER.get(), new Item.Properties())); public static final DeferredItem OURANWOOD_LOG_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.OURANWOOD_LOG); public static final DeferredItem OURANWOOD_WOOD_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.OURANWOOD_WOOD); public static final DeferredItem MOSSY_OURANWOOD_LOG_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.MOSSY_OURANWOOD_LOG); @@ -396,6 +393,11 @@ public final class AntarchyNeoforgeItems { public static final DeferredItem BROWN_ANT_NEST_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.BROWN_ANT_NEST); public static final DeferredItem RAINBOW_ANT_NEST_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.RAINBOW_ANT_NEST); public static final DeferredItem TERMITE_NEST_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.TERMITE_NEST); + + public static final DeferredItem ANT_TRAP_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.ANT_TRAP); + + public static final DeferredItem BUG_SPRAY = ITEMS.register("bug_spray", + () -> new com.craisinlord.antarchy.content.item.BugSprayItem(new Item.Properties().stacksTo(16))); public static final DeferredItem URANIUM_ORE_ITEM = ITEMS.register("uranium_ore", () -> new net.minecraft.world.item.BlockItem(AntarchyNeoforgeBlocks.URANIUM_ORE.get(), new Item.Properties().rarity(Rarity.UNCOMMON))); public static final DeferredItem DEEPSLATE_URANIUM_ORE_ITEM = ITEMS.register("deepslate_uranium_ore", 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 ebcf9680..e64287f0 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 @@ -71,7 +71,7 @@ public final class AntarchyNeoforgeMisc { public static final DeferredHolder COMPUTER_POI = POI_TYPES.register("computer", () -> new PoiType( - java.util.Set.copyOf(AntarchyNeoforgeBlocks.COMPUTER.get().getStateDefinition().getPossibleStates()), + java.util.Set.copyOf(net.minecraft.world.level.block.Block.byItem(com.craisinlord.antos.content.AntOSObjects.COMPUTER_ITEM.get()).getStateDefinition().getPossibleStates()), 1, 1)); @@ -83,6 +83,13 @@ public final class AntarchyNeoforgeMisc { com.google.common.collect.ImmutableSet.of(), com.google.common.collect.ImmutableSet.of(), net.minecraft.sounds.SoundEvents.VILLAGER_WORK_LIBRARIAN)); + + public static final DeferredHolder PEST_CONTROL_POI = POI_TYPES.register("pest_control", + () -> new PoiType(java.util.Set.copyOf(AntarchyNeoforgeBlocks.ANT_TRAP.get().getStateDefinition().getPossibleStates()), 1, 1)); + + public static final DeferredHolder PEST_CONTROL = VILLAGER_PROFESSIONS.register("pest_control", + () -> new VillagerProfession("pest_control", holder -> holder.value() == PEST_CONTROL_POI.get(), + holder -> holder.value() == PEST_CONTROL_POI.get(), com.google.common.collect.ImmutableSet.of(), com.google.common.collect.ImmutableSet.of(), net.minecraft.sounds.SoundEvents.VILLAGER_WORK_FLETCHER)); private static final DeferredRegister MOB_EFFECTS = DeferredRegister.create(Registries.MOB_EFFECT, Antarchy.MODID); private static final DeferredRegister POTIONS = DeferredRegister.create(Registries.POTION, Antarchy.MODID); private static final DeferredRegister FLUID_TYPES = DeferredRegister.create(NeoForgeRegistries.Keys.FLUID_TYPES, Antarchy.MODID); @@ -105,12 +112,6 @@ public final class AntarchyNeoforgeMisc { .persistent(com.craisinlord.antarchy.content.entity.glimmer.GlimmerVariant.CODEC) .networkSynchronized(com.craisinlord.antarchy.content.entity.glimmer.GlimmerVariant.STREAM_CODEC) .build()); - public static final DeferredHolder, net.minecraft.core.component.DataComponentType> FLOPPY_DISK_COMPONENT = - DATA_COMPONENT_TYPES.register("floppy_disk", - () -> net.minecraft.core.component.DataComponentType.builder() - .persistent(net.minecraft.resources.ResourceLocation.CODEC) - .networkSynchronized(net.minecraft.resources.ResourceLocation.STREAM_CODEC) - .build()); public static final DeferredHolder, net.minecraft.core.component.DataComponentType> AMERICAN = DATA_COMPONENT_TYPES.register("american", () -> net.minecraft.core.component.DataComponentType.builder() @@ -234,6 +235,8 @@ public final class AntarchyNeoforgeMisc { // Particle types public static final DeferredHolder, SimpleParticleType> DREAM_FIRE_FLAME = PARTICLE_TYPES.register("dream_fire_flame", () -> new SimpleParticleType(true)); + public static final DeferredHolder, SimpleParticleType> BUG_SPRAY_PARTICLE = PARTICLE_TYPES.register("bug_spray", + () -> new SimpleParticleType(true)); public static final DeferredHolder, SimpleParticleType> NIGHTMARE_FIRE_FLAME = PARTICLE_TYPES.register("nightmare_fire_flame", () -> new SimpleParticleType(true)); public static final DeferredHolder, SimpleParticleType> STINKY_GAS = PARTICLE_TYPES.register("stinky_gas", diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgePayloadHandlers.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgePayloadHandlers.java index 746159c8..b424a17c 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgePayloadHandlers.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgePayloadHandlers.java @@ -1,21 +1,10 @@ package com.craisinlord.antarchy.neoforge.registry; import com.craisinlord.antarchy.content.network.BloodCrystalKatanaTrailPayload; -import com.craisinlord.antarchy.content.network.ComputerAccessHandler; -import com.craisinlord.antarchy.content.network.ComputerAccessPayload; -import com.craisinlord.antarchy.content.network.ComputerAccessResultPayload; +import com.craisinlord.antarchy.content.network.AntarchyGameNetworkHandler; +import com.craisinlord.antarchy.content.network.AntarchyGamePayload; +import com.craisinlord.antarchy.content.network.AntarchyGameResultPayload; import com.craisinlord.antarchy.content.network.ToggleTigerEyeCamouflagePayload; -import com.craisinlord.antarchy.content.network.AntmailPayloadTypes; -import com.craisinlord.antarchy.content.network.AntmailSetupPayload; -import com.craisinlord.antarchy.content.network.AntmailStateRequestPayload; -import com.craisinlord.antarchy.content.network.AntmailMessageRequestPayload; -import com.craisinlord.antarchy.content.network.AntmailSendPayload; -import com.craisinlord.antarchy.content.network.AntmailReadPayload; -import com.craisinlord.antarchy.content.network.AntmailDeletePayload; -import com.craisinlord.antarchy.content.network.AntmailDraftPayload; -import com.craisinlord.antarchy.content.network.AntmailRetryPayload; -import com.craisinlord.antarchy.content.network.AntmailResultPayload; -import com.craisinlord.antarchy.content.network.AntmailServerHandler; import com.craisinlord.antarchy.content.item.TigerEyeArmorUtil; import com.craisinlord.antarchy.content.tigereye.TigerEyeCamouflageController; import com.craisinlord.antarchy.neoforge.network.AntarchyGravityNetworking; @@ -38,52 +27,18 @@ public class AntarchyNeoforgePayloadHandlers { static void registerPayloadHandlers(RegisterPayloadHandlersEvent event) { var registrar = event.registrar("1"); registrar.playToServer( - ComputerAccessPayload.TYPE, - ComputerAccessPayload.STREAM_CODEC, + AntarchyGamePayload.TYPE, + AntarchyGamePayload.STREAM_CODEC, (payload, ctx) -> ctx.enqueueWork(() -> { if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer player) { - ComputerAccessHandler.handle(player, payload); + AntarchyGameNetworkHandler.handle(player, payload); } }) ); - registrar.playToServer(AntmailSetupPayload.TYPE, AntmailSetupPayload.STREAM_CODEC, - (payload, ctx) -> ctx.enqueueWork(() -> { - if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer player) AntmailServerHandler.handle(player, payload); - })); - registrar.playToServer(AntmailStateRequestPayload.TYPE, AntmailStateRequestPayload.STREAM_CODEC, - (payload, ctx) -> ctx.enqueueWork(() -> { - if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer player) AntmailServerHandler.handle(player, payload); - })); - registrar.playToServer(AntmailMessageRequestPayload.TYPE, AntmailMessageRequestPayload.STREAM_CODEC, - (payload, ctx) -> ctx.enqueueWork(() -> { - if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer player) AntmailServerHandler.handle(player, payload); - })); - registrar.playToServer(AntmailSendPayload.TYPE, AntmailSendPayload.STREAM_CODEC, - (payload, ctx) -> ctx.enqueueWork(() -> { - if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer player) AntmailServerHandler.handle(player, payload); - })); - registrar.playToServer(AntmailReadPayload.TYPE, AntmailReadPayload.STREAM_CODEC, - (payload, ctx) -> ctx.enqueueWork(() -> { - if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer player) AntmailServerHandler.handle(player, payload); - })); - registrar.playToServer(AntmailDeletePayload.TYPE, AntmailDeletePayload.STREAM_CODEC, - (payload, ctx) -> ctx.enqueueWork(() -> { - if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer player) AntmailServerHandler.handle(player, payload); - })); - registrar.playToServer(AntmailDraftPayload.TYPE, AntmailDraftPayload.STREAM_CODEC, - (payload, ctx) -> ctx.enqueueWork(() -> { - if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer player) AntmailServerHandler.handle(player, payload); - })); - registrar.playToServer(AntmailRetryPayload.TYPE, AntmailRetryPayload.STREAM_CODEC, - (payload, ctx) -> ctx.enqueueWork(() -> { - if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer player) AntmailServerHandler.handle(player, payload); - })); - registrar.playToClient(AntmailResultPayload.TYPE, AntmailResultPayload.STREAM_CODEC, - (payload, ctx) -> ctx.enqueueWork(() -> com.craisinlord.antarchy.content.client.AntmailClientState.update(payload))); registrar.playToClient( - ComputerAccessResultPayload.TYPE, - ComputerAccessResultPayload.STREAM_CODEC, - (payload, ctx) -> ctx.enqueueWork(() -> com.craisinlord.antarchy.content.client.ComputerAccessClientState.update(payload)) + AntarchyGameResultPayload.TYPE, + AntarchyGameResultPayload.STREAM_CODEC, + (payload, ctx) -> ctx.enqueueWork(() -> com.craisinlord.antarchy.content.client.AntarchyGameClientState.update(payload)) ); AntarchyGravityNetworking.register(registrar); AntarchyTimeDilationNetworking.register(registrar); diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java index 8e265d8d..c0a128b3 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java @@ -259,6 +259,9 @@ public final class AntarchyNeoforgeSounds { public static final DeferredHolder PRINCESS_SHOOT = registerSoundEvent("princess_shoot"); public static final DeferredHolder PRINCESS_FLY = registerSoundEvent("princess_fly"); public static final DeferredHolder PRINCESS_STEP = registerSoundEvent("princess_step"); + public static final DeferredHolder HOVERBOARD_MOUNT = registerSoundEvent("hoverboard_mount"); + public static final DeferredHolder HOVERBOARD_DISMOUNT = registerSoundEvent("hoverboard_dismount"); + public static final DeferredHolder HOVERBOARD_IDLE = registerSoundEvent("hoverboard_idle"); private AntarchyNeoforgeSounds() {} diff --git a/neoforge-1.21.1/src/main/resources/META-INF/neoforge.mods.toml b/neoforge-1.21.1/src/main/resources/META-INF/neoforge.mods.toml index 9939e998..4367d003 100644 --- a/neoforge-1.21.1/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge-1.21.1/src/main/resources/META-INF/neoforge.mods.toml @@ -25,6 +25,13 @@ displayURL="https://www.curseforge.com/minecraft/mc-mods/antarchy" type="required" versionRange="[1.21.1,)" +[[dependencies.antarchy]] + modId="antos" + type="required" + versionRange="*" + ordering="AFTER" + side="BOTH" + [[dependencies.antarchy]] modId="integrated_api" type="required" @@ -59,4 +66,4 @@ displayURL="https://www.curseforge.com/minecraft/mc-mods/antarchy" type="optional" versionRange="*" ordering="NONE" - reason="Enables an in-game config screen for Antarchy's settings; Antarchy works fully without it." \ No newline at end of file + reason="Enables an in-game config screen for Antarchy's settings; Antarchy works fully without it." diff --git a/neoforge-1.21.1/src/main/resources/data/antarchy/neoforge/biome_modifier/octopus_bomb_spawns.json b/neoforge-1.21.1/src/main/resources/data/antarchy/neoforge/biome_modifier/octopus_bomb_spawns.json deleted file mode 100644 index 8faeead3..00000000 --- a/neoforge-1.21.1/src/main/resources/data/antarchy/neoforge/biome_modifier/octopus_bomb_spawns.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "type": "neoforge:add_spawns", - "biomes": [ - "minecraft:deep_ocean", - "minecraft:deep_cold_ocean", - "minecraft:deep_lukewarm_ocean", - "minecraft:deep_frozen_ocean" - ], - "spawners": [ - { - "type": "antarchy:octopus_bomb", - "weight": 2, - "minCount": 1, - "maxCount": 2 - } - ] -}