diff --git a/bc23-shards/assets/bc23/lang/en_us.json b/bc23-shards/assets/bc23/lang/en_us.json new file mode 100644 index 0000000..663dd16 --- /dev/null +++ b/bc23-shards/assets/bc23/lang/en_us.json @@ -0,0 +1,6 @@ +{ + "shard_type.bc23.visitor.description": "Visitor Shard", + "shard_type.bc23.challenge.description": "Challenge Shard", + "shard_type.bc23.secret.description": "Secret Shard", + "shard_type.bc23.missing.description": "Missing Shard" +} \ No newline at end of file diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/challenge_backing.png b/bc23-shards/assets/bc23/textures/gui/shards/challenge_backing.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/challenge_backing.png rename to bc23-shards/assets/bc23/textures/gui/shards/challenge_backing.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/challenge_front.png b/bc23-shards/assets/bc23/textures/gui/shards/challenge_front.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/challenge_front.png rename to bc23-shards/assets/bc23/textures/gui/shards/challenge_front.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/challenge_mini_back.png b/bc23-shards/assets/bc23/textures/gui/shards/challenge_mini_backing.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/challenge_mini_back.png rename to bc23-shards/assets/bc23/textures/gui/shards/challenge_mini_backing.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/challenge_mini_front.png b/bc23-shards/assets/bc23/textures/gui/shards/challenge_mini_front.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/challenge_mini_front.png rename to bc23-shards/assets/bc23/textures/gui/shards/challenge_mini_front.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/secret_backing.png b/bc23-shards/assets/bc23/textures/gui/shards/secret_backing.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/secret_backing.png rename to bc23-shards/assets/bc23/textures/gui/shards/secret_backing.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/secret_front.png b/bc23-shards/assets/bc23/textures/gui/shards/secret_front.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/secret_front.png rename to bc23-shards/assets/bc23/textures/gui/shards/secret_front.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/secret_mini_back.png b/bc23-shards/assets/bc23/textures/gui/shards/secret_mini_backing.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/secret_mini_back.png rename to bc23-shards/assets/bc23/textures/gui/shards/secret_mini_backing.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/secret_mini_front.png b/bc23-shards/assets/bc23/textures/gui/shards/secret_mini_front.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/secret_mini_front.png rename to bc23-shards/assets/bc23/textures/gui/shards/secret_mini_front.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/visitor_backing.png b/bc23-shards/assets/bc23/textures/gui/shards/visitor_backing.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/visitor_backing.png rename to bc23-shards/assets/bc23/textures/gui/shards/visitor_backing.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/visitor_front.png b/bc23-shards/assets/bc23/textures/gui/shards/visitor_front.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/visitor_front.png rename to bc23-shards/assets/bc23/textures/gui/shards/visitor_front.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/visitor_mini_back.png b/bc23-shards/assets/bc23/textures/gui/shards/visitor_mini_backing.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/visitor_mini_back.png rename to bc23-shards/assets/bc23/textures/gui/shards/visitor_mini_backing.png diff --git a/src/main/resources/assets/scattered_shards/textures/gui/shards/visitor_mini_front.png b/bc23-shards/assets/bc23/textures/gui/shards/visitor_mini_front.png similarity index 100% rename from src/main/resources/assets/scattered_shards/textures/gui/shards/visitor_mini_front.png rename to bc23-shards/assets/bc23/textures/gui/shards/visitor_mini_front.png diff --git a/bc23-shards/data/bc23/shard_type/bc23_types.json b/bc23-shards/data/bc23/shard_type/bc23_types.json new file mode 100644 index 0000000..409125a --- /dev/null +++ b/bc23-shards/data/bc23/shard_type/bc23_types.json @@ -0,0 +1,31 @@ +{ + "bc23:visitor": { + "text_color": "#6de851", + "glow_color": "#00ff48", + "collect_particle": "minecraft:totem_of_undying", + "collect_sound": { + "sound_id": "scattered_shards:collect_visitor" + }, + "list_order": 1 + }, + + "bc23:challenge": { + "text_color": "#5174e8", + "glow_color": "#0026ff", + "collect_particle": "minecraft:glow", + "collect_sound": { + "sound_id": "scattered_shards:collect_challenge" + }, + "list_order": 2 + }, + + "bc23:secret": { + "text_color": "#eb4034", + "glow_color": "#f08", + "collect_particle": "minecraft:witch", + "collect_sound": { + "sound_id": "scattered_shards:collect_secret" + }, + "list_order": 3 + } +} diff --git a/bc23-shards/pack.mcmeta b/bc23-shards/pack.mcmeta new file mode 100644 index 0000000..eec78d6 --- /dev/null +++ b/bc23-shards/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "pack_format": 10, + "description": "Scattered Shards assets used at BlanketCon '23" + } +} \ No newline at end of file diff --git a/src/main/java/net/modfest/scatteredshards/ScatteredShards.java b/src/main/java/net/modfest/scatteredshards/ScatteredShards.java index e384583..6688f4f 100644 --- a/src/main/java/net/modfest/scatteredshards/ScatteredShards.java +++ b/src/main/java/net/modfest/scatteredshards/ScatteredShards.java @@ -1,5 +1,7 @@ package net.modfest.scatteredshards; +import net.modfest.scatteredshards.api.ScatteredShardsAPI; +import net.modfest.scatteredshards.load.ShardTypeLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,14 +30,11 @@ public static String permission(String path) { @Override public void onInitialize() { + //ScatteredShardsAPI.init(); ShardType.register(); - //ShardTypeLoader.register(); - //ShardSetLoader.register(); + ShardTypeLoader.register(); ShardCommand.register(); ScatteredShardsNetworking.register(); ScatteredShardsContent.register(); - FabricLoader.getInstance().getModContainer(ID).ifPresent(mod -> { - ResourceManagerHelper.registerBuiltinResourcePack(ScatteredShards.id("test"), mod, ResourcePackActivationType.NORMAL); - }); } } diff --git a/src/main/java/net/modfest/scatteredshards/api/MiniRegistry.java b/src/main/java/net/modfest/scatteredshards/api/MiniRegistry.java index 7e3bc19..d01c0e4 100644 --- a/src/main/java/net/modfest/scatteredshards/api/MiniRegistry.java +++ b/src/main/java/net/modfest/scatteredshards/api/MiniRegistry.java @@ -1,5 +1,7 @@ package net.modfest.scatteredshards.api; +import java.util.Collection; +import java.util.Map; import java.util.Optional; import java.util.function.BiConsumer; import java.util.stream.Stream; @@ -47,10 +49,18 @@ public Stream streamKeys() { public void put(Identifier id, T value) { data.put(id, value); } + + public void putAll(Map values) { + data.putAll(values); + } public void remove(Identifier id) { data.remove(id); } + + public void removeAll(Collection ids) { + data.keySet().removeAll(ids); + } public void clear() { data.clear(); diff --git a/src/main/java/net/modfest/scatteredshards/api/impl/ColorCodec.java b/src/main/java/net/modfest/scatteredshards/api/impl/ColorCodec.java new file mode 100644 index 0000000..34f0bb1 --- /dev/null +++ b/src/main/java/net/modfest/scatteredshards/api/impl/ColorCodec.java @@ -0,0 +1,59 @@ +package net.modfest.scatteredshards.api.impl; + +import com.mojang.serialization.Codec; + +public class ColorCodec { + + public static Codec CODEC = Codec.STRING.xmap(ColorCodec::parseColor, ColorCodec::valueOf); + + public static int parseColor(String str) { + if (str.startsWith("#")) str = str.substring(1); + if (str.length() == 3) { + int r = hexDigit(str.charAt(0)); r = r | (r << 4); + int g = hexDigit(str.charAt(1)); g = g | (g << 4); + int b = hexDigit(str.charAt(2)); b = b | (b << 4); + return (r << 16) | (g << 8) | b; + } else if (str.length() == 6) { + int r = hexDigit(str.charAt(0)) << 4 | hexDigit(str.charAt(1)); + int g = hexDigit(str.charAt(2)) << 4 | hexDigit(str.charAt(3)); + int b = hexDigit(str.charAt(4)) << 4 | hexDigit(str.charAt(5)); + return (r << 16) | (g << 8) | b; + } else { + return 0xFFFFFF; + } + } + + public static String valueOf(int col) { + col = col & 0xFFFFFF; + int r = (col >> 16) & 0xFF; + int g = (col >> 8) & 0xFF; + int b = col & 0xFF; + + String rs = Integer.toHexString(r); + String gs = Integer.toHexString(g); + String bs = Integer.toHexString(b); + while (rs.length()<2) rs = "0" + rs; + while (gs.length()<2) gs = "0" + gs; + while (bs.length()<2) bs = "0" + bs; + + boolean shortR = (rs.charAt(0) == rs.charAt(1)); + boolean shortG = (gs.charAt(0) == gs.charAt(1)); + boolean shortB = (bs.charAt(0) == bs.charAt(1)); + if (shortR && shortG && shortB) { + return "#" + rs.charAt(0) + gs.charAt(0) + bs.charAt(0); + } else { + return "#" + rs + gs + bs; + } + } + + private static final char[] HEX_DIGITS = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + private static final int hexDigit(char ch) { + ch = Character.toLowerCase(ch); + for(int i=0; i TYPE = new PersistentState.Type<>( @@ -20,7 +19,6 @@ public class ShardLibraryPersistentState extends PersistentState { null ); - public static final String SHARD_TYPES_KEY = "ShardTypes"; public static final String SHARDS_KEY = "Shards"; public static final String SHARD_SETS_KEY = "ShardSets"; @@ -31,15 +29,6 @@ public static ShardLibraryPersistentState get(MinecraftServer server) { } public ShardLibraryPersistentState() { - addDefaultShardTypes(); - } - - private static void addDefaultShardTypes() { - ShardLibrary library = ScatteredShardsAPI.getServerLibrary(); - library.shardTypes().put(ScatteredShards.id("visitor"), ShardType.VISITOR); - library.shardTypes().put(ScatteredShards.id("challenge"), ShardType.CHALLENGE); - library.shardTypes().put(ScatteredShards.id("secret"), ShardType.SECRET); - library.shardTypes().put(ShardType.MISSING_ID, ShardType.MISSING); } public static ShardLibraryPersistentState createFromNbt(NbtCompound tag) { @@ -48,27 +37,8 @@ public static ShardLibraryPersistentState createFromNbt(NbtCompound tag) { // This is just a placeholder - all the data lives in the serverLibrary below ShardLibrary library = ScatteredShardsAPI.getServerLibrary(); - library.clearAll(); - - NbtCompound shardTypes = tag.getCompound(SHARD_TYPES_KEY); - if (shardTypes.isEmpty() || (shardTypes.getSize() == 1 && shardTypes.contains(ShardType.MISSING_ID.toString()))) { - //Either the ShardTypes were completely empty, or the only ShardType present is the missing type. - - //TODO: Load shardTypes from resources - //For now, we're preloading with the default types if none are present. - addDefaultShardTypes(); - state.markDirty(); - } else { - for(String id : shardTypes.getKeys()) { - try { - NbtCompound shardNbt = shardTypes.getCompound(id); - library.shardTypes().put(new Identifier(id), ShardType.fromNbt(shardNbt)); - - } catch (Throwable t) { - ScatteredShards.LOGGER.error("Could not load shardType \""+id+"\": " + t.getMessage()); - } - } - } + library.shards().clear(); + library.shardSets().clear(); NbtCompound shards = tag.getCompound(SHARDS_KEY); for(String id : shards.getKeys()) { @@ -99,11 +69,7 @@ public static ShardLibraryPersistentState createFromNbt(NbtCompound tag) { } } - if (library.shardTypes().size() == 1 && library.shardTypes().streamKeys().findFirst().get().equals(ShardType.MISSING_ID)) { - - } - - ScatteredShards.LOGGER.info("Loaded " + library.shardTypes().size() + " shard types, " + library.shards().size() + " shards, and " + library.shardSets().size() + " shardSets."); + ScatteredShards.LOGGER.info("Loaded " + library.shards().size() + " shards and " + library.shardSets().size() + " shardSets."); return state; } @@ -112,9 +78,8 @@ public static ShardLibraryPersistentState createFromNbt(NbtCompound tag) { @Override public NbtCompound writeNbt(NbtCompound tag) { ShardLibrary library = ScatteredShardsAPI.getServerLibrary(); - ScatteredShards.LOGGER.info("Saving the ShardLibrary with " + library.shardTypes().size() + " shard types, " + library.shards().size() + " shards, and " + library.shardSets().size() + " shardSets..."); + ScatteredShards.LOGGER.info("Saving the ShardLibrary with " + library.shards().size() + " shards and " + library.shardSets().size() + " shardSets..."); - tag.put(SHARD_TYPES_KEY, library.shardTypes().toNbt()); tag.put(SHARDS_KEY, library.shards().toNbt()); NbtCompound shardSets = new NbtCompound(); diff --git a/src/main/java/net/modfest/scatteredshards/api/shard/Shard.java b/src/main/java/net/modfest/scatteredshards/api/shard/Shard.java index d6ff1b4..4eaac82 100644 --- a/src/main/java/net/modfest/scatteredshards/api/shard/Shard.java +++ b/src/main/java/net/modfest/scatteredshards/api/shard/Shard.java @@ -29,12 +29,12 @@ public class Shard { public static final Codec> ICON_CODEC = Codec.either(ItemStack.CODEC, Identifier.CODEC); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("shardTypeId").forGetter(Shard::shardTypeId), + Identifier.CODEC.fieldOf("shard_type_id").forGetter(Shard::shardTypeId), TextCodecs.CODEC.fieldOf("name").forGetter(Shard::name), TextCodecs.CODEC.fieldOf("lore").forGetter(Shard::lore), TextCodecs.CODEC.fieldOf("hint").forGetter(Shard::hint), TextCodecs.CODEC.fieldOf("source").forGetter(Shard::source), - Identifier.CODEC.fieldOf("sourceId").forGetter(Shard::sourceId), + Identifier.CODEC.fieldOf("source_id").forGetter(Shard::sourceId), ICON_CODEC.fieldOf("icon").forGetter(Shard::icon) ).apply(instance, Shard::new)); diff --git a/src/main/java/net/modfest/scatteredshards/api/shard/ShardType.java b/src/main/java/net/modfest/scatteredshards/api/shard/ShardType.java index adb94f5..42260cc 100644 --- a/src/main/java/net/modfest/scatteredshards/api/shard/ShardType.java +++ b/src/main/java/net/modfest/scatteredshards/api/shard/ShardType.java @@ -10,32 +10,29 @@ import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtOps; import net.minecraft.particle.ParticleType; -import net.minecraft.particle.ParticleTypes; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.sound.SoundEvent; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.modfest.scatteredshards.ScatteredShards; +import net.modfest.scatteredshards.api.impl.ColorCodec; -public record ShardType(int textColor, int glowColor, Optional> collectParticle, Optional collectSound) { +public record ShardType(int textColor, int glowColor, Optional> collectParticle, Optional collectSound, int listOrder) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Codec.INT.fieldOf("textColor").forGetter(ShardType::textColor), - Codec.INT.fieldOf("glowColor").forGetter(ShardType::glowColor), - Codec.optionalField("collectParticle", Registries.PARTICLE_TYPE.getCodec()).forGetter(ShardType::collectParticle), - Codec.optionalField("collectSound", SoundEvent.CODEC).forGetter(ShardType::collectSound) + ColorCodec.CODEC.fieldOf("text_color").forGetter(ShardType::textColor), + ColorCodec.CODEC.fieldOf("glow_color").forGetter(ShardType::glowColor), + Codec.optionalField("collect_particle", Registries.PARTICLE_TYPE.getCodec()).forGetter(ShardType::collectParticle), + Codec.optionalField("collect_sound", SoundEvent.CODEC).forGetter(ShardType::collectSound), + Codec.INT.fieldOf("list_order").forGetter(ShardType::listOrder) ).apply(instance, ShardType::new)); public static final SoundEvent COLLECT_VISITOR_SOUND = SoundEvent.of(ScatteredShards.id("collect_visitor")); public static final SoundEvent COLLECT_CHALLENGE_SOUND = SoundEvent.of(ScatteredShards.id("collect_challenge")); public static final SoundEvent COLLECT_SECRET_SOUND = SoundEvent.of(ScatteredShards.id("collect_secret")); - - public static final ShardType VISITOR = new ShardType(0x6DE851, 0x00FF48, Optional.of(ParticleTypes.TOTEM_OF_UNDYING), Optional.of(COLLECT_VISITOR_SOUND)); - public static final ShardType CHALLENGE = new ShardType(0x5174E8, 0x0026FF, Optional.of(ParticleTypes.GLOW), Optional.of(COLLECT_CHALLENGE_SOUND)); - public static final ShardType SECRET = new ShardType(0xEB4034, 0xFF0088, Optional.of(ParticleTypes.WITCH), Optional.of(COLLECT_SECRET_SOUND)); - public static final ShardType MISSING = new ShardType(0xFFFFFF, 0xFF00FF, Optional.empty(), Optional.empty()); + public static final ShardType MISSING = new ShardType(0xFFFFFF, 0xFF00FF, Optional.empty(), Optional.empty(), -1); public static final Identifier MISSING_ID = ScatteredShards.id("missing"); public static Identifier createModId(Identifier shardTypeId, String modId) { @@ -58,8 +55,8 @@ public static Identifier getMiniFrontTexture(Identifier id) { return getTexture(id, "mini_front"); } - public static Identifier getMiniBackTexture(Identifier id) { - return getTexture(id, "mini_back"); + public static Identifier getMiniBackingTexture(Identifier id) { + return getTexture(id, "mini_backing"); } public static Text getDescription(Identifier id) { diff --git a/src/main/java/net/modfest/scatteredshards/client/ScatteredShardsClient.java b/src/main/java/net/modfest/scatteredshards/client/ScatteredShardsClient.java index b01789f..d217121 100644 --- a/src/main/java/net/modfest/scatteredshards/client/ScatteredShardsClient.java +++ b/src/main/java/net/modfest/scatteredshards/client/ScatteredShardsClient.java @@ -6,6 +6,7 @@ import net.minecraft.client.toast.SystemToast; import net.minecraft.client.toast.Toast; +import net.minecraft.sound.SoundEvents; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.modfest.scatteredshards.ScatteredShards; @@ -14,6 +15,7 @@ import net.modfest.scatteredshards.api.ScatteredShardsAPI; import net.modfest.scatteredshards.api.shard.Shard; import net.modfest.scatteredshards.api.shard.ShardType; +import net.modfest.scatteredshards.client.screen.ShardTabletGuiDescription; import net.modfest.scatteredshards.networking.ScatteredShardsNetworking; public class ScatteredShardsClient implements ClientModInitializer { @@ -56,8 +58,19 @@ public static void triggerShardModificationToast(Identifier shardId, boolean suc var toast = new SystemToast( SystemToast.Type.PERIODIC_NOTIFICATION, Text.translatable(SHARD_MODIFY_TOAST_KEY + ".title"), - Text.translatable(SHARD_MODIFY_TOAST_KEY + "." + (success ? "success" : "fail"), shardId) + Text.stringifiedTranslatable(SHARD_MODIFY_TOAST_KEY + "." + (success ? "success" : "fail"), shardId) ); MinecraftClient.getInstance().getToastManager().add(toast); } + + public static void openShardTablet() { + final var client = MinecraftClient.getInstance(); + client.send(() -> { + final var library = ScatteredShardsAPI.getClientLibrary(); + final var collection = ScatteredShardsAPI.getClientCollection(); + + client.setScreen(new ShardTabletGuiDescription.Screen(collection, library)); + client.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.ITEM_BOOK_PAGE_TURN, 1.0f, 1.0f)); + }); + } } diff --git a/src/main/java/net/modfest/scatteredshards/client/command/ClientShardCommand.java b/src/main/java/net/modfest/scatteredshards/client/command/ClientShardCommand.java index abfe33d..37d7b26 100644 --- a/src/main/java/net/modfest/scatteredshards/client/command/ClientShardCommand.java +++ b/src/main/java/net/modfest/scatteredshards/client/command/ClientShardCommand.java @@ -28,13 +28,11 @@ public class ClientShardCommand { private static DynamicCommandExceptionType createInvalidException(String item) { return new DynamicCommandExceptionType( - obj -> Text.translatable("error.scattered_shards.invalid_" + item, obj) + obj -> Text.stringifiedTranslatable("error.scattered_shards.invalid_" + item, obj) ); } private static final DynamicCommandExceptionType INVALID_SET_ID = createInvalidException("set_id"); - //We've removed checks for invalid modid's so people can use shards not related to them - //private static final DynamicCommandExceptionType INVALID_MOD_ID = createInvalidException("mod_id"); private static final DynamicCommandExceptionType INVALID_SHARD_TYPE = createInvalidException("shard_type"); private static final DynamicCommandExceptionType INVALID_SHARD_ID = createInvalidException("shard_id"); @@ -94,7 +92,9 @@ public static CompletableFuture suggestShards(CommandContext suggestShardTypes(CommandContext context, SuggestionsBuilder builder) { ScatteredShardsAPI.getClientLibrary().shardTypes().forEach((id, shardSet) -> { - builder.suggest(id.toString()); + if (!id.equals(ShardType.MISSING_ID)) { + builder.suggest(id.toString()); + } }); return builder.buildFuture(); } diff --git a/src/main/java/net/modfest/scatteredshards/client/screen/widget/WMiniShard.java b/src/main/java/net/modfest/scatteredshards/client/screen/widget/WMiniShard.java index a91655d..4d3abda 100644 --- a/src/main/java/net/modfest/scatteredshards/client/screen/widget/WMiniShard.java +++ b/src/main/java/net/modfest/scatteredshards/client/screen/widget/WMiniShard.java @@ -42,7 +42,7 @@ public WMiniShard setShardConsumer(Consumer onClick) { @Environment(EnvType.CLIENT) @Override public void paint(DrawContext context, int x, int y, int mouseX, int mouseY) { - Identifier tex = (isCollected) ? ShardType.getMiniFrontTexture(shard.shardTypeId()) : ShardType.getMiniBackTexture(shard.shardTypeId()); + Identifier tex = (isCollected) ? ShardType.getMiniFrontTexture(shard.shardTypeId()) : ShardType.getMiniBackingTexture(shard.shardTypeId()); int color = (isCollected) ? 0xFF_FFFFFF : 0xFF_668866; float opacity = (isCollected) ? 1.0f : 0.6f; ScreenDrawing.texturedRect(context, x, y, 12, 16, tex, color, opacity); diff --git a/src/main/java/net/modfest/scatteredshards/client/screen/widget/WShardSetPanel.java b/src/main/java/net/modfest/scatteredshards/client/screen/widget/WShardSetPanel.java index ec22316..bd374c2 100644 --- a/src/main/java/net/modfest/scatteredshards/client/screen/widget/WShardSetPanel.java +++ b/src/main/java/net/modfest/scatteredshards/client/screen/widget/WShardSetPanel.java @@ -8,6 +8,7 @@ import net.modfest.scatteredshards.api.ShardCollection; import net.modfest.scatteredshards.api.ShardLibrary; import net.modfest.scatteredshards.api.shard.Shard; +import net.modfest.scatteredshards.api.shard.ShardType; import net.modfest.scatteredshards.client.screen.widget.scalable.WScaledLabel; import java.util.List; @@ -52,7 +53,21 @@ public int layoutHeight() { public void setShardSet(Identifier setId, ShardLibrary library, ShardCollection collection) { List shardSet = new ArrayList<>(); shardSet.addAll(library.shardSets().get(setId)); - shardSet.sort(WShardSetPanel::shardComparator); + shardSet.sort((a, b) -> { + int aPriority = library.shards().get(a) + .map(it -> it.shardTypeId()) + .flatMap(library.shardTypes()::get) + .map(ShardType::listOrder) + .orElse(Integer.MAX_VALUE); + + int bPriority = library.shards().get(b) + .map(it -> it.shardTypeId()) + .flatMap(library.shardTypes()::get) + .map(ShardType::listOrder) + .orElse(Integer.MAX_VALUE); + + return Integer.compare(aPriority, bPriority); + }); //Add/dump MiniShards till we have the same number of card icons as the shardSet has cards while(shards.size() > shardSet.size()) shards.remove(shards.size()-1); @@ -81,6 +96,7 @@ public void setShardSet(Identifier setId, ShardLibrary library, ShardCollection if (host != null) this.validate(host); } + /* //TODO: Replace with json / ShardType field private static int shardPriority(String path) { return switch(path) { @@ -92,6 +108,7 @@ private static int shardPriority(String path) { } private static int shardComparator(Identifier a, Identifier b) { + return Integer.compare(shardPriority(a.getPath()), shardPriority(b.getPath())); - } + }*/ } diff --git a/src/main/java/net/modfest/scatteredshards/command/AwardCommand.java b/src/main/java/net/modfest/scatteredshards/command/AwardCommand.java index f719d1d..7319b3b 100644 --- a/src/main/java/net/modfest/scatteredshards/command/AwardCommand.java +++ b/src/main/java/net/modfest/scatteredshards/command/AwardCommand.java @@ -31,9 +31,9 @@ public static int award(CommandContext ctx) throws CommandS final int collected = i; if (collected == 0) { - ctx.getSource().sendFeedback(() -> Text.translatable("commands.scattered_shards.shard.award.none", shardId), false); + ctx.getSource().sendFeedback(() -> Text.stringifiedTranslatable("commands.scattered_shards.shard.award.none", shardId), false); } else { - ctx.getSource().sendFeedback(() -> Text.translatable("commands.scattered_shards.shard.award", shardId, collected), false); + ctx.getSource().sendFeedback(() -> Text.stringifiedTranslatable("commands.scattered_shards.shard.award", shardId, collected), false); } return collected; diff --git a/src/main/java/net/modfest/scatteredshards/command/BlockCommand.java b/src/main/java/net/modfest/scatteredshards/command/BlockCommand.java index 9e2eb4c..d65f987 100644 --- a/src/main/java/net/modfest/scatteredshards/command/BlockCommand.java +++ b/src/main/java/net/modfest/scatteredshards/command/BlockCommand.java @@ -35,7 +35,7 @@ public static int blockCommand(CommandContext ctx, boolean if (!player.giveItemStack(stack)) throw ShardCommand.NO_ROOM_FOR_ITEM.create(ScatteredShardsContent.SHARD_BLOCK_ITEM.getName()); - ctx.getSource().sendFeedback(() -> Text.translatable("commands.scattered_shards.shard.block", shardId), false); + ctx.getSource().sendFeedback(() -> Text.stringifiedTranslatable("commands.scattered_shards.shard.block", shardId), false); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/net/modfest/scatteredshards/command/CollectCommand.java b/src/main/java/net/modfest/scatteredshards/command/CollectCommand.java index 597e6c6..edc84cb 100644 --- a/src/main/java/net/modfest/scatteredshards/command/CollectCommand.java +++ b/src/main/java/net/modfest/scatteredshards/command/CollectCommand.java @@ -24,7 +24,7 @@ public static int collect(CommandContext ctx) throws Comman //Validate that source is a player and collect it ScatteredShardsAPI.triggerShardCollection(ctx.getSource().getPlayerOrThrow(), id); - ctx.getSource().sendFeedback(() -> Text.translatable("commands.scattered_shards.shard.collect", id), false); + ctx.getSource().sendFeedback(() -> Text.stringifiedTranslatable("commands.scattered_shards.shard.collect", id), false); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/net/modfest/scatteredshards/command/LibraryCommand.java b/src/main/java/net/modfest/scatteredshards/command/LibraryCommand.java index 969da16..ace267d 100644 --- a/src/main/java/net/modfest/scatteredshards/command/LibraryCommand.java +++ b/src/main/java/net/modfest/scatteredshards/command/LibraryCommand.java @@ -35,7 +35,7 @@ public static int delete(CommandContext ctx) throws Command ShardLibraryPersistentState.get(server).markDirty(); S2CDeleteShard.sendToAll(server, shardId); - ctx.getSource().sendFeedback(() -> Text.translatable("commands.scattered_shards.shard.library.delete", shardId), true); + ctx.getSource().sendFeedback(() -> Text.stringifiedTranslatable("commands.scattered_shards.shard.library.delete", shardId), true); return Command.SINGLE_SUCCESS; } @@ -49,7 +49,7 @@ public static int deleteAll(CommandContext ctx) throws Comm ShardLibraryPersistentState.get(server).markDirty(); S2CSyncLibrary.sendToAll(server); - ctx.getSource().sendFeedback(() -> Text.translatable("commands.scattered_shards.shard.library.delete.all", toDelete), true); + ctx.getSource().sendFeedback(() -> Text.stringifiedTranslatable("commands.scattered_shards.shard.library.delete.all", toDelete), true); return toDelete; } diff --git a/src/main/java/net/modfest/scatteredshards/command/ShardCommand.java b/src/main/java/net/modfest/scatteredshards/command/ShardCommand.java index 65b8f77..deaeeda 100644 --- a/src/main/java/net/modfest/scatteredshards/command/ShardCommand.java +++ b/src/main/java/net/modfest/scatteredshards/command/ShardCommand.java @@ -7,7 +7,7 @@ public class ShardCommand { public static final DynamicCommandExceptionType INVALID_SHARD = new DynamicCommandExceptionType( - it -> Text.translatable("error.scattered_shards.invalid_shard_id", it) + it -> Text.stringifiedTranslatable("error.scattered_shards.invalid_shard_id", it) ); public static final DynamicCommandExceptionType NO_ROOM_FOR_ITEM = new DynamicCommandExceptionType( diff --git a/src/main/java/net/modfest/scatteredshards/command/UncollectCommand.java b/src/main/java/net/modfest/scatteredshards/command/UncollectCommand.java index 65b82d5..aa7dbde 100644 --- a/src/main/java/net/modfest/scatteredshards/command/UncollectCommand.java +++ b/src/main/java/net/modfest/scatteredshards/command/UncollectCommand.java @@ -19,7 +19,7 @@ public class UncollectCommand { public static final DynamicCommandExceptionType NOT_IN_COLLECTION = new DynamicCommandExceptionType( - it -> Text.translatable("error.scattered_shards.shard_not_in_collection", it) + it -> Text.stringifiedTranslatable("error.scattered_shards.shard_not_in_collection", it) ); /** @@ -39,7 +39,7 @@ public static int uncollect(CommandContext ctx) throws Comm ShardCollectionPersistentState.get(server).markDirty(); S2CUncollectShard.send(player, id); - ctx.getSource().sendFeedback(() -> Text.translatable("commands.scattered_shards.shard.uncollect", id), false); + ctx.getSource().sendFeedback(() -> Text.stringifiedTranslatable("commands.scattered_shards.shard.uncollect", id), false); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/net/modfest/scatteredshards/item/ShardTablet.java b/src/main/java/net/modfest/scatteredshards/item/ShardTablet.java index 39aa489..03f136b 100644 --- a/src/main/java/net/modfest/scatteredshards/item/ShardTablet.java +++ b/src/main/java/net/modfest/scatteredshards/item/ShardTablet.java @@ -2,17 +2,13 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.sound.SoundEvents; import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; import net.minecraft.world.World; -import net.modfest.scatteredshards.api.ScatteredShardsAPI; -import net.modfest.scatteredshards.client.screen.ShardTabletGuiDescription; +import net.modfest.scatteredshards.client.ScatteredShardsClient; public class ShardTablet extends Item { @@ -24,14 +20,7 @@ public ShardTablet(Settings settings) { // TODO: sneak interact on another player opens their collection @Override public TypedActionResult use(World world, PlayerEntity user, Hand hand) { - final var client = MinecraftClient.getInstance(); - client.send(() -> { - final var library = ScatteredShardsAPI.getClientLibrary(); - final var collection = ScatteredShardsAPI.getClientCollection(); - - client.setScreen(new ShardTabletGuiDescription.Screen(collection, library)); - client.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.ITEM_BOOK_PAGE_TURN, 1.0f, 1.0f)); - }); + ScatteredShardsClient.openShardTablet(); return TypedActionResult.success(user.getStackInHand(hand)); } } diff --git a/src/main/java/net/modfest/scatteredshards/load/ShardTypeLoader.java b/src/main/java/net/modfest/scatteredshards/load/ShardTypeLoader.java index 6f50668..5c4acbe 100644 --- a/src/main/java/net/modfest/scatteredshards/load/ShardTypeLoader.java +++ b/src/main/java/net/modfest/scatteredshards/load/ShardTypeLoader.java @@ -3,6 +3,8 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; + +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.minecraft.resource.JsonDataLoader; @@ -12,20 +14,18 @@ import net.minecraft.util.JsonHelper; import net.minecraft.util.profiler.Profiler; import net.modfest.scatteredshards.ScatteredShards; +import net.modfest.scatteredshards.api.ScatteredShardsAPI; import net.modfest.scatteredshards.api.shard.ShardType; +import net.modfest.scatteredshards.networking.S2CSyncLibrary; import org.jetbrains.annotations.NotNull; -import java.util.HashMap; import java.util.Map; -@Deprecated public class ShardTypeLoader extends JsonDataLoader implements IdentifiableResourceReloadListener { public static final String TYPE = "shard_type"; public static final Identifier ID = ScatteredShards.id(TYPE); - public static final Map MAP = new HashMap<>(); - public ShardTypeLoader() { super(new Gson(), TYPE); } @@ -37,23 +37,41 @@ public ShardTypeLoader() { @Override protected void apply(Map cache, ResourceManager manager, Profiler profiler) { - MAP.clear(); + var library = ScatteredShardsAPI.getServerLibrary(); + + library.shardTypes().clear(); + library.shardTypes().put(ShardType.MISSING_ID, ShardType.MISSING); + + + int successes = 0; for (var entry : cache.entrySet()) { try { - JsonObject obj = JsonHelper.asObject(entry.getValue(), "shard type object"); - MAP.put(entry.getKey(), ShardType.fromJson(obj)); - successes++; + JsonObject root = JsonHelper.asObject(entry.getValue(), "root element"); + + if (root.has("text_color")) { + library.shardTypes().put(entry.getKey(), ShardType.fromJson(root)); + successes++; + } else { + for(var shardEntry : root.entrySet()) { + JsonObject shardTypeObj = JsonHelper.asObject(shardEntry.getValue(), "shard-type object"); + library.shardTypes().put(new Identifier(shardEntry.getKey()), ShardType.fromJson(shardTypeObj)); + successes++; + } + } } catch (Exception ex) { ScatteredShards.LOGGER.error("Failed to load shard type '" + entry.getKey() + "':", ex); } } ScatteredShards.LOGGER.info("Loaded " + successes + " shard type" + (successes == 1 ? "" : "s")); - //TODO: Sync this if we're live - //ScatteredShardsAPIImpl.updateShardTypes(); } public static void register() { ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new ShardTypeLoader()); + ServerLifecycleEvents.END_DATA_PACK_RELOAD.register((server, resourceManager, success) -> { + if (server != null) { + S2CSyncLibrary.sendToAll(server); + } + }); } } diff --git a/src/main/resources/assets/scattered_shards/lang/en_us.json b/src/main/resources/assets/scattered_shards/lang/en_us.json index ef8dff1..b1ceb90 100644 --- a/src/main/resources/assets/scattered_shards/lang/en_us.json +++ b/src/main/resources/assets/scattered_shards/lang/en_us.json @@ -5,9 +5,6 @@ "error.scattered_shards.invalid_shard_id": "Unknown shard '%s'", "error.scattered_shards.no_inventory_room": "There's no inventory room for this %s", "error.scattered_shards.shard_not_in_collection": "Shard '%s' was not in your collection", - "shard_type.scattered_shards.visitor.description": "Visitor Shard", - "shard_type.scattered_shards.challenge.description": "Challenge Shard", - "shard_type.scattered_shards.secret.description": "Secret Shard", "shard_type.scattered_shards.missing.description": "Missing Shard", "scattered_shards.toast.collect": "Shard Collected!", "argument.scattered_shards.shard.invalid": "Unknown shard '%s'", diff --git a/src/main/resources/resourcepacks/test/data/scattered_shards/shard_set/test.json b/src/main/resources/resourcepacks/test/data/scattered_shards/shard_set/test.json deleted file mode 100644 index f8cda75..0000000 --- a/src/main/resources/resourcepacks/test/data/scattered_shards/shard_set/test.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "bruh_mod:visitor": { - "shard_type": "scattered_shards:visitor", - "name": "Booth Visitor Blah Blah Blah Blah", - "lore": "Thanks for visiting my booth", - "hint": "Visit the booth :P", - "icon": { - "id": "minecraft:iron_block", - "Count": 1 - } - }, - "bruh_mod:challenge": { - "shard_type": "scattered_shards:challenge", - "name": "Conqueror", - "lore": "Lots of jumping required", - "hint": "Reach the top of the parkour", - "icon": { - "id": "minecraft:diamond_boots", - "Count": 1 - } - }, - "bruh_mod:secret": { - "shard_type": "scattered_shards:secret", - "name": "Here I lie", - "lore": "The terrible truth", - "hint": "Find the secret underground dungeon", - "icon": "bruh_mod:shard/dungeon.png" - } -} diff --git a/src/main/resources/resourcepacks/test/pack.mcmeta b/src/main/resources/resourcepacks/test/pack.mcmeta deleted file mode 100644 index 977497a..0000000 --- a/src/main/resources/resourcepacks/test/pack.mcmeta +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pack": { - "pack_format": 10, - "description": "Scattered Shards test data pack" - } -} \ No newline at end of file