From 1da86cda06d03cf977c1f9ef1d8856bf691a547c Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 20 Nov 2021 16:40:23 +0200 Subject: [PATCH] Add a toast message when discovering traits --- .../magic/spell/trait/TraitDiscovery.java | 10 +- .../unicopia/client/DiscoveryToast.java | 105 ++++++++++++++++++ .../unicopia/network/Channel.java | 1 + .../unicopia/network/MsgUnlockTraits.java | 38 +++++++ .../network/handler/ClientNetworkHandler.java | 3 + .../handler/ClientNetworkHandlerImpl.java | 9 ++ .../resources/assets/unicopia/lang/en_us.json | 5 +- 7 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/client/DiscoveryToast.java create mode 100644 src/main/java/com/minelittlepony/unicopia/network/MsgUnlockTraits.java diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java index 8aa9b6a9..9ebf671a 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java @@ -10,6 +10,8 @@ import java.util.Set; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.network.Channel; +import com.minelittlepony.unicopia.network.MsgUnlockTraits; import com.minelittlepony.unicopia.util.NbtSerialisable; import net.fabricmc.api.EnvType; @@ -21,6 +23,7 @@ import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtString; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; @@ -56,12 +59,17 @@ public class TraitDiscovery implements NbtSerialisable { } SpellTraits traits = SpellTraits.of(item); items.put(Registry.ITEM.getId(item), traits); + Set newTraits = new HashSet<>(); traits.entries().forEach(e -> { if (this.traits.add(e.getKey())) { - unreadTraits.add(e.getKey()); + newTraits.add(e.getKey()); } }); + unreadTraits.addAll(newTraits); pony.setDirty(); + if (!newTraits.isEmpty() && !pony.getWorld().isClient) { + Channel.UNLOCK_TRAITS.send((ServerPlayerEntity)pony.getMaster(), new MsgUnlockTraits(newTraits)); + } } public SpellTraits getKnownTraits(Item item) { diff --git a/src/main/java/com/minelittlepony/unicopia/client/DiscoveryToast.java b/src/main/java/com/minelittlepony/unicopia/client/DiscoveryToast.java new file mode 100644 index 00000000..07c48e1b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/DiscoveryToast.java @@ -0,0 +1,105 @@ +package com.minelittlepony.unicopia.client; + +import com.minelittlepony.unicopia.item.UItems; +import com.mojang.blaze3d.systems.RenderSystem; + +import java.util.ArrayList; +import java.util.List; +import org.spongepowered.include.com.google.common.base.Objects; + +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.render.GameRenderer; +import net.minecraft.client.toast.Toast; +import net.minecraft.client.toast.ToastManager; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Identifier; + +public class DiscoveryToast implements Toast { + private static final long MAX_AGE = 5000L; + private static final Text TITLE = new TranslatableText("unicopia.toast.discoveries.title"); + private static final Text DESCRIPTION = new TranslatableText("unicopia.toast.discoveries.description"); + + private final List discoveries = new ArrayList<>(); + private long startTime; + + private boolean justUpdated; + + @Override + public Toast.Visibility draw(MatrixStack matrices, ToastManager manager, long startTime) { + if (justUpdated) { + this.startTime = startTime; + justUpdated = false; + } + + if (discoveries.isEmpty()) { + return Toast.Visibility.HIDE; + } + + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderTexture(0, TEXTURE); + RenderSystem.setShaderColor(1.0F, 1, 1, 1); + manager.drawTexture(matrices, 0, 0, 0, 32, getWidth(), getHeight()); + manager.getGame().textRenderer.draw(matrices, TITLE, 30, 7, -11534256); + manager.getGame().textRenderer.draw(matrices, DESCRIPTION, 30, 18, -16777216); + + Identifier icon = discoveries.get((int)(startTime / Math.max(1L, MAX_AGE / discoveries.size()) % discoveries.size())); + + MatrixStack matrixStack = RenderSystem.getModelViewStack(); + matrixStack.push(); + matrixStack.scale(0.6F, 0.6F, 1); + RenderSystem.applyModelViewMatrix(); + manager.getGame().getItemRenderer().renderInGui(UItems.SPELLBOOK.getDefaultStack(), 3, 3); + matrixStack.pop(); + RenderSystem.applyModelViewMatrix(); + + RenderSystem.setShaderTexture(0, icon); + DrawableHelper.drawTexture(matrices, 8, 8, 1, 0, 0, 16, 16, 16, 16); + + // manager.getGame().getItemRenderer().renderInGui(recipe.getOutput(), 8, 8); + + return startTime - this.startTime >= MAX_AGE ? Toast.Visibility.HIDE : Toast.Visibility.SHOW; + } + + public DiscoveryToast addDiscoveries(Identifier icon) { + if (!discoveries.contains(icon)) { + discoveries.add(icon); + } + justUpdated = true; + + return this; + } + + class Discovery { + final Identifier icon; + final Text description; + + Discovery(Identifier icon, Text description) { + this.icon = icon; + this.description = description; + } + + @Override + public boolean equals(Object o) { + return o instanceof Discovery + && Objects.equal(icon, ((Discovery) o).icon) + && Objects.equal(description, ((Discovery) o).description); + } + + @Override + public int hashCode() { + return Objects.hashCode(icon, description); + } + } + + public static void show(ToastManager manager, Identifier icon) { + DiscoveryToast existing = manager.getToast(DiscoveryToast.class, TYPE); + if (existing == null) { + manager.add(new DiscoveryToast().addDiscoveries(icon)); + } else { + existing.addDiscoveries(icon); + } + } +} + diff --git a/src/main/java/com/minelittlepony/unicopia/network/Channel.java b/src/main/java/com/minelittlepony/unicopia/network/Channel.java index 14f56ebe..e5fab51f 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/Channel.java +++ b/src/main/java/com/minelittlepony/unicopia/network/Channel.java @@ -17,6 +17,7 @@ public interface Channel { S2CPacketType SERVER_SPAWN_PROJECTILE = SimpleNetworking.serverToClient(new Identifier("unicopia", "projectile_entity"), MsgSpawnProjectile::new); S2CPacketType SERVER_BLOCK_DESTRUCTION = SimpleNetworking.serverToClient(new Identifier("unicopia", "block_destruction"), MsgBlockDestruction::new); S2CPacketType CANCEL_PLAYER_ABILITY = SimpleNetworking.serverToClient(new Identifier("unicopia", "player_ability_cancel"), MsgCancelPlayerAbility::new); + S2CPacketType UNLOCK_TRAITS = SimpleNetworking.serverToClient(new Identifier("unicopia", "unlock_traits"), MsgUnlockTraits::new); Identifier SERVER_SELECT_TRIBE_ID = new Identifier("unicopia", "select_tribe"); S2CPacketType SERVER_SELECT_TRIBE = SimpleNetworking.serverToClient(SERVER_SELECT_TRIBE_ID, MsgTribeSelect::new); diff --git a/src/main/java/com/minelittlepony/unicopia/network/MsgUnlockTraits.java b/src/main/java/com/minelittlepony/unicopia/network/MsgUnlockTraits.java new file mode 100644 index 00000000..7d9f55aa --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/network/MsgUnlockTraits.java @@ -0,0 +1,38 @@ +package com.minelittlepony.unicopia.network; + +import java.util.HashSet; +import java.util.Set; + +import com.minelittlepony.unicopia.InteractionManager; +import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; +import com.minelittlepony.unicopia.util.network.Packet; + +import net.minecraft.network.PacketByteBuf; +import net.minecraft.entity.player.PlayerEntity; + +public class MsgUnlockTraits implements Packet { + + public final Set traits = new HashSet<>(); + + MsgUnlockTraits(PacketByteBuf buffer) { + int length = buffer.readInt(); + for (int i = 0; i < length; i++) { + Trait.fromId(buffer.readIdentifier()).ifPresent(traits::add); + } + } + + public MsgUnlockTraits(Set traits) { + this.traits.addAll(traits); + } + + @Override + public void toBuffer(PacketByteBuf buffer) { + buffer.writeInt(traits.size()); + traits.forEach(trait -> buffer.writeIdentifier(trait.getId())); + } + + @Override + public void handle(PlayerEntity sender) { + InteractionManager.instance().getClientNetworkHandler().handleUnlockTraits(this); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandler.java b/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandler.java index c8080898..d1b1e2b0 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandler.java +++ b/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandler.java @@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.network.MsgBlockDestruction; import com.minelittlepony.unicopia.network.MsgCancelPlayerAbility; import com.minelittlepony.unicopia.network.MsgSpawnProjectile; import com.minelittlepony.unicopia.network.MsgTribeSelect; +import com.minelittlepony.unicopia.network.MsgUnlockTraits; public interface ClientNetworkHandler { @@ -14,4 +15,6 @@ public interface ClientNetworkHandler { void handleBlockDestruction(MsgBlockDestruction packet); void handleCancelAbility(MsgCancelPlayerAbility packet); + + void handleUnlockTraits(MsgUnlockTraits packet); } diff --git a/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandlerImpl.java b/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandlerImpl.java index ee478203..7c73abef 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandlerImpl.java +++ b/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandlerImpl.java @@ -1,13 +1,16 @@ package com.minelittlepony.unicopia.network.handler; import com.minelittlepony.unicopia.Owned; +import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.client.ClientBlockDestructionManager; +import com.minelittlepony.unicopia.client.DiscoveryToast; import com.minelittlepony.unicopia.client.gui.TribeSelectionScreen; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.network.MsgBlockDestruction; import com.minelittlepony.unicopia.network.MsgCancelPlayerAbility; import com.minelittlepony.unicopia.network.MsgSpawnProjectile; import com.minelittlepony.unicopia.network.MsgTribeSelect; +import com.minelittlepony.unicopia.network.MsgUnlockTraits; import net.minecraft.client.MinecraftClient; import net.minecraft.client.world.ClientWorld; @@ -59,4 +62,10 @@ public class ClientNetworkHandlerImpl implements ClientNetworkHandler { Pony.of(client.player).getAbilities().getStats().forEach(s -> s.setCooldown(0)); } + @Override + public void handleUnlockTraits(MsgUnlockTraits packet) { + for (Trait trait : packet.traits) { + DiscoveryToast.show(client.getToastManager(), trait.getSprite()); + } + } } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 90525967..279acba5 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -500,5 +500,8 @@ "advancements.unicopia.molting_season_2.description": "Drop 5 feathers whilst flying", "advancements.unicopia.molting_season_3.title": "Molting Season 3", - "advancements.unicopia.molting_season_3.description": "Drop 15 feathers whilst flying" + "advancements.unicopia.molting_season_3.description": "Drop 15 feathers whilst flying", + + "unicopia.toast.discoveries.title": "New Discoveries!", + "unicopia.toast.discoveries.description": "Check your spellbook" }