make the casting UI less of an eyesore maybe
This commit is contained in:
parent
8ea2a6d66d
commit
d80ace0812
29 changed files with 372 additions and 119 deletions
|
@ -25,7 +25,7 @@ interface Action {
|
|||
fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ interface ConstManaAction : Action {
|
|||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (this.argc > stack.size)
|
||||
|
@ -31,6 +31,6 @@ interface ConstManaAction : Action {
|
|||
|
||||
val sideEffects = mutableListOf<OperatorSideEffect>(OperatorSideEffect.ConsumeMana(this.manaCost))
|
||||
|
||||
return OperationResult(continuation, stack, local, sideEffects)
|
||||
return OperationResult(continuation, stack, ravenmind, sideEffects)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ import at.petrak.hexcasting.api.spell.iota.Iota
|
|||
data class OperationResult(
|
||||
val newContinuation: SpellContinuation,
|
||||
val newStack: List<Iota>,
|
||||
val newLocalIota: Iota,
|
||||
val newLocalIota: Iota?,
|
||||
val sideEffects: List<OperatorSideEffect>
|
||||
)
|
||||
|
|
|
@ -242,6 +242,8 @@ fun List<Iota>.getLongOrList(idx: Int, argc: Int = 0): Either<Long, SpellList> {
|
|||
)
|
||||
}
|
||||
|
||||
fun Iota?.orNull() = this ?: NullIota()
|
||||
|
||||
// TODO do we make this work on lists
|
||||
// there should probably be some way to abstract function application over lists, vecs, and numbers,
|
||||
// and i bet it's fucking monads
|
||||
|
|
|
@ -21,14 +21,14 @@ interface SpellAction : Action {
|
|||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (this.argc > stack.size)
|
||||
throw MishapNotEnoughArgs(this.argc, stack.size)
|
||||
val args = stack.takeLast(this.argc)
|
||||
for (_i in 0 until this.argc) stack.removeLast()
|
||||
val executeResult = this.execute(args, ctx) ?: return OperationResult(continuation, stack, local, listOf())
|
||||
val executeResult = this.execute(args, ctx) ?: return OperationResult(continuation, stack, ravenmind, listOf())
|
||||
val (spell, mana, particles) = executeResult
|
||||
|
||||
val sideEffects = mutableListOf<OperatorSideEffect>()
|
||||
|
@ -49,7 +49,7 @@ interface SpellAction : Action {
|
|||
for (spray in particles)
|
||||
sideEffects.add(OperatorSideEffect.Particles(spray))
|
||||
|
||||
return OperationResult(continuation, stack, local, sideEffects)
|
||||
return OperationResult(continuation, stack, ravenmind, sideEffects)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import at.petrak.hexcasting.api.spell.ParticleSpray
|
|||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import at.petrak.hexcasting.api.spell.iota.ListIota
|
||||
import at.petrak.hexcasting.api.spell.iota.NullIota
|
||||
import at.petrak.hexcasting.api.spell.iota.PatternIota
|
||||
import at.petrak.hexcasting.api.spell.math.HexDir
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
|
@ -35,7 +34,7 @@ import kotlin.math.min
|
|||
*/
|
||||
class CastingHarness private constructor(
|
||||
var stack: MutableList<Iota>,
|
||||
var ravenmind: Iota,
|
||||
var ravenmind: Iota?,
|
||||
var parenCount: Int,
|
||||
var parenthesized: List<Iota>,
|
||||
var escapeNext: Boolean,
|
||||
|
@ -47,7 +46,7 @@ class CastingHarness private constructor(
|
|||
constructor(
|
||||
ctx: CastingContext,
|
||||
prepackagedColorizer: FrozenColorizer? = null
|
||||
) : this(mutableListOf(), NullIota(), 0, mutableListOf(), false, ctx, prepackagedColorizer)
|
||||
) : this(mutableListOf(), null, 0, mutableListOf(), false, ctx, prepackagedColorizer)
|
||||
|
||||
/**
|
||||
* Execute a single iota.
|
||||
|
@ -79,14 +78,20 @@ class CastingHarness private constructor(
|
|||
}
|
||||
|
||||
if (continuation is SpellContinuation.NotDone) {
|
||||
lastResolutionType = if (lastResolutionType.success) ResolvedPatternType.EVALUATED else ResolvedPatternType.ERRORED
|
||||
lastResolutionType =
|
||||
if (lastResolutionType.success) ResolvedPatternType.EVALUATED else ResolvedPatternType.ERRORED
|
||||
}
|
||||
|
||||
val (stackDescs, parenDescs, ravenmind) = generateDescs()
|
||||
|
||||
return ControllerInfo(
|
||||
info.playSound,
|
||||
this.stack.isEmpty() && this.parenCount == 0 && !this.escapeNext,
|
||||
lastResolutionType,
|
||||
generateDescs()
|
||||
stackDescs,
|
||||
parenDescs,
|
||||
ravenmind,
|
||||
this.parenCount
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -248,7 +253,11 @@ class CastingHarness private constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun generateDescs() = stack.map(Iota::display)
|
||||
fun generateDescs() = Triple(
|
||||
stack.map(HexIotaTypes::serialize),
|
||||
parenthesized.map(HexIotaTypes::serialize),
|
||||
ravenmind?.let(HexIotaTypes::serialize)
|
||||
)
|
||||
|
||||
/**
|
||||
* Return the functional update represented by the current state (for use with `copy`)
|
||||
|
@ -459,7 +468,8 @@ class CastingHarness private constructor(
|
|||
fun serializeToNBT() = NBTBuilder {
|
||||
TAG_STACK %= stack.serializeToNBT()
|
||||
|
||||
TAG_LOCAL %= HexIotaTypes.serialize(ravenmind)
|
||||
if (ravenmind != null)
|
||||
TAG_LOCAL %= HexIotaTypes.serialize(ravenmind!!)
|
||||
TAG_PAREN_COUNT %= parenCount
|
||||
TAG_ESCAPE_NEXT %= escapeNext
|
||||
|
||||
|
@ -488,12 +498,15 @@ class CastingHarness private constructor(
|
|||
stack.add(datum)
|
||||
}
|
||||
|
||||
val localIota = HexIotaTypes.deserialize(nbt.getCompound(TAG_LOCAL), ctx.world)
|
||||
val ravenmind = if (nbt.contains(TAG_LOCAL))
|
||||
HexIotaTypes.deserialize(nbt.getCompound(TAG_LOCAL), ctx.world)
|
||||
else
|
||||
null
|
||||
|
||||
val parenthesized = mutableListOf<Iota>()
|
||||
val parenTag = nbt.getList(TAG_PARENTHESIZED, Tag.TAG_COMPOUND)
|
||||
for (subtag in parenTag) {
|
||||
parenthesized.add(HexIotaTypes.deserialize(nbt.getCompound(TAG_LOCAL), ctx.world))
|
||||
parenthesized.add(HexIotaTypes.deserialize(subtag.downcast(CompoundTag.TYPE), ctx.world))
|
||||
}
|
||||
|
||||
val parenCount = nbt.getInt(TAG_PAREN_COUNT)
|
||||
|
@ -505,7 +518,7 @@ class CastingHarness private constructor(
|
|||
null
|
||||
}
|
||||
|
||||
CastingHarness(stack, localIota, parenCount, parenthesized, escapeNext, ctx, colorizer)
|
||||
CastingHarness(stack, ravenmind, parenCount, parenthesized, escapeNext, ctx, colorizer)
|
||||
} catch (exn: Exception) {
|
||||
CastingHarness(ctx)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package at.petrak.hexcasting.api.spell.casting
|
||||
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
|
||||
/**
|
||||
* Information for the sake of the GUI.
|
||||
|
@ -9,5 +9,8 @@ data class ControllerInfo(
|
|||
val makesCastSound: Boolean,
|
||||
val isStackClear: Boolean,
|
||||
val resolutionType: ResolvedPatternType,
|
||||
val stackDesc: List<Component>
|
||||
val stack: List<CompoundTag>,
|
||||
val parenthesized: List<CompoundTag>,
|
||||
val ravenmind: CompoundTag?,
|
||||
val parenCount: Int,
|
||||
)
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package at.petrak.hexcasting.api.spell.iota;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
// Take notes from ForgeRegistryEntry
|
||||
public abstract class IotaType<T extends Iota> {
|
||||
|
@ -14,7 +17,7 @@ public abstract class IotaType<T extends Iota> {
|
|||
* The {@code type} key is given when registering the spell datum type; this method
|
||||
* deserializes the tag associated with {@code "datum"}.
|
||||
* <p>
|
||||
* Returning {@code null} makes the resulting datum be {@link at.petrak.hexcasting.api.spell.Widget Widget.NULL}.
|
||||
* Returning {@code null} makes the resulting datum be {@link NullIota}.
|
||||
* Throwing an exception raises a mishap.
|
||||
*/
|
||||
@Nullable
|
||||
|
@ -26,6 +29,15 @@ public abstract class IotaType<T extends Iota> {
|
|||
*/
|
||||
public abstract Component display(Tag tag);
|
||||
|
||||
/**
|
||||
* Get a display of this datum from the {@code data} tag, with a maximum width.
|
||||
* This is for use on the client.
|
||||
*/
|
||||
public List<FormattedCharSequence> displayWithWidth(Tag tag, int maxWidth, Font font) {
|
||||
var display = this.display(tag);
|
||||
return font.split(display, maxWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color associated with this datum type.
|
||||
*/
|
||||
|
|
|
@ -4,12 +4,15 @@ import at.petrak.hexcasting.api.spell.SpellList;
|
|||
import at.petrak.hexcasting.api.utils.HexUtils;
|
||||
import at.petrak.hexcasting.common.lib.HexIotaTypes;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
@ -111,6 +114,54 @@ public class ListIota extends Iota {
|
|||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FormattedCharSequence> displayWithWidth(Tag tag, int maxWidth, Font font) {
|
||||
// We aim to not break one iota between lines
|
||||
var listTag = HexUtils.downcast(tag, ListTag.TYPE);
|
||||
|
||||
var start = FormattedCharSequence.forward("[", Style.EMPTY.withColor(ChatFormatting.DARK_PURPLE));
|
||||
var cursor = font.width(start);
|
||||
var currentLine = new ArrayList<>(List.of(start));
|
||||
var out = new ArrayList<FormattedCharSequence>();
|
||||
|
||||
for (int i = 0; i < listTag.size(); i++) {
|
||||
Tag subtag = listTag.get(i);
|
||||
var cSubtag = HexUtils.downcast(subtag, CompoundTag.TYPE);
|
||||
var translation = HexIotaTypes.getDisplay(cSubtag);
|
||||
var currentElement = translation.getVisualOrderText();
|
||||
String addl;
|
||||
if (i < listTag.size() - 1) {
|
||||
addl = ", ";
|
||||
} else {
|
||||
// Last go-around, so add the closing bracket
|
||||
addl = "]";
|
||||
}
|
||||
currentElement = FormattedCharSequence.composite(currentElement,
|
||||
FormattedCharSequence.forward(addl, Style.EMPTY.withColor(ChatFormatting.DARK_PURPLE)));
|
||||
|
||||
var width = font.width(currentElement);
|
||||
|
||||
if (cursor + width > maxWidth) {
|
||||
out.add(FormattedCharSequence.composite(currentLine));
|
||||
currentLine = new ArrayList<>();
|
||||
// Indent further lines by two spaces
|
||||
var indentation = FormattedCharSequence.forward(" ", Style.EMPTY);
|
||||
var lineStart = FormattedCharSequence.composite(indentation, currentElement);
|
||||
currentLine.add(lineStart);
|
||||
cursor = font.width(lineStart);
|
||||
} else {
|
||||
currentLine.add(currentElement);
|
||||
cursor += width;
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentLine.isEmpty()) {
|
||||
out.add(FormattedCharSequence.composite(currentLine));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int color() {
|
||||
return 0xff_aa00aa;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@file:JvmName("RenderLib")
|
||||
|
||||
package at.petrak.hexcasting.client
|
||||
|
||||
import at.petrak.hexcasting.api.mod.HexConfig
|
||||
|
@ -205,8 +206,16 @@ fun makeZappy(points: List<Vec2>, hops: Int, variance: Float, speed: Float, flow
|
|||
// (We use i, j (segment #, subsegment #) as seeds for the Perlin noise,
|
||||
// and zSeed (i.e. time elapsed) to perturb the shape gradually over time)
|
||||
val minorPerturb = NOISE.getValue(i.toDouble(), j.toDouble(), sin(zSeed)) * flowIrregular
|
||||
val theta = (3 * NOISE.getValue(i.toDouble() + j.toDouble() / (hops + 1) + minorPerturb - zSeed, 1337.0, 0.0) * TAU).toFloat()
|
||||
val r = (NOISE.getValue(i.toDouble() + j.toDouble() / (hops + 1) - zSeed, 69420.0, 0.0) * maxVariance * scaleVariance(progress)).toFloat()
|
||||
val theta = (3 * NOISE.getValue(
|
||||
i.toDouble() + j.toDouble() / (hops + 1) + minorPerturb - zSeed,
|
||||
1337.0,
|
||||
0.0
|
||||
) * TAU).toFloat()
|
||||
val r = (NOISE.getValue(
|
||||
i.toDouble() + j.toDouble() / (hops + 1) - zSeed,
|
||||
69420.0,
|
||||
0.0
|
||||
) * maxVariance * scaleVariance(progress)).toFloat()
|
||||
val randomHop = Vec2(r * Mth.cos(theta), r * Mth.sin(theta))
|
||||
// Then record the new location.
|
||||
zappyPts.add(pos.add(randomHop))
|
||||
|
@ -339,3 +348,28 @@ fun renderEntity(
|
|||
immediate.endBatch()
|
||||
ms.popPose()
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure you have the `PositionColorShader` set
|
||||
*/
|
||||
fun renderQuad(
|
||||
ps: PoseStack, x: Float, y: Float, w: Float, h: Float, color: Int
|
||||
) {
|
||||
val mat = ps.last().pose()
|
||||
val tess = Tesselator.getInstance()
|
||||
val buf = tess.builder
|
||||
buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR)
|
||||
buf.vertex(mat, x, y, 0f)
|
||||
.color(color)
|
||||
.endVertex()
|
||||
buf.vertex(mat, x, y + h, 0f)
|
||||
.color(color)
|
||||
.endVertex()
|
||||
buf.vertex(mat, x + w, y + h, 0f)
|
||||
.color(color)
|
||||
.endVertex()
|
||||
buf.vertex(mat, x + w, y, 0f)
|
||||
.color(color)
|
||||
.endVertex()
|
||||
tess.end()
|
||||
}
|
||||
|
|
|
@ -9,11 +9,15 @@ import at.petrak.hexcasting.api.spell.math.HexCoord
|
|||
import at.petrak.hexcasting.api.spell.math.HexDir
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
import at.petrak.hexcasting.api.utils.asTranslatedComponent
|
||||
import at.petrak.hexcasting.api.utils.gold
|
||||
import at.petrak.hexcasting.api.utils.otherHand
|
||||
import at.petrak.hexcasting.client.ClientTickCounter
|
||||
import at.petrak.hexcasting.client.drawPatternFromPoints
|
||||
import at.petrak.hexcasting.client.drawSpot
|
||||
import at.petrak.hexcasting.client.renderQuad
|
||||
import at.petrak.hexcasting.client.sound.GridSoundInstance
|
||||
import at.petrak.hexcasting.common.items.ItemSpellbook
|
||||
import at.petrak.hexcasting.common.lib.HexIotaTypes
|
||||
import at.petrak.hexcasting.common.lib.HexItems
|
||||
import at.petrak.hexcasting.common.lib.HexSounds
|
||||
import at.petrak.hexcasting.common.network.MsgNewSpellPatternSyn
|
||||
|
@ -25,20 +29,26 @@ import net.minecraft.client.Minecraft
|
|||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.client.renderer.GameRenderer
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.util.FormattedCharSequence
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.InteractionHand
|
||||
import net.minecraft.world.phys.Vec2
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.math.*
|
||||
|
||||
class GuiSpellcasting(
|
||||
class GuiSpellcasting constructor(
|
||||
private val handOpenedWith: InteractionHand,
|
||||
private var patterns: MutableList<ResolvedPattern>,
|
||||
private var stackDescs: List<Component>
|
||||
private var cachedStack: List<CompoundTag>,
|
||||
private var cachedParens: List<CompoundTag>,
|
||||
private var cachedRavenmind: CompoundTag?,
|
||||
private var parenCount: Int,
|
||||
) : Screen("gui.hexcasting.spellcasting".asTranslatedComponent) {
|
||||
private var stackDescs: List<FormattedCharSequence> = listOf()
|
||||
private var parenDescs: List<FormattedCharSequence> = listOf()
|
||||
private var ravenmind: List<FormattedCharSequence>? = null
|
||||
|
||||
private var drawState: PatternDrawState = PatternDrawState.BetweenPatterns
|
||||
private val usedSpots: MutableSet<HexCoord> = HashSet()
|
||||
|
||||
|
@ -48,16 +58,17 @@ class GuiSpellcasting(
|
|||
for ((pattern, origin) in patterns) {
|
||||
this.usedSpots.addAll(pattern.positions(origin))
|
||||
}
|
||||
this.calculateIotaDisplays()
|
||||
}
|
||||
|
||||
fun recvServerUpdate(info: ControllerInfo) {
|
||||
this.stackDescs = info.stackDesc
|
||||
this.patterns.lastOrNull()?.let {
|
||||
it.type = info.resolutionType
|
||||
}
|
||||
|
||||
val mc = Minecraft.getInstance()
|
||||
if (info.resolutionType.success) {
|
||||
Minecraft.getInstance().soundManager.play(
|
||||
mc.soundManager.play(
|
||||
SimpleSoundInstance(
|
||||
HexSounds.ADD_PATTERN,
|
||||
SoundSource.PLAYERS,
|
||||
|
@ -69,6 +80,34 @@ class GuiSpellcasting(
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
this.cachedStack = info.stack
|
||||
this.cachedParens = info.parenthesized
|
||||
this.cachedRavenmind = info.ravenmind
|
||||
this.parenCount = info.parenCount
|
||||
this.calculateIotaDisplays()
|
||||
}
|
||||
|
||||
fun calculateIotaDisplays() {
|
||||
val mc = Minecraft.getInstance()
|
||||
val width = (this.width * LHS_IOTAS_ALLOCATION).toInt()
|
||||
this.stackDescs =
|
||||
this.cachedStack.flatMap { HexIotaTypes.getDisplayWithMaxWidth(it, width, mc.font).asReversed() }
|
||||
.asReversed()
|
||||
this.parenDescs = if (this.cachedParens.isNotEmpty())
|
||||
this.cachedParens.flatMap { HexIotaTypes.getDisplayWithMaxWidth(it, width, mc.font) }
|
||||
else if (this.parenCount > 0)
|
||||
listOf("...".gold.visualOrderText)
|
||||
else
|
||||
emptyList()
|
||||
this.ravenmind =
|
||||
this.cachedRavenmind?.let {
|
||||
HexIotaTypes.getDisplayWithMaxWidth(
|
||||
it,
|
||||
(this.width * RHS_IOTAS_ALLOCATION).toInt(),
|
||||
mc.font
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
|
@ -80,6 +119,8 @@ class GuiSpellcasting(
|
|||
this.ambianceSoundInstance = GridSoundInstance(player)
|
||||
soundManager.play(this.ambianceSoundInstance!!)
|
||||
}
|
||||
|
||||
this.calculateIotaDisplays()
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
|
@ -251,13 +292,13 @@ class GuiSpellcasting(
|
|||
super.onClose()
|
||||
}
|
||||
|
||||
override fun render(poseStack: PoseStack, pMouseX: Int, pMouseY: Int, pPartialTick: Float) {
|
||||
super.render(poseStack, pMouseX, pMouseY, pPartialTick)
|
||||
override fun render(ps: PoseStack, pMouseX: Int, pMouseY: Int, pPartialTick: Float) {
|
||||
super.render(ps, pMouseX, pMouseY, pPartialTick)
|
||||
|
||||
this.ambianceSoundInstance?.mousePosX = pMouseX / this.width.toDouble()
|
||||
this.ambianceSoundInstance?.mousePosY = pMouseX / this.width.toDouble()
|
||||
|
||||
val mat = poseStack.last().pose()
|
||||
val mat = ps.last().pose()
|
||||
val prevShader = RenderSystem.getShader()
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader)
|
||||
RenderSystem.disableDepthTest()
|
||||
|
@ -326,15 +367,73 @@ class GuiSpellcasting(
|
|||
drawPatternFromPoints(mat, points, false, 0xff_64c8ff_u.toInt(), 0xff_fecbe6_u.toInt(), 0.1f)
|
||||
}
|
||||
|
||||
RenderSystem.setShader { prevShader }
|
||||
RenderSystem.enableDepthTest()
|
||||
|
||||
val mc = Minecraft.getInstance()
|
||||
val font = mc.font
|
||||
for ((i, s) in this.stackDescs.withIndex()) {
|
||||
val offsetIdx = this.stackDescs.size - i - 1
|
||||
font.draw(poseStack, s, 10f, 10f + 9f * offsetIdx, -1)
|
||||
ps.pushPose()
|
||||
ps.translate(10.0, 10.0, 0.0)
|
||||
|
||||
if (this.parenCount > 0) {
|
||||
val boxHeight = (this.parenDescs.size + 1f) * 10f
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader)
|
||||
RenderSystem.defaultBlendFunc()
|
||||
drawBox(ps, 0f, 0f, (this.width * LHS_IOTAS_ALLOCATION + 5).toFloat(), boxHeight, 7.5f)
|
||||
ps.translate(0.0, 0.0, 1.0)
|
||||
|
||||
val time = ClientTickCounter.getTotal() * 0.8f
|
||||
val opacity = (Mth.map(cos(time), -1f, 1f, 200f, 255f)).toInt()
|
||||
val color = 0x00_ffffff or (opacity shl 24)
|
||||
RenderSystem.setShader { prevShader }
|
||||
for (desc in this.parenDescs) {
|
||||
font.draw(ps, desc, 10f, 7f, color)
|
||||
ps.translate(0.0, 10.0, 0.0)
|
||||
}
|
||||
ps.translate(0.0, 15.0, 0.0)
|
||||
}
|
||||
|
||||
if (this.stackDescs.isNotEmpty()) {
|
||||
val boxHeight = (this.stackDescs.size + 1f) * 10f
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader)
|
||||
RenderSystem.enableBlend()
|
||||
drawBox(ps, 0f, 0f, (this.width * LHS_IOTAS_ALLOCATION + 5).toFloat(), boxHeight)
|
||||
ps.translate(0.0, 0.0, 1.0)
|
||||
RenderSystem.setShader { prevShader }
|
||||
for (desc in this.stackDescs) {
|
||||
font.draw(ps, desc, 5f, 7f, -1)
|
||||
ps.translate(0.0, 10.0, 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
ps.popPose()
|
||||
if (!this.ravenmind.isNullOrEmpty()) {
|
||||
val kotlinBad = this.ravenmind!!
|
||||
ps.pushPose()
|
||||
ps.translate(this.width * 0.8, 10.0, 0.0)
|
||||
val boxHeight = (kotlinBad.size + 0.5f) * 10f
|
||||
val addlScale = 1.5f
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader)
|
||||
RenderSystem.enableBlend()
|
||||
drawBox(
|
||||
ps, 0f, 0f,
|
||||
((this.width * RHS_IOTAS_ALLOCATION + 5) * addlScale).toFloat(), boxHeight * addlScale,
|
||||
)
|
||||
ps.translate(5.0, 5.0, 1.0)
|
||||
ps.scale(addlScale, addlScale, 1f)
|
||||
|
||||
val time = ClientTickCounter.getTotal() * 0.42f
|
||||
val opacity = (Mth.map(sin(time), -1f, 1f, 150f, 255f)).toInt()
|
||||
val color = 0x00_ffffff or (opacity shl 24)
|
||||
|
||||
RenderSystem.setShader { prevShader }
|
||||
for (desc in kotlinBad) {
|
||||
font.draw(ps, desc, 0f, 0f, color)
|
||||
ps.translate(0.0, 10.0, 0.0)
|
||||
}
|
||||
ps.popPose()
|
||||
}
|
||||
|
||||
RenderSystem.setShader { prevShader }
|
||||
}
|
||||
|
||||
// why the hell is this default true
|
||||
|
@ -369,4 +468,16 @@ class GuiSpellcasting(
|
|||
/** We've started drawing a pattern for real. */
|
||||
data class Drawing(val start: HexCoord, var current: HexCoord, val wipPattern: HexPattern) : PatternDrawState()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val LHS_IOTAS_ALLOCATION = 0.7
|
||||
const val RHS_IOTAS_ALLOCATION = 0.1
|
||||
|
||||
fun drawBox(ps: PoseStack, x: Float, y: Float, w: Float, h: Float, leftMargin: Float = 2.5f) {
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader)
|
||||
RenderSystem.enableBlend()
|
||||
renderQuad(ps, x, y, w, h, 0x50_303030)
|
||||
renderQuad(ps, x + leftMargin, y + 2.5f, w - leftMargin - 2.5f, h - 5f, 0x50_303030)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ object OpEval : Action {
|
|||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
val instrs = stack.getList(stack.lastIndex)
|
||||
|
@ -29,6 +29,6 @@ object OpEval : Action {
|
|||
}
|
||||
|
||||
val frame = ContinuationFrame.Evaluate(instrs)
|
||||
return OperationResult(newCont.pushFrame(frame), stack, local, listOf())
|
||||
return OperationResult(newCont.pushFrame(frame), stack, ravenmind, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.eval
|
||||
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.Action
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.casting.SpellContinuation
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
|
||||
object OpEvalDelay : Action {
|
||||
override fun operate(continuation: SpellContinuation, stack: MutableList<Iota>, local: Iota, ctx: CastingContext): OperationResult {
|
||||
return OperationResult(continuation, stack, local, listOf())
|
||||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
return OperationResult(continuation, stack, ravenmind, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ object OpForEach : Action {
|
|||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (stack.size < 2)
|
||||
|
@ -29,7 +29,7 @@ object OpForEach : Action {
|
|||
return OperationResult(
|
||||
continuation.pushFrame(frame),
|
||||
stack,
|
||||
local,
|
||||
ravenmind,
|
||||
listOf()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.eval
|
||||
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.Action
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.casting.SpellContinuation
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
|
||||
object OpHalt : Action {
|
||||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
var newStack = stack.toList()
|
||||
|
@ -29,6 +29,6 @@ object OpHalt : Action {
|
|||
newStack = listOf()
|
||||
}
|
||||
|
||||
return OperationResult(newCont, newStack, local, listOf())
|
||||
return OperationResult(newCont, newStack, ravenmind, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ object OpLastNToList : Action {
|
|||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (stack.isEmpty())
|
||||
|
@ -28,6 +28,6 @@ object OpLastNToList : Action {
|
|||
}
|
||||
stack.addAll(output.asActionResult)
|
||||
|
||||
return OperationResult(continuation, stack, local, listOf())
|
||||
return OperationResult(continuation, stack, ravenmind, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.local
|
||||
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.Action
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.casting.SpellContinuation
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import at.petrak.hexcasting.api.spell.orNull
|
||||
|
||||
object OpPeekLocal : Action {
|
||||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
stack.add(local)
|
||||
return OperationResult(continuation, stack, local, listOf())
|
||||
stack.add(ravenmind.orNull())
|
||||
return OperationResult(continuation, stack, ravenmind, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.local
|
||||
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.Action
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
||||
import at.petrak.hexcasting.api.spell.casting.SpellContinuation
|
||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
||||
|
||||
object OpPushLocal : Action {
|
||||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (stack.isEmpty())
|
||||
|
|
|
@ -15,7 +15,7 @@ object OpPrint : Action {
|
|||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (stack.isEmpty()) {
|
||||
|
@ -23,7 +23,7 @@ object OpPrint : Action {
|
|||
}
|
||||
val datum = stack[stack.lastIndex]
|
||||
return OperationResult(
|
||||
continuation, stack, local, listOf(
|
||||
continuation, stack, ravenmind, listOf(
|
||||
OperatorSideEffect.AttemptSpell(Spell(datum), hasCastingSound = false, awardStat = false)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -14,7 +14,7 @@ object OpAlwinfyHasAscendedToABeingOfPureMath : Action {
|
|||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (stack.isEmpty())
|
||||
|
@ -48,7 +48,7 @@ object OpAlwinfyHasAscendedToABeingOfPureMath : Action {
|
|||
return OperationResult(
|
||||
continuation,
|
||||
stack,
|
||||
local,
|
||||
ravenmind,
|
||||
listOf()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ object OpBitMask : Action {
|
|||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (stack.size < 1)
|
||||
|
@ -38,6 +38,6 @@ object OpBitMask : Action {
|
|||
}
|
||||
}
|
||||
|
||||
return OperationResult(continuation, out.asReversed(), local, listOf())
|
||||
return OperationResult(continuation, out.asReversed(), ravenmind, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ object OpFisherman : Action {
|
|||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (stack.size < 2)
|
||||
|
@ -23,6 +23,6 @@ object OpFisherman : Action {
|
|||
val fish = stack.removeAt(stack.size - 1 - depth)
|
||||
stack.add(fish)
|
||||
|
||||
return OperationResult(continuation, stack, local, listOf())
|
||||
return OperationResult(continuation, stack, ravenmind, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ object OpStackSize : Action {
|
|||
override fun operate(
|
||||
continuation: SpellContinuation,
|
||||
stack: MutableList<Iota>,
|
||||
local: Iota,
|
||||
ravenmind: Iota?,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
stack.add(DoubleIota(stack.size.toDouble()))
|
||||
return OperationResult(continuation, stack, local, listOf())
|
||||
return OperationResult(continuation, stack, ravenmind, listOf())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,9 +35,11 @@ public class ItemStaff extends Item {
|
|||
if (!world.isClientSide() && player instanceof ServerPlayer serverPlayer) {
|
||||
var harness = IXplatAbstractions.INSTANCE.getHarness(serverPlayer, hand);
|
||||
var patterns = IXplatAbstractions.INSTANCE.getPatterns(serverPlayer);
|
||||
var descs = harness.generateDescs();
|
||||
|
||||
IXplatAbstractions.INSTANCE.sendPacketToPlayer(serverPlayer,
|
||||
new MsgOpenSpellGuiAck(hand, patterns, harness.generateDescs()));
|
||||
new MsgOpenSpellGuiAck(hand, patterns, descs.getFirst(), descs.getSecond(), descs.getThird(),
|
||||
harness.getParenCount()));
|
||||
}
|
||||
|
||||
player.awardStat(Stats.ITEM_USED.get(this));
|
||||
|
|
|
@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.spell.iota.*;
|
|||
import at.petrak.hexcasting.api.utils.HexUtils;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
@ -12,9 +13,11 @@ import net.minecraft.network.chat.Component;
|
|||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
|
@ -23,6 +26,7 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
|||
/**
|
||||
* Stores the registry for iota types, some utility methods, and all the types Hexcasting itself defines.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public class HexIotaTypes {
|
||||
public static final Registry<IotaType<?>> REGISTRY = IXplatAbstractions.INSTANCE.getIotaTypeRegistry();
|
||||
public static final String
|
||||
|
@ -141,6 +145,18 @@ public class HexIotaTypes {
|
|||
return type.display(data);
|
||||
}
|
||||
|
||||
public static List<FormattedCharSequence> getDisplayWithMaxWidth(CompoundTag tag, int maxWidth, Font font) {
|
||||
var type = getTypeFromTag(tag);
|
||||
if (type == null) {
|
||||
return List.of();
|
||||
}
|
||||
var data = tag.get(KEY_DATA);
|
||||
if (data == null) {
|
||||
return List.of();
|
||||
}
|
||||
return type.displayWithWidth(data, maxWidth, font);
|
||||
}
|
||||
|
||||
public static int getColor(CompoundTag tag) {
|
||||
var type = getTypeFromTag(tag);
|
||||
if (type == null) {
|
||||
|
|
|
@ -7,10 +7,9 @@ import at.petrak.hexcasting.common.lib.HexSounds;
|
|||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
|
@ -31,14 +30,15 @@ public record MsgNewSpellPatternAck(ControllerInfo info) implements IMessage {
|
|||
var wasSpellCast = buf.readBoolean();
|
||||
var isStackEmpty = buf.readBoolean();
|
||||
var resolutionType = buf.readEnum(ResolvedPatternType.class);
|
||||
var descsLen = buf.readInt();
|
||||
var desc = new ArrayList<Component>(descsLen);
|
||||
for (int i = 0; i < descsLen; i++) {
|
||||
desc.add(buf.readComponent());
|
||||
}
|
||||
|
||||
var stack = buf.readList(FriendlyByteBuf::readNbt);
|
||||
var parens = buf.readList(FriendlyByteBuf::readNbt);
|
||||
var raven = buf.readOptional(FriendlyByteBuf::readNbt).orElse(null);
|
||||
|
||||
var parenCount = buf.readVarInt();
|
||||
|
||||
return new MsgNewSpellPatternAck(
|
||||
new ControllerInfo(wasSpellCast, isStackEmpty, resolutionType, desc)
|
||||
new ControllerInfo(wasSpellCast, isStackEmpty, resolutionType, stack, parens, raven, parenCount)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -47,10 +47,12 @@ public record MsgNewSpellPatternAck(ControllerInfo info) implements IMessage {
|
|||
buf.writeBoolean(this.info.getMakesCastSound());
|
||||
buf.writeBoolean(this.info.isStackClear());
|
||||
buf.writeEnum(this.info.getResolutionType());
|
||||
buf.writeInt(this.info.getStackDesc().size());
|
||||
for (var desc : this.info.getStackDesc()) {
|
||||
buf.writeComponent(desc);
|
||||
}
|
||||
|
||||
buf.writeCollection(this.info.getStack(), FriendlyByteBuf::writeNbt);
|
||||
buf.writeCollection(this.info.getParenthesized(), FriendlyByteBuf::writeNbt);
|
||||
buf.writeOptional(Optional.ofNullable(this.info.getRavenmind()), FriendlyByteBuf::writeNbt);
|
||||
|
||||
buf.writeVarInt(this.info.getParenCount());
|
||||
}
|
||||
|
||||
public static void handle(MsgNewSpellPatternAck self) {
|
||||
|
|
|
@ -25,7 +25,7 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
|||
|
||||
/**
|
||||
* Sent client->server when the player finishes drawing a pattern.
|
||||
* Server will send back a MsgNewSpellPatternAck packet
|
||||
* Server will send back a {@link MsgNewSpellPatternAck} packet
|
||||
*/
|
||||
public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern,
|
||||
List<ResolvedPattern> resolvedPatterns)
|
||||
|
@ -40,12 +40,12 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern
|
|||
public static MsgNewSpellPatternSyn deserialize(ByteBuf buffer) {
|
||||
var buf = new FriendlyByteBuf(buffer);
|
||||
var hand = buf.readEnum(InteractionHand.class);
|
||||
var pattern = HexPattern.fromNBT(buf.readAnySizeNbt());
|
||||
var pattern = HexPattern.fromNBT(buf.readNbt());
|
||||
|
||||
var resolvedPatternsLen = buf.readInt();
|
||||
var resolvedPatterns = new ArrayList<ResolvedPattern>(resolvedPatternsLen);
|
||||
for (int i = 0; i < resolvedPatternsLen; i++) {
|
||||
resolvedPatterns.add(ResolvedPattern.fromNBT(buf.readAnySizeNbt()));
|
||||
resolvedPatterns.add(ResolvedPattern.fromNBT(buf.readNbt()));
|
||||
}
|
||||
return new MsgNewSpellPatternSyn(hand, pattern, resolvedPatterns);
|
||||
}
|
||||
|
@ -86,8 +86,9 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern
|
|||
|
||||
ControllerInfo clientInfo;
|
||||
if (autoFail) {
|
||||
var descs = harness.generateDescs();
|
||||
clientInfo = new ControllerInfo(false, harness.getStack().isEmpty(), ResolvedPatternType.INVALID,
|
||||
harness.generateDescs());
|
||||
descs.getFirst(), descs.getSecond(), descs.getThird(), harness.getParenCount());
|
||||
} else {
|
||||
clientInfo = harness.executeIota(new PatternIota(this.pattern), sender.getLevel());
|
||||
|
||||
|
|
|
@ -4,12 +4,11 @@ import at.petrak.hexcasting.api.spell.casting.ResolvedPattern;
|
|||
import at.petrak.hexcasting.client.gui.GuiSpellcasting;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
@ -17,7 +16,12 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
|||
/**
|
||||
* Sent server->client when the player opens the spell gui to request the server provide the current stack.
|
||||
*/
|
||||
public record MsgOpenSpellGuiAck(InteractionHand hand, List<ResolvedPattern> patterns, List<Component> components)
|
||||
public record MsgOpenSpellGuiAck(InteractionHand hand, List<ResolvedPattern> patterns,
|
||||
List<CompoundTag> stack,
|
||||
List<CompoundTag> parenthesized,
|
||||
CompoundTag ravenmind,
|
||||
int parenCount
|
||||
)
|
||||
implements IMessage {
|
||||
public static final ResourceLocation ID = modLoc("cgui");
|
||||
|
||||
|
@ -31,33 +35,27 @@ public record MsgOpenSpellGuiAck(InteractionHand hand, List<ResolvedPattern> pat
|
|||
|
||||
var hand = buf.readEnum(InteractionHand.class);
|
||||
|
||||
var patternsLen = buf.readInt();
|
||||
var patterns = new ArrayList<ResolvedPattern>(patternsLen);
|
||||
for (int i = 0; i < patternsLen; i++) {
|
||||
patterns.add(ResolvedPattern.fromNBT(buf.readAnySizeNbt()));
|
||||
}
|
||||
var patterns = buf.readList(fbb -> ResolvedPattern.fromNBT(fbb.readAnySizeNbt()));
|
||||
|
||||
var descsLen = buf.readInt();
|
||||
var desc = new ArrayList<Component>(descsLen);
|
||||
for (int i = 0; i < descsLen; i++) {
|
||||
desc.add(buf.readComponent());
|
||||
}
|
||||
var stack = buf.readList(FriendlyByteBuf::readNbt);
|
||||
var parens = buf.readList(FriendlyByteBuf::readNbt);
|
||||
var raven = buf.readAnySizeNbt();
|
||||
|
||||
return new MsgOpenSpellGuiAck(hand, patterns, desc);
|
||||
var parenCount = buf.readVarInt();
|
||||
|
||||
return new MsgOpenSpellGuiAck(hand, patterns, stack, parens, raven, parenCount);
|
||||
}
|
||||
|
||||
public void serialize(FriendlyByteBuf buf) {
|
||||
buf.writeEnum(this.hand);
|
||||
|
||||
buf.writeInt(this.patterns.size());
|
||||
for (var pattern : this.patterns) {
|
||||
buf.writeNbt(pattern.serializeToNBT());
|
||||
}
|
||||
buf.writeCollection(this.patterns, (fbb, pat) -> fbb.writeNbt(pat.serializeToNBT()));
|
||||
|
||||
buf.writeInt(this.components.size());
|
||||
for (var desc : this.components) {
|
||||
buf.writeComponent(desc);
|
||||
}
|
||||
buf.writeCollection(this.stack, FriendlyByteBuf::writeNbt);
|
||||
buf.writeCollection(this.parenthesized, FriendlyByteBuf::writeNbt);
|
||||
buf.writeNbt(this.ravenmind);
|
||||
|
||||
buf.writeVarInt(this.parenCount);
|
||||
}
|
||||
|
||||
public static void handle(MsgOpenSpellGuiAck msg) {
|
||||
|
@ -65,7 +63,9 @@ public record MsgOpenSpellGuiAck(InteractionHand hand, List<ResolvedPattern> pat
|
|||
@Override
|
||||
public void run() {
|
||||
var mc = Minecraft.getInstance();
|
||||
mc.setScreen(new GuiSpellcasting(msg.hand(), msg.patterns(), msg.components()));
|
||||
mc.setScreen(
|
||||
new GuiSpellcasting(msg.hand(), msg.patterns(), msg.stack, msg.parenthesized, msg.ravenmind,
|
||||
msg.parenCount));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"item.hexcasting.book": "Hex Notebook",
|
||||
"item.hexcasting.wand_oak": "Oak Staff",
|
||||
"item.hexcasting.wand_spruce": "Spruce Staff",
|
||||
"item.hexcasting.wand_birch": "Birch Staff",
|
||||
"item.hexcasting.wand_jungle": "Jungle Staff",
|
||||
"item.hexcasting.wand_acacia": "Acacia Staff",
|
||||
"item.hexcasting.wand_dark_oak": "Dark Oak Staff",
|
||||
"item.hexcasting.wand_crimson": "Crimson Staff",
|
||||
"item.hexcasting.wand_warped": "Warped Staff",
|
||||
"item.hexcasting.wand_akashic": "Edified Staff",
|
||||
"item.hexcasting.oak_staff": "Oak Staff",
|
||||
"item.hexcasting.spruce_staff": "Spruce Staff",
|
||||
"item.hexcasting.birch_staff": "Birch Staff",
|
||||
"item.hexcasting.jungle_staff": "Jungle Staff",
|
||||
"item.hexcasting.acacia_staff": "Acacia Staff",
|
||||
"item.hexcasting.dark_oak_staff": "Dark Oak Staff",
|
||||
"item.hexcasting.crimson_staff": "Crimson Staff",
|
||||
"item.hexcasting.warped_staff": "Warped Staff",
|
||||
"item.hexcasting.edified_staff": "Edified Staff",
|
||||
"item.hexcasting.focus": "Focus",
|
||||
"item.hexcasting.focus.sealed": "Sealed Focus",
|
||||
"item.hexcasting.spellbook": "Spellbook",
|
||||
|
|
Loading…
Reference in a new issue