diff --git a/src/main/java/at/petrak/hexcasting/api/circle/BlockEntityAbstractImpetus.java b/src/main/java/at/petrak/hexcasting/api/circle/BlockEntityAbstractImpetus.java index f6a8a93d..85e76a30 100644 --- a/src/main/java/at/petrak/hexcasting/api/circle/BlockEntityAbstractImpetus.java +++ b/src/main/java/at/petrak/hexcasting/api/circle/BlockEntityAbstractImpetus.java @@ -55,7 +55,8 @@ public abstract class BlockEntityAbstractImpetus extends PaucalBlockEntity imple TAG_NEXT_BLOCK = "next_block", TAG_TRACKED_BLOCKS = "tracked_blocks", TAG_FOUND_ALL = "found_all", - TAG_MANA = "mana"; + TAG_MANA = "mana", + TAG_LAST_MISHAP = "last_mishap"; @Nullable private UUID activator = null; @@ -67,6 +68,8 @@ public abstract class BlockEntityAbstractImpetus extends PaucalBlockEntity imple private List trackedBlocks = null; private transient Set knownBlocks = null; private boolean foundAll = false; + @Nullable + private Component lastMishap = null; private int mana = 0; private final LazyOptional inventoryHandlerLazy; @@ -86,6 +89,15 @@ public abstract class BlockEntityAbstractImpetus extends PaucalBlockEntity imple this.mana = mana; } + @Nullable + public Component getLastMishap() { + return lastMishap; + } + + public void setLastMishap(@Nullable Component lastMishap) { + this.lastMishap = lastMishap; + } + public void activateSpellCircle(ServerPlayer activator) { if (this.nextBlock != null) { return; @@ -106,14 +118,18 @@ public abstract class BlockEntityAbstractImpetus extends PaucalBlockEntity imple public List> getScryingLensOverlay(BlockState state, BlockPos pos, LocalPlayer observer, ClientLevel world, InteractionHand lensHand) { + var out = new ArrayList>(); if (world.getBlockEntity(pos) instanceof BlockEntityAbstractImpetus beai) { var dustCount = (float) beai.getMana() / (float) HexConfig.dustManaAmount.get(); - var tc = new TranslatableComponent("hexcasting.tooltip.lens.impetus.mana", + var dustCmp = new TranslatableComponent("hexcasting.tooltip.lens.impetus.mana", String.format("%.2f", dustCount)); - return new ArrayList<>(List.of(new Pair<>(new ItemStack(HexItems.AMETHYST_DUST.get()), tc))); - } else { - return new ArrayList<>(); + out.add(new Pair<>(new ItemStack(HexItems.AMETHYST_DUST.get()), dustCmp)); + + if (this.lastMishap != null) { + out.add(new Pair<>(new ItemStack(HexItems.SCRYING_LENS.get()), this.lastMishap)); + } } + return out; } @NotNull @@ -145,7 +161,11 @@ public abstract class BlockEntityAbstractImpetus extends PaucalBlockEntity imple } tag.put(TAG_TRACKED_BLOCKS, trackeds); } + tag.putInt(TAG_MANA, this.mana); + if (this.lastMishap != null) { + tag.putString(TAG_LAST_MISHAP, Component.Serializer.toJson(this.lastMishap)); + } } @Override @@ -167,6 +187,9 @@ public abstract class BlockEntityAbstractImpetus extends PaucalBlockEntity imple } this.mana = tag.getInt(TAG_MANA); + if (tag.contains(TAG_LAST_MISHAP)) { + this.lastMishap = Component.Serializer.fromJson(tag.getString(TAG_LAST_MISHAP)); + } } void stepCircle() { diff --git a/src/main/java/at/petrak/hexcasting/client/HexAdditionalRenderers.java b/src/main/java/at/petrak/hexcasting/client/HexAdditionalRenderers.java index befdc015..f2e40e33 100644 --- a/src/main/java/at/petrak/hexcasting/client/HexAdditionalRenderers.java +++ b/src/main/java/at/petrak/hexcasting/client/HexAdditionalRenderers.java @@ -15,6 +15,8 @@ import com.mojang.math.Vector3f; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.locale.Language; +import net.minecraft.network.chat.Style; import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.phys.BlockHitResult; @@ -178,26 +180,33 @@ public class HexAdditionalRenderers { var lines = ScryingLensOverlayRegistry.getLines(bs, pos, mc.player, mc.level, lensHand); if (lines != null) { var window = mc.getWindow(); - var lineSpacing = 15f; - var totalHeight = lineSpacing * lines.size(); var x = window.getGuiScaledWidth() / 2f + 8f; - var y = window.getGuiScaledHeight() / 2f - totalHeight / 2f; + var y = window.getGuiScaledHeight() / 2f; ps.pushPose(); ps.translate(x, y, 0); + var maxWidth = (int) (window.getGuiScaledWidth() / 2f * 0.8f); + for (var pair : lines) { - ps.pushPose(); var stack = pair.getFirst(); if (stack != null) { // this draws centered in the Y ... RenderLib.renderItemStackInGui(ps, pair.getFirst(), 0, 0); } + float tx = stack == null ? 0 : 18; + float ty = 5; // but this draws where y=0 is the baseline - mc.font.drawShadow(ps, pair.getSecond(), stack == null ? 0 : 18, 5, 16777215); + var text = pair.getSecond(); + var textLines = mc.font.getSplitter().splitLines(text, maxWidth, Style.EMPTY); - ps.popPose(); - ps.translate(0, lineSpacing, 0); + for (var line : textLines) { + var actualLine = Language.getInstance().getVisualOrder(line); + mc.font.drawShadow(ps, actualLine, tx, ty, 0xffffffff); + ps.translate(0, 9, 0); + } + + ps.translate(0, 6, 0); } ps.popPose(); diff --git a/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt b/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt index 1723efaf..effd80fb 100644 --- a/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt +++ b/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt @@ -51,14 +51,14 @@ class GuiSpellcasting(private val handOpenedWith: InteractionHand) : Screen(Text PatternValidity.OK } - val sound = - if (info.wasPrevPatternInvalid) HexSounds.FAIL_PATTERN.get() else HexSounds.ADD_PATTERN.get() - Minecraft.getInstance().soundManager.play( - SimpleSoundInstance.forUI( - sound, - 1f + (Math.random().toFloat() - 0.5f) * 0.1f + if (!info.wasPrevPatternInvalid) { + Minecraft.getInstance().soundManager.play( + SimpleSoundInstance.forUI( + HexSounds.ADD_PATTERN.get(), + 1f + (Math.random().toFloat() - 0.5f) * 0.1f + ) ) - ) + } } override fun init() { diff --git a/src/main/java/at/petrak/hexcasting/common/casting/OperatorSideEffect.kt b/src/main/java/at/petrak/hexcasting/common/casting/OperatorSideEffect.kt index 5b062e8e..b12a0105 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/OperatorSideEffect.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/OperatorSideEffect.kt @@ -1,14 +1,17 @@ package at.petrak.hexcasting.common.casting +import at.petrak.hexcasting.api.circle.BlockEntityAbstractImpetus import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.spell.RenderedSpell import at.petrak.hexcasting.common.casting.colors.FrozenColorizer import at.petrak.hexcasting.common.casting.mishaps.Mishap import at.petrak.hexcasting.common.items.HexItems +import at.petrak.hexcasting.common.lib.HexSounds import at.petrak.hexcasting.common.lib.HexStatistics import at.petrak.hexcasting.datagen.HexAdvancements import net.minecraft.Util import net.minecraft.network.chat.TranslatableComponent +import net.minecraft.sounds.SoundSource import net.minecraft.world.item.DyeColor /** @@ -61,8 +64,17 @@ sealed class OperatorSideEffect { data class DoMishap(val mishap: Mishap, val errorCtx: Mishap.Context) : OperatorSideEffect() { override fun performEffect(harness: CastingHarness): Boolean { - // for now - harness.ctx.caster.sendMessage(mishap.errorMessage(harness.ctx, errorCtx), Util.NIL_UUID) + val msg = mishap.errorMessage(harness.ctx, errorCtx); + if (harness.ctx.spellCircle != null) { + val tile = harness.ctx.world.getBlockEntity(harness.ctx.spellCircle.impetusPos) + if (tile is BlockEntityAbstractImpetus) { + tile.lastMishap = msg + tile.setChanged() + } + } else { + // for now + harness.ctx.caster.sendMessage(msg, Util.NIL_UUID) + } val spray = mishap.particleSpray(harness.ctx) val color = mishap.accentColor(harness.ctx, errorCtx) @@ -72,6 +84,11 @@ sealed class OperatorSideEffect { FrozenColorizer(HexItems.DYE_COLORIZERS[DyeColor.RED]!!.get(), Util.NIL_UUID) ) + harness.ctx.world.playSound( + null, harness.ctx.position.x, harness.ctx.position.y, harness.ctx.position.z, + HexSounds.FAIL_PATTERN.get(), SoundSource.PLAYERS, 1f, 1f + ) + mishap.execute(harness.ctx, errorCtx, harness.stack) return true diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt index 081d4c04..80cbbb6a 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt @@ -6,8 +6,10 @@ import at.petrak.hexcasting.common.casting.CastingContext import at.petrak.hexcasting.common.casting.colors.FrozenColorizer import at.petrak.hexcasting.common.items.HexItems import at.petrak.hexcasting.hexmath.HexPattern +import net.minecraft.ChatFormatting import net.minecraft.Util import net.minecraft.network.chat.Component +import net.minecraft.network.chat.Style import net.minecraft.network.chat.TranslatableComponent import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.item.ItemEntity @@ -40,6 +42,7 @@ sealed class Mishap : Throwable() { protected fun actionName(action: ResourceLocation?): Component = TranslatableComponent("hexcasting.spell.${action ?: "unknown"}") + .setStyle(Style.EMPTY.withColor(ChatFormatting.LIGHT_PURPLE).withUnderlined(true)) protected fun yeetItem(stack: ItemStack, ctx: CastingContext, delta: Vec3) { val entity = ItemEntity( diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidIota.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidIota.kt index 0743cc1a..7cb2d5fc 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidIota.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidIota.kt @@ -37,8 +37,8 @@ class MishapInvalidIota( error( "invalid_value", actionName(errorCtx.action), - reverseIdx, expected, + reverseIdx, perpetrator.display() ) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNoSpellCircle.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNoSpellCircle.kt index 33369970..a71ccda8 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNoSpellCircle.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNoSpellCircle.kt @@ -11,7 +11,7 @@ class MishapNoSpellCircle : Mishap() { dyeColor(DyeColor.PURPLE) override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList>) { - ctx.caster.drop(true) + ctx.caster.inventory.dropAll() } override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component = diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNotEnoughArgs.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNotEnoughArgs.kt index 3ec54a4b..9ba01327 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNotEnoughArgs.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapNotEnoughArgs.kt @@ -12,7 +12,7 @@ class MishapNotEnoughArgs(val expected: Int, val got: Int) : Mishap() { dyeColor(DyeColor.LIGHT_GRAY) override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList>) { - for (i in expected until got) + for (i in got until expected) stack.add(SpellDatum.make(Widget.GARBAGE)) }