now everything is colory

colors not final
This commit is contained in:
yrsegal@gmail.com 2022-05-22 16:56:58 -04:00
parent dd089c2be7
commit 0955510929
13 changed files with 86 additions and 106 deletions

View file

@ -278,7 +278,6 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
new SpellCircleContext(this.getBlockPos(), bounds, this.activatorAlwaysInRange()));
var harness = new CastingHarness(ctx);
var castSpell = false;
var makeSound = false;
BlockPos erroredPos = null;
for (var tracked : this.trackedBlocks) {
@ -287,13 +286,10 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
var newPattern = cc.getPattern(tracked, bs, this.level);
if (newPattern != null) {
var info = harness.executeNewIota(SpellDatum.make(newPattern), splayer.getLevel());
if (info.getWasSpellCast()) {
castSpell = true;
if (info.getHasCastingSound()) {
makeSound = true;
}
if (info.getMakesCastSound()) {
makeSound = true;
}
if (info.getWasPrevPatternInvalid()) {
if (!info.getResolutionType().getSuccess()) {
erroredPos = tracked;
break;
}
@ -301,7 +297,7 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
}
}
if (castSpell && makeSound) {
if (makeSound) {
this.level.playSound(null, this.getBlockPos(), HexSounds.SPELL_CIRCLE_CAST, SoundSource.BLOCKS,
2f, 1f);
}

View file

@ -8,22 +8,14 @@ import at.petrak.hexcasting.api.misc.HexDamageSources
import at.petrak.hexcasting.api.mod.HexConfig
import at.petrak.hexcasting.api.mod.HexItemTags
import at.petrak.hexcasting.api.mod.HexStatistics
import at.petrak.hexcasting.api.spell.Operator
import at.petrak.hexcasting.api.spell.ParticleSpray
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.api.spell.Widget
import at.petrak.hexcasting.api.spell.math.HexPattern
import at.petrak.hexcasting.api.spell.mishaps.Mishap
import at.petrak.hexcasting.api.spell.mishaps.MishapDisallowedSpell
import at.petrak.hexcasting.api.spell.mishaps.MishapError
import at.petrak.hexcasting.api.spell.mishaps.MishapTooManyCloseParens
import at.petrak.hexcasting.api.spell.*
import at.petrak.hexcasting.api.spell.math.HexDir
import at.petrak.hexcasting.api.spell.math.HexPattern
import at.petrak.hexcasting.api.spell.mishaps.*
import at.petrak.hexcasting.api.utils.ManaHelper
import at.petrak.hexcasting.xplat.IXplatAbstractions
import at.petrak.hexcasting.api.utils.asCompound
import at.petrak.hexcasting.api.utils.getList
import at.petrak.hexcasting.xplat.IXplatAbstractions
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag
import net.minecraft.nbt.Tag
@ -59,19 +51,13 @@ class CastingHarness private constructor(
fun executeNewIota(iota: SpellDatum<*>, world: ServerLevel): ControllerInfo {
val result = this.getUpdate(iota, world)
this.applyFunctionalData(result.newData)
return this.performSideEffects(result.sideEffects)
return this.performSideEffects(result.sideEffects, result.resolutionType)
}
fun getUpdate(iota: SpellDatum<*>, world: ServerLevel): CastResult {
try {
// wouldn't it be nice to be able to go paren'
// i guess i'll call it paren2
val paren2 = this.handleParentheses(iota)
if (paren2 != null) {
return CastResult(
paren2,
listOf()
)
this.handleParentheses(iota)?.let { (data, resolutionType) ->
return@getUpdate CastResult(data, resolutionType, listOf())
}
return if (iota.getType() == DatumType.PATTERN) {
@ -79,6 +65,7 @@ class CastingHarness private constructor(
} else {
CastResult(
this.getFunctionalData(),
ResolvedPatternType.INVALID, // Should never matter
listOf(
OperatorSideEffect.DoMishap(
MishapUnescapedValue(iota),
@ -90,12 +77,14 @@ class CastingHarness private constructor(
} catch (mishap: Mishap) {
return CastResult(
this.getFunctionalData(),
mishap.resolutionType(ctx),
listOf(OperatorSideEffect.DoMishap(mishap, Mishap.Context(iota.payload as? HexPattern ?: HexPattern(HexDir.WEST), null))),
)
} catch (exception: Exception) {
exception.printStackTrace()
return CastResult(
this.getFunctionalData(),
ResolvedPatternType.ERROR,
listOf(OperatorSideEffect.DoMishap(MishapError(exception), Mishap.Context(iota.payload as? HexPattern ?: HexPattern(HexDir.WEST), null)))
)
}
@ -138,17 +127,20 @@ class CastingHarness private constructor(
return CastResult(
fd,
ResolvedPatternType.OK,
sideEffects,
)
} catch (mishap: Mishap) {
return CastResult(
this.getFunctionalData(),
mishap.resolutionType(ctx),
listOf(OperatorSideEffect.DoMishap(mishap, Mishap.Context(newPat, operatorIdPair?.second))),
)
} catch (exception: Exception) {
exception.printStackTrace()
return CastResult(
this.getFunctionalData(),
ResolvedPatternType.ERROR,
listOf(OperatorSideEffect.DoMishap(MishapError(exception), Mishap.Context(newPat, operatorIdPair?.second)))
)
}
@ -157,30 +149,21 @@ class CastingHarness private constructor(
/**
* Execute the side effects of a cast, and then tell the client what to think about it.
*/
fun performSideEffects(sideEffects: List<OperatorSideEffect>): ControllerInfo {
var wasSpellCast = false
var wasPrevPatternInvalid = false
var hasCastingSound = false
fun performSideEffects(sideEffects: List<OperatorSideEffect>, resolutionType: ResolvedPatternType): ControllerInfo {
var makesCastSound = false
for (haskellProgrammersShakingandCryingRN in sideEffects) {
val mustStop = haskellProgrammersShakingandCryingRN.performEffect(this)
if (mustStop) {
wasPrevPatternInvalid = true
break
}
if (mustStop) break
if (haskellProgrammersShakingandCryingRN is OperatorSideEffect.AttemptSpell) {
wasSpellCast = true
if (haskellProgrammersShakingandCryingRN.hasCastingSound)
hasCastingSound = true
if (haskellProgrammersShakingandCryingRN is OperatorSideEffect.AttemptSpell &&
haskellProgrammersShakingandCryingRN.hasCastingSound)
makesCastSound = true
}
}
return ControllerInfo(
wasSpellCast,
hasCastingSound,
makesCastSound,
this.stack.isEmpty() && this.parenCount == 0 && !this.escapeNext,
wasPrevPatternInvalid,
resolutionType,
generateDescs()
)
}
@ -218,7 +201,7 @@ class CastingHarness private constructor(
* Return a non-null value if we handled this in some sort of parenthesey way,
* either escaping it onto the stack or changing the parenthese-handling state.
*/
private fun handleParentheses(iota: SpellDatum<*>): FunctionalData? {
private fun handleParentheses(iota: SpellDatum<*>): Pair<FunctionalData, ResolvedPatternType>? {
val operator = (iota.payload as? HexPattern)?.let {
try {
PatternRegistry.matchPattern(it, this.ctx.world)
@ -234,11 +217,11 @@ class CastingHarness private constructor(
this.getFunctionalData().copy(
escapeNext = false,
parenthesized = newParens
)
) to ResolvedPatternType.PATTERN
} else if (operator == Widget.ESCAPE) {
this.getFunctionalData().copy(
escapeNext = true,
)
) to ResolvedPatternType.OK
} else if (operator == Widget.OPEN_PAREN) {
// we have escaped the parens onto the stack; we just also record our count.
val newParens = this.parenthesized.toMutableList()
@ -246,7 +229,7 @@ class CastingHarness private constructor(
this.getFunctionalData().copy(
parenthesized = newParens,
parenCount = this.parenCount + 1
)
) to ResolvedPatternType.OK
} else if (operator == Widget.CLOSE_PAREN) {
val newParenCount = this.parenCount - 1
if (newParenCount == 0) {
@ -256,7 +239,7 @@ class CastingHarness private constructor(
stack = newStack,
parenCount = newParenCount,
parenthesized = listOf()
)
) to ResolvedPatternType.OK
} else if (newParenCount < 0) {
throw MishapTooManyCloseParens()
} else {
@ -267,14 +250,14 @@ class CastingHarness private constructor(
this.getFunctionalData().copy(
parenCount = newParenCount,
parenthesized = newParens
)
) to ResolvedPatternType.PATTERN
}
} else {
val newParens = this.parenthesized.toMutableList()
newParens.add(iota)
this.getFunctionalData().copy(
parenthesized = newParens
)
) to ResolvedPatternType.PATTERN
}
} else if (this.escapeNext) {
val newStack = this.stack.toMutableList()
@ -282,15 +265,15 @@ class CastingHarness private constructor(
this.getFunctionalData().copy(
stack = newStack,
escapeNext = false,
)
) to ResolvedPatternType.PATTERN
} else if (operator == Widget.ESCAPE) {
this.getFunctionalData().copy(
escapeNext = true
)
) to ResolvedPatternType.OK
} else if (operator == Widget.OPEN_PAREN) {
this.getFunctionalData().copy(
parenCount = this.parenCount + 1
)
) to ResolvedPatternType.OK
} else if (operator == Widget.CLOSE_PAREN) {
throw MishapTooManyCloseParens()
} else {
@ -451,6 +434,7 @@ class CastingHarness private constructor(
data class CastResult(
val newData: FunctionalData,
val sideEffects: List<OperatorSideEffect>,
val resolutionType: ResolvedPatternType,
val sideEffects: List<OperatorSideEffect>
)
}

View file

@ -6,9 +6,8 @@ import net.minecraft.network.chat.Component
* Information for the sake of the GUI.
*/
data class ControllerInfo(
val wasSpellCast: Boolean,
val hasCastingSound: Boolean,
val makesCastSound: Boolean,
val isStackClear: Boolean,
val wasPrevPatternInvalid: Boolean,
val resolutionType: ResolvedPatternType,
val stackDesc: List<Component>
)

View file

@ -3,15 +3,16 @@ package at.petrak.hexcasting.api.spell.casting
import at.petrak.hexcasting.api.spell.math.HexCoord
import at.petrak.hexcasting.api.spell.math.HexPattern
import net.minecraft.nbt.CompoundTag
import java.util.*
data class ResolvedPattern(val pattern: HexPattern, val origin: HexCoord, var valid: ResolvedPatternValidity) {
data class ResolvedPattern(val pattern: HexPattern, val origin: HexCoord, var type: ResolvedPatternType) {
fun serializeToNBT(): CompoundTag {
val tag = CompoundTag()
tag.put("Pattern", pattern.serializeToNBT())
tag.putInt("OriginQ", origin.q)
tag.putInt("OriginR", origin.r)
tag.putInt("Valid", valid.ordinal)
tag.putString("Valid", type.name.lowercase(Locale.ROOT))
return tag
}
@ -20,7 +21,11 @@ data class ResolvedPattern(val pattern: HexPattern, val origin: HexCoord, var va
fun DeserializeFromNBT(tag: CompoundTag): ResolvedPattern {
val pattern = HexPattern.DeserializeFromNBT(tag.getCompound("Pattern"))
val origin = HexCoord(tag.getInt("OriginQ"), tag.getInt("OriginR"))
val valid = ResolvedPatternValidity.values()[tag.getInt("Valid").coerceIn(0, ResolvedPatternValidity.values().size - 1)]
val valid = try {
ResolvedPatternType.valueOf(tag.getString("Valid").uppercase(Locale.ROOT))
} catch (e: IllegalArgumentException) {
ResolvedPatternType.UNKNOWN
}
return ResolvedPattern(pattern, origin, valid)
}
}

View file

@ -0,0 +1,9 @@
package at.petrak.hexcasting.api.spell.casting
enum class ResolvedPatternType(val color: Int, val fadeColor: Int, val success: Boolean) {
UNKNOWN(0x7f7f7f, 0xcccccc, false),
OK(0x7385de, 0xfecbe6, true),
PATTERN(0xdddd73, 0xffffe5, true),
ERROR(0xde6262, 0xffc7a0, false),
INVALID(0xddbcbc, 0xfff0e5, false)
}

View file

@ -1,7 +0,0 @@
package at.petrak.hexcasting.api.spell.casting
enum class ResolvedPatternValidity {
UNKNOWN,
OK,
ERROR
}

View file

@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.misc.FrozenColorizer
import at.petrak.hexcasting.api.spell.ParticleSpray
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.api.spell.casting.CastingContext
import at.petrak.hexcasting.api.spell.casting.ResolvedPatternType
import at.petrak.hexcasting.api.spell.math.HexPattern
import at.petrak.hexcasting.common.lib.HexItems
import at.petrak.hexcasting.mixin.accessor.AccessorLivingEntity
@ -28,6 +29,8 @@ sealed class Mishap : Throwable() {
return ParticleSpray(ctx.position.add(0.0, 0.2, 0.0), Vec3(0.0, 2.0, 0.0), 0.2, Math.PI / 4, 40)
}
open fun resolutionType(ctx: CastingContext): ResolvedPatternType = ResolvedPatternType.ERROR
/**
* Execute the actual effect, not any sfx.
*

View file

@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.spell.mishaps
import at.petrak.hexcasting.api.misc.FrozenColorizer
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.api.spell.casting.CastingContext
import at.petrak.hexcasting.api.spell.casting.ResolvedPatternType
import net.minecraft.network.chat.Component
import net.minecraft.world.item.DyeColor
@ -10,9 +11,12 @@ class MishapDisallowedSpell : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.BLACK)
override fun resolutionType(ctx: CastingContext) = ResolvedPatternType.INVALID
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
// NO-OP
}
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("disallowed", actionName(errorCtx.action))
}
}

View file

@ -1,9 +1,10 @@
package at.petrak.hexcasting.api.spell.mishaps
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.api.spell.casting.CastingContext
import at.petrak.hexcasting.api.spell.Widget
import at.petrak.hexcasting.api.misc.FrozenColorizer
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.api.spell.Widget
import at.petrak.hexcasting.api.spell.casting.CastingContext
import at.petrak.hexcasting.api.spell.casting.ResolvedPatternType
import net.minecraft.network.chat.Component
import net.minecraft.world.item.DyeColor
@ -11,6 +12,7 @@ class MishapInvalidPattern : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.YELLOW)
override fun resolutionType(ctx: CastingContext) = ResolvedPatternType.INVALID
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
stack.add(SpellDatum.make(Widget.GARBAGE))

View file

@ -3,7 +3,7 @@ package at.petrak.hexcasting.client.gui
import at.petrak.hexcasting.api.mod.HexItemTags
import at.petrak.hexcasting.api.spell.casting.ControllerInfo
import at.petrak.hexcasting.api.spell.casting.ResolvedPattern
import at.petrak.hexcasting.api.spell.casting.ResolvedPatternValidity
import at.petrak.hexcasting.api.spell.casting.ResolvedPatternType
import at.petrak.hexcasting.api.spell.math.HexAngle
import at.petrak.hexcasting.api.spell.math.HexCoord
import at.petrak.hexcasting.api.spell.math.HexDir
@ -52,13 +52,10 @@ class GuiSpellcasting(
fun recvServerUpdate(info: ControllerInfo) {
this.stackDescs = info.stackDesc
this.patterns.lastOrNull()?.let {
it.valid = if (info.wasPrevPatternInvalid)
ResolvedPatternValidity.ERROR
else
ResolvedPatternValidity.OK
it.type = info.resolutionType
}
if (!info.wasPrevPatternInvalid) {
if (info.resolutionType.success) {
Minecraft.getInstance().soundManager.play(
SimpleSoundInstance(
HexSounds.ADD_PATTERN,
@ -214,7 +211,7 @@ class GuiSpellcasting(
is PatternDrawState.Drawing -> {
val (start, _, pat) = this.drawState as PatternDrawState.Drawing
this.drawState = PatternDrawState.BetweenPatterns
this.patterns.add(ResolvedPattern(pat, start, ResolvedPatternValidity.UNKNOWN))
this.patterns.add(ResolvedPattern(pat, start, ResolvedPatternType.UNKNOWN))
this.usedSpots.addAll(pat.positions(start))
@ -295,21 +292,11 @@ class GuiSpellcasting(
}
RenderSystem.defaultBlendFunc()
val alreadyPats = this.patterns.map { (pat, origin, valid) ->
val colors: Pair<Int, Int> = when (valid) {
ResolvedPatternValidity.UNKNOWN -> Pair(0xc8_7f7f7f_u.toInt(), 0xc8_7f7f7f_u.toInt())
ResolvedPatternValidity.OK -> Pair(0xc8_7385de_u.toInt(), 0xc8_fecbe6_u.toInt())
ResolvedPatternValidity.ERROR -> Pair(0xc8_de6262_u.toInt(), 0xc8_e6755c_u.toInt())
}
Pair(
pat.toLines(
this.hexSize(),
this.coordToPx(origin)
), colors
)
}
for ((pat, color) in alreadyPats) {
RenderLib.drawPatternFromPoints(mat, pat, true, color.first, color.second)
for ((pat, origin, valid) in this.patterns) {
RenderLib.drawPatternFromPoints(mat, pat.toLines(
this.hexSize(),
this.coordToPx(origin)
), true, valid.color or (0xC8 shl 24), valid.fadeColor or (0xC8 shl 24))
}
// Now draw the currently WIP pattern

View file

@ -112,7 +112,7 @@ public abstract class ItemPackagedHex extends ItemManaHolder implements HexHolde
var harness = new CastingHarness(ctx);
for (var insn : instrs) {
var info = harness.executeNewIota(insn, sPlayer.getLevel());
if (info.getWasPrevPatternInvalid()) {
if (!info.getResolutionType().getSuccess()) {
break;
}
}

View file

@ -1,6 +1,7 @@
package at.petrak.hexcasting.common.network;
import at.petrak.hexcasting.api.spell.casting.ControllerInfo;
import at.petrak.hexcasting.api.spell.casting.ResolvedPatternType;
import at.petrak.hexcasting.client.gui.GuiSpellcasting;
import at.petrak.hexcasting.common.lib.HexSounds;
import io.netty.buffer.ByteBuf;
@ -28,9 +29,8 @@ public record MsgNewSpellPatternAck(ControllerInfo info) implements IMessage {
var buf = new FriendlyByteBuf(buffer);
var wasSpellCast = buf.readBoolean();
var hasCastingSound = buf.readBoolean();
var isStackEmpty = buf.readBoolean();
var wasPrevPatternInvalid = 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++) {
@ -38,16 +38,15 @@ public record MsgNewSpellPatternAck(ControllerInfo info) implements IMessage {
}
return new MsgNewSpellPatternAck(
new ControllerInfo(wasSpellCast, hasCastingSound, isStackEmpty, wasPrevPatternInvalid, desc)
new ControllerInfo(wasSpellCast, isStackEmpty, resolutionType, desc)
);
}
@Override
public void serialize(FriendlyByteBuf buf) {
buf.writeBoolean(this.info.getWasSpellCast());
buf.writeBoolean(this.info.getHasCastingSound());
buf.writeBoolean(this.info.getMakesCastSound());
buf.writeBoolean(this.info.isStackClear());
buf.writeBoolean(this.info.getWasPrevPatternInvalid());
buf.writeEnum(this.info.getResolutionType());
buf.writeInt(this.info.getStackDesc().size());
for (var desc : this.info.getStackDesc()) {
buf.writeComponent(desc);

View file

@ -4,7 +4,7 @@ import at.petrak.hexcasting.api.mod.HexItemTags;
import at.petrak.hexcasting.api.spell.SpellDatum;
import at.petrak.hexcasting.api.spell.casting.ControllerInfo;
import at.petrak.hexcasting.api.spell.casting.ResolvedPattern;
import at.petrak.hexcasting.api.spell.casting.ResolvedPatternValidity;
import at.petrak.hexcasting.api.spell.casting.ResolvedPatternType;
import at.petrak.hexcasting.api.spell.math.HexCoord;
import at.petrak.hexcasting.api.spell.math.HexPattern;
import at.petrak.hexcasting.common.lib.HexSounds;
@ -82,12 +82,12 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern
ControllerInfo clientInfo;
if (autoFail) {
clientInfo = new ControllerInfo(false, false, harness.getStack().isEmpty(), true,
clientInfo = new ControllerInfo(false, harness.getStack().isEmpty(), ResolvedPatternType.INVALID,
harness.generateDescs());
} else {
clientInfo = harness.executeNewIota(SpellDatum.make(this.pattern), sender.getLevel());
if (clientInfo.getWasSpellCast() && clientInfo.getHasCastingSound()) {
if (clientInfo.getMakesCastSound()) {
sender.level.playSound(null, sender.getX(), sender.getY(), sender.getZ(),
HexSounds.ACTUALLY_CAST, SoundSource.PLAYERS, 1f,
1f + ((float) Math.random() - 0.5f) * 0.2f);
@ -100,8 +100,7 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern
} else {
IXplatAbstractions.INSTANCE.setHarness(sender, harness);
if (!resolvedPatterns.isEmpty()) {
resolvedPatterns.get(resolvedPatterns.size() - 1).setValid(clientInfo.getWasPrevPatternInvalid() ?
ResolvedPatternValidity.ERROR : ResolvedPatternValidity.OK);
resolvedPatterns.get(resolvedPatterns.size() - 1).setType(clientInfo.getResolutionType());
}
IXplatAbstractions.INSTANCE.setPatterns(sender, resolvedPatterns);
}