and now for the part of the show where we refactor every single operator
This commit is contained in:
parent
8261063208
commit
71c3cade9b
20 changed files with 275 additions and 147 deletions
|
@ -5,10 +5,10 @@ import at.petrak.hexcasting.api.misc.FrozenColorizer;
|
||||||
import at.petrak.hexcasting.api.misc.ManaConstants;
|
import at.petrak.hexcasting.api.misc.ManaConstants;
|
||||||
import at.petrak.hexcasting.api.mod.HexConfig;
|
import at.petrak.hexcasting.api.mod.HexConfig;
|
||||||
import at.petrak.hexcasting.api.spell.ParticleSpray;
|
import at.petrak.hexcasting.api.spell.ParticleSpray;
|
||||||
import at.petrak.hexcasting.api.spell.iota.Iota;
|
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingContext;
|
import at.petrak.hexcasting.api.spell.casting.CastingContext;
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingHarness;
|
import at.petrak.hexcasting.api.spell.casting.CastingHarness;
|
||||||
import at.petrak.hexcasting.api.spell.casting.SpellCircleContext;
|
import at.petrak.hexcasting.api.spell.casting.SpellCircleContext;
|
||||||
|
import at.petrak.hexcasting.api.spell.iota.PatternIota;
|
||||||
import at.petrak.hexcasting.api.utils.ManaHelper;
|
import at.petrak.hexcasting.api.utils.ManaHelper;
|
||||||
import at.petrak.hexcasting.common.lib.HexItems;
|
import at.petrak.hexcasting.common.lib.HexItems;
|
||||||
import at.petrak.hexcasting.common.lib.HexSounds;
|
import at.petrak.hexcasting.common.lib.HexSounds;
|
||||||
|
@ -287,7 +287,7 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
|
||||||
if (bs.getBlock() instanceof BlockCircleComponent cc) {
|
if (bs.getBlock() instanceof BlockCircleComponent cc) {
|
||||||
var newPattern = cc.getPattern(tracked, bs, this.level);
|
var newPattern = cc.getPattern(tracked, bs, this.level);
|
||||||
if (newPattern != null) {
|
if (newPattern != null) {
|
||||||
var info = harness.executeIota(LegacySpellDatum.make(newPattern), splayer.getLevel());
|
var info = harness.executeIota(new PatternIota(newPattern), splayer.getLevel());
|
||||||
if (info.getMakesCastSound()) {
|
if (info.getMakesCastSound()) {
|
||||||
makeSound = true;
|
makeSound = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package at.petrak.hexcasting.api.spell
|
package at.petrak.hexcasting.api.spell
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||||
import at.petrak.hexcasting.api.spell.casting.SpellContinuation
|
|
||||||
import at.petrak.hexcasting.api.spell.casting.OperatorSideEffect
|
import at.petrak.hexcasting.api.spell.casting.OperatorSideEffect
|
||||||
|
import at.petrak.hexcasting.api.spell.casting.SpellContinuation
|
||||||
|
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,7 +16,12 @@ interface ConstManaOperator : Operator {
|
||||||
|
|
||||||
fun execute(args: List<Iota>, ctx: CastingContext): List<Iota>
|
fun execute(args: List<Iota>, ctx: CastingContext): List<Iota>
|
||||||
|
|
||||||
override fun operate(continuation: SpellContinuation, stack: MutableList<Iota>, local: Iota, ctx: CastingContext): OperationResult {
|
override fun operate(
|
||||||
|
continuation: SpellContinuation,
|
||||||
|
stack: MutableList<Iota>,
|
||||||
|
local: Iota,
|
||||||
|
ctx: CastingContext
|
||||||
|
): OperationResult {
|
||||||
if (this.argc > stack.size)
|
if (this.argc > stack.size)
|
||||||
throw MishapNotEnoughArgs(this.argc, stack.size)
|
throw MishapNotEnoughArgs(this.argc, stack.size)
|
||||||
val args = stack.takeLast(this.argc)
|
val args = stack.takeLast(this.argc)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package at.petrak.hexcasting.api.spell
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||||
import at.petrak.hexcasting.api.spell.casting.SpellContinuation
|
import at.petrak.hexcasting.api.spell.casting.SpellContinuation
|
||||||
|
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||||
import net.minecraft.world.phys.Vec3
|
import net.minecraft.world.phys.Vec3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,7 +22,12 @@ interface Operator {
|
||||||
*
|
*
|
||||||
* A particle effect at the cast site and various messages and advancements are done automagically.
|
* A particle effect at the cast site and various messages and advancements are done automagically.
|
||||||
*/
|
*/
|
||||||
fun operate(continuation: SpellContinuation, stack: MutableList<Iota>, local: Iota, ctx: CastingContext): OperationResult
|
fun operate(
|
||||||
|
continuation: SpellContinuation,
|
||||||
|
stack: MutableList<Iota>,
|
||||||
|
local: Iota,
|
||||||
|
ctx: CastingContext
|
||||||
|
): OperationResult
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do you need to be enlightened to use this operator? (i.e. is this operator a Great Pattern)
|
* Do you need to be enlightened to use this operator? (i.e. is this operator a Great Pattern)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
package at.petrak.hexcasting.api.spell
|
package at.petrak.hexcasting.api.spell
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.spell.iota.*
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidIota
|
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidIota
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
||||||
|
@ -9,14 +10,20 @@ import at.petrak.hexcasting.api.utils.asTranslatedComponent
|
||||||
import com.mojang.datafixers.util.Either
|
import com.mojang.datafixers.util.Either
|
||||||
import com.mojang.math.Vector3f
|
import com.mojang.math.Vector3f
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraft.world.entity.Entity
|
import net.minecraft.world.entity.Entity
|
||||||
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.entity.item.ItemEntity
|
||||||
|
import net.minecraft.world.entity.npc.Villager
|
||||||
import net.minecraft.world.phys.Vec3
|
import net.minecraft.world.phys.Vec3
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
import kotlin.math.roundToLong
|
||||||
|
|
||||||
fun numOrVec(datum: Iota, reverseIdx: Int): Either<Double, Vec3> =
|
fun numOrVec(datum: Iota, reverseIdx: Int): Either<Double, Vec3> =
|
||||||
when (datum.payload) {
|
when (datum) {
|
||||||
is Double -> Either.left(datum.payload)
|
is DoubleIota -> Either.left(datum.double)
|
||||||
is Vec3 -> Either.right(datum.payload)
|
is Vec3Iota -> Either.right(datum.vec3)
|
||||||
else -> throw MishapInvalidIota(
|
else -> throw MishapInvalidIota(
|
||||||
datum,
|
datum,
|
||||||
reverseIdx,
|
reverseIdx,
|
||||||
|
@ -25,9 +32,9 @@ fun numOrVec(datum: Iota, reverseIdx: Int): Either<Double, Vec3> =
|
||||||
}
|
}
|
||||||
|
|
||||||
fun numOrList(datum: Iota, reverseIdx: Int): Either<Double, SpellList> =
|
fun numOrList(datum: Iota, reverseIdx: Int): Either<Double, SpellList> =
|
||||||
when (datum.payload) {
|
when (datum) {
|
||||||
is Double -> Either.left(datum.payload)
|
is DoubleIota -> Either.left(datum.double)
|
||||||
is SpellList -> Either.right(datum.payload)
|
is ListIota -> Either.right(datum.list)
|
||||||
else -> throw MishapInvalidIota(
|
else -> throw MishapInvalidIota(
|
||||||
datum,
|
datum,
|
||||||
reverseIdx,
|
reverseIdx,
|
||||||
|
@ -35,38 +42,176 @@ fun numOrList(datum: Iota, reverseIdx: Int): Either<Double, SpellList> =
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun spellListOf(vararg vs: Any): List<Iota> {
|
fun List<Iota>.getDouble(idx: Int, argc: Int = 0): Double {
|
||||||
val out = ArrayList<Iota>(vs.size)
|
|
||||||
for (v in vs) {
|
|
||||||
out.add(LegacySpellDatum.make(v))
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <reified T : Any> List<Iota>.getChecked(idx: Int, argc: Int = 0): T {
|
|
||||||
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
if (x.payload is T)
|
if (x is DoubleIota) {
|
||||||
return x.payload
|
return x.double
|
||||||
else
|
} else {
|
||||||
throw MishapInvalidIota.ofClass(x, if (argc == 0) idx else argc - (idx + 1), T::class.java)
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "double")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun List<Iota>.getEntity(idx: Int, argc: Int = 0): Entity {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is EntityIota) {
|
||||||
|
return x.entity
|
||||||
|
} else {
|
||||||
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline val Boolean.asSpellResult get() = spellListOf(if (this) 1.0 else 0.0)
|
fun List<Iota>.getList(idx: Int, argc: Int = 0): SpellList {
|
||||||
inline val Double.asSpellResult get() = spellListOf(this)
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
inline val Number.asSpellResult get() = spellListOf(this.toDouble())
|
if (x is ListIota) {
|
||||||
|
return x.list
|
||||||
|
} else {
|
||||||
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline val SpellList.asSpellResult get() = spellListOf(this)
|
fun List<Iota>.getPattern(idx: Int, argc: Int = 0): HexPattern {
|
||||||
inline val List<Iota>.asSpellResult get() = spellListOf(this)
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is PatternIota) {
|
||||||
|
return x.pattern
|
||||||
|
} else {
|
||||||
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "pattern")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline val Widget.asSpellResult get() = spellListOf(this)
|
fun List<Iota>.getVec3(idx: Int, argc: Int = 0): Vec3 {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is Vec3Iota) {
|
||||||
|
return x.vec3
|
||||||
|
} else {
|
||||||
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "vector")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline val BlockPos.asSpellResult get() = spellListOf(Vec3.atCenterOf(this))
|
// Helpers
|
||||||
inline val Vector3f.asSpellResult get() = spellListOf(Vec3(this))
|
|
||||||
inline val Vec3.asSpellResult get() = spellListOf(this)
|
|
||||||
|
|
||||||
inline val Entity?.asSpellResult get() = spellListOf(this ?: Widget.NULL)
|
fun List<Iota>.getItemEntity(idx: Int, argc: Int = 0): ItemEntity {
|
||||||
inline val HexPattern.asSpellResult get() = spellListOf(this)
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is EntityIota) {
|
||||||
|
val e = x.entity
|
||||||
|
if (e is ItemEntity)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.item")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Iota>.getPlayer(idx: Int, argc: Int = 0): ServerPlayer {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is EntityIota) {
|
||||||
|
val e = x.entity
|
||||||
|
if (e is ServerPlayer)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.player")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Iota>.getVillager(idx: Int, argc: Int = 0): Villager {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is EntityIota) {
|
||||||
|
val e = x.entity
|
||||||
|
if (e is Villager)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.villager")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Iota>.getLivingEntity(idx: Int, argc: Int = 0): LivingEntity {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is EntityIota) {
|
||||||
|
val e = x.entity
|
||||||
|
if (e is LivingEntity)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.living")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Iota>.getPositiveDoubleB(idx: Int, argc: Int = 0): Double {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is DoubleIota) {
|
||||||
|
val double = x.double
|
||||||
|
if (0 <= double) {
|
||||||
|
return double
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "double.positive")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Iota>.getDoubleBetween(idx: Int, min: Double, max: Double, argc: Int = 0): Double {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is DoubleIota) {
|
||||||
|
val double = x.double
|
||||||
|
if (double in min..max) {
|
||||||
|
return double
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "double.between", min, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Iota>.getInt(idx: Int, argc: Int = 0): Int {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is DoubleIota) {
|
||||||
|
val double = x.double
|
||||||
|
val rounded = double.roundToInt()
|
||||||
|
if (abs(double - rounded) <= DoubleIota.TOLERANCE) {
|
||||||
|
return rounded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Iota>.getLong(idx: Int, argc: Int = 0): Long {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is DoubleIota) {
|
||||||
|
val double = x.double
|
||||||
|
val rounded = double.roundToLong()
|
||||||
|
if (abs(double - rounded) <= DoubleIota.TOLERANCE) {
|
||||||
|
return rounded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "int") // shh we're lying
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Iota>.getPositiveInt(idx: Int, argc: Int = 0): Int {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is DoubleIota) {
|
||||||
|
val double = x.double
|
||||||
|
val rounded = double.roundToInt()
|
||||||
|
if (abs(double - rounded) <= DoubleIota.TOLERANCE && rounded > 0) {
|
||||||
|
return rounded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "int.positive")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Iota>.getIntBetween(idx: Int, min: Int, max: Int, argc: Int = 0): Int {
|
||||||
|
val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) }
|
||||||
|
if (x is DoubleIota) {
|
||||||
|
val double = x.double
|
||||||
|
val rounded = double.roundToInt()
|
||||||
|
if (abs(double - rounded) <= DoubleIota.TOLERANCE && rounded in min..max) {
|
||||||
|
return rounded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "double.between", min, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline val Boolean.asSpellResult get() = listOf(DoubleIota(if (this) 1.0 else 0.0))
|
||||||
|
inline val Double.asSpellResult get() = listOf(DoubleIota(this))
|
||||||
|
inline val Number.asSpellResult get() = listOf(DoubleIota(this.toDouble()))
|
||||||
|
|
||||||
|
inline val SpellList.asSpellResult get() = listOf(ListIota(this))
|
||||||
|
inline val List<Iota>.asSpellResult get() = listOf(ListIota(this))
|
||||||
|
|
||||||
|
inline val BlockPos.asSpellResult get() = listOf(Vec3Iota(Vec3.atCenterOf(this)))
|
||||||
|
inline val Vector3f.asSpellResult get() = listOf(Vec3Iota(Vec3(this)))
|
||||||
|
inline val Vec3.asSpellResult get() = listOf(Vec3Iota(this))
|
||||||
|
|
||||||
|
inline val Entity?.asSpellResult get() = listOf(if (this == null) NullIota.INSTANCE else EntityIota(this))
|
||||||
|
inline val HexPattern.asSpellResult get() = listOf(PatternIota(this))
|
||||||
|
|
||||||
private const val TOLERANCE = 0.0001
|
private const val TOLERANCE = 0.0001
|
||||||
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
package at.petrak.hexcasting.api.spell
|
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Miscellaneous spell datums used as markers, etc.
|
|
||||||
*
|
|
||||||
* They act as operators that push themselves.
|
|
||||||
*/
|
|
||||||
enum class Widget : ConstManaOperator {
|
|
||||||
NULL,
|
|
||||||
OPEN_PAREN, CLOSE_PAREN, ESCAPE,
|
|
||||||
GARBAGE;
|
|
||||||
|
|
||||||
override val argc: Int
|
|
||||||
get() = 0
|
|
||||||
|
|
||||||
override fun execute(args: List<Iota>, ctx: CastingContext): List<Iota> =
|
|
||||||
this.asSpellResult
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmStatic
|
|
||||||
fun fromString(key: String): Widget {
|
|
||||||
val lowercaseKey = key.lowercase(Locale.ROOT)
|
|
||||||
return values().firstOrNull { it.name.lowercase(Locale.ROOT) == lowercaseKey } ?: GARBAGE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,8 +8,12 @@ import at.petrak.hexcasting.api.misc.HexDamageSources
|
||||||
import at.petrak.hexcasting.api.mod.HexConfig
|
import at.petrak.hexcasting.api.mod.HexConfig
|
||||||
import at.petrak.hexcasting.api.mod.HexItemTags
|
import at.petrak.hexcasting.api.mod.HexItemTags
|
||||||
import at.petrak.hexcasting.api.mod.HexStatistics
|
import at.petrak.hexcasting.api.mod.HexStatistics
|
||||||
import at.petrak.hexcasting.api.spell.*
|
import at.petrak.hexcasting.api.spell.Operator
|
||||||
|
import at.petrak.hexcasting.api.spell.ParticleSpray
|
||||||
|
import at.petrak.hexcasting.api.spell.SpellList
|
||||||
|
import at.petrak.hexcasting.api.spell.Widget
|
||||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
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.NullIota
|
||||||
import at.petrak.hexcasting.api.spell.iota.PatternIota
|
import at.petrak.hexcasting.api.spell.iota.PatternIota
|
||||||
import at.petrak.hexcasting.api.spell.math.HexDir
|
import at.petrak.hexcasting.api.spell.math.HexDir
|
||||||
|
@ -17,6 +21,7 @@ import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.*
|
import at.petrak.hexcasting.api.spell.mishaps.*
|
||||||
import at.petrak.hexcasting.api.utils.*
|
import at.petrak.hexcasting.api.utils.*
|
||||||
import at.petrak.hexcasting.common.items.magic.ItemCreativeUnlocker
|
import at.petrak.hexcasting.common.items.magic.ItemCreativeUnlocker
|
||||||
|
import at.petrak.hexcasting.common.lib.HexIotaTypes
|
||||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
|
@ -240,7 +245,7 @@ class CastingHarness private constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateDescs() = stack.map { it.type.display(it) }
|
fun generateDescs() = stack.map(Iota::display)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the functional update represented by the current state (for use with `copy`)
|
* Return the functional update represented by the current state (for use with `copy`)
|
||||||
|
@ -300,7 +305,7 @@ class CastingHarness private constructor(
|
||||||
val newParenCount = this.parenCount - 1
|
val newParenCount = this.parenCount - 1
|
||||||
if (newParenCount == 0) {
|
if (newParenCount == 0) {
|
||||||
val newStack = this.stack.toMutableList()
|
val newStack = this.stack.toMutableList()
|
||||||
newStack.add(LegacySpellDatum.make(this.parenthesized.toList()))
|
newStack.add(ListIota(this.parenthesized.toList()))
|
||||||
this.getFunctionalData().copy(
|
this.getFunctionalData().copy(
|
||||||
stack = newStack,
|
stack = newStack,
|
||||||
parenCount = newParenCount,
|
parenCount = newParenCount,
|
||||||
|
@ -438,7 +443,7 @@ class CastingHarness private constructor(
|
||||||
fun serializeToNBT() = NBTBuilder {
|
fun serializeToNBT() = NBTBuilder {
|
||||||
TAG_STACK %= stack.serializeToNBT()
|
TAG_STACK %= stack.serializeToNBT()
|
||||||
|
|
||||||
TAG_LOCAL %= ravenmind.serializeToNBT()
|
TAG_LOCAL %= HexIotaTypes.serialize(ravenmind)
|
||||||
TAG_PAREN_COUNT %= parenCount
|
TAG_PAREN_COUNT %= parenCount
|
||||||
TAG_ESCAPE_NEXT %= escapeNext
|
TAG_ESCAPE_NEXT %= escapeNext
|
||||||
|
|
||||||
|
@ -463,23 +468,16 @@ class CastingHarness private constructor(
|
||||||
val stack = mutableListOf<Iota>()
|
val stack = mutableListOf<Iota>()
|
||||||
val stackTag = nbt.getList(TAG_STACK, Tag.TAG_COMPOUND)
|
val stackTag = nbt.getList(TAG_STACK, Tag.TAG_COMPOUND)
|
||||||
for (subtag in stackTag) {
|
for (subtag in stackTag) {
|
||||||
val datum = LegacySpellDatum.fromNBT(subtag.asCompound, ctx.world)
|
val datum = HexIotaTypes.deserialize(subtag.asCompound, ctx.world)
|
||||||
stack.add(datum)
|
stack.add(datum)
|
||||||
}
|
}
|
||||||
|
|
||||||
val localTag = nbt.getCompound(TAG_LOCAL)
|
val localIota = HexIotaTypes.deserialize(nbt.getCompound(TAG_LOCAL), ctx.world)
|
||||||
val localIota =
|
|
||||||
if (localTag.size() == 1) LegacySpellDatum.fromNBT(localTag, ctx.world) else LegacySpellDatum.make(
|
|
||||||
Widget.NULL
|
|
||||||
)
|
|
||||||
|
|
||||||
val parenthesized = mutableListOf<Iota>()
|
val parenthesized = mutableListOf<Iota>()
|
||||||
val parenTag = nbt.getList(TAG_PARENTHESIZED, Tag.TAG_COMPOUND)
|
val parenTag = nbt.getList(TAG_PARENTHESIZED, Tag.TAG_COMPOUND)
|
||||||
for (subtag in parenTag) {
|
for (subtag in parenTag) {
|
||||||
if (subtag.asCompound.size() != 1)
|
parenthesized.add(HexIotaTypes.deserialize(nbt.getCompound(TAG_LOCAL), ctx.world))
|
||||||
parenthesized.add(LegacySpellDatum.make(HexPattern.fromNBT(subtag.asCompound)))
|
|
||||||
else
|
|
||||||
parenthesized.add(LegacySpellDatum.fromNBT(subtag.asCompound, ctx.world))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val parenCount = nbt.getInt(TAG_PAREN_COUNT)
|
val parenCount = nbt.getInt(TAG_PAREN_COUNT)
|
||||||
|
|
|
@ -127,7 +127,7 @@ sealed interface ContinuationFrame {
|
||||||
override fun breakDownwards(stack: List<Iota>): Pair<Boolean, List<Iota>> {
|
override fun breakDownwards(stack: List<Iota>): Pair<Boolean, List<Iota>> {
|
||||||
val newStack = baseStack?.toMutableList() ?: mutableListOf()
|
val newStack = baseStack?.toMutableList() ?: mutableListOf()
|
||||||
acc.addAll(stack)
|
acc.addAll(stack)
|
||||||
newStack.add(ListIota(SpellList.LList(acc)))
|
newStack.add(ListIota(acc))
|
||||||
return true to newStack
|
return true to newStack
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ sealed interface ContinuationFrame {
|
||||||
.pushFrame(Evaluate(code))
|
.pushFrame(Evaluate(code))
|
||||||
} else {
|
} else {
|
||||||
// Else, dump our final list onto the stack.
|
// Else, dump our final list onto the stack.
|
||||||
ListIota(SpellList.LList(acc)) to continuation
|
ListIota(acc) to continuation
|
||||||
}
|
}
|
||||||
val tStack = stack.toMutableList()
|
val tStack = stack.toMutableList()
|
||||||
tStack.add(stackTop)
|
tStack.add(stackTop)
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class EntityIota extends Iota {
|
public class EntityIota extends Iota {
|
||||||
protected EntityIota(@NotNull Entity e) {
|
public EntityIota(@NotNull Entity e) {
|
||||||
super(HexIotaTypes.ENTITY, e);
|
super(HexIotaTypes.ENTITY, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,11 @@ public class EntityIota extends Iota {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component display() {
|
||||||
|
return this.getEntity().getName();
|
||||||
|
}
|
||||||
|
|
||||||
public static IotaType<EntityIota> TYPE = new IotaType<>() {
|
public static IotaType<EntityIota> TYPE = new IotaType<>() {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
|
@ -65,11 +70,6 @@ public class EntityIota extends Iota {
|
||||||
return Component.Serializer.fromJsonLenient(nameJson);
|
return Component.Serializer.fromJsonLenient(nameJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component display(EntityIota iota) {
|
|
||||||
return iota.getEntity().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int color() {
|
public int color() {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
public class GarbageIota extends Iota {
|
public class GarbageIota extends Iota {
|
||||||
private static final Object NULL_SUBSTITUTE = new Object();
|
private static final Object NULL_SUBSTITUTE = new Object();
|
||||||
|
|
||||||
|
public static final GarbageIota INSTANCE = new GarbageIota();
|
||||||
|
|
||||||
public GarbageIota() {
|
public GarbageIota() {
|
||||||
// We have to pass *something* here, but there's nothing that actually needs to go there,
|
// We have to pass *something* here, but there's nothing that actually needs to go there,
|
||||||
|
|
|
@ -2,13 +2,14 @@ package at.petrak.hexcasting.api.spell.iota;
|
||||||
|
|
||||||
import at.petrak.hexcasting.common.lib.HexIotaTypes;
|
import at.petrak.hexcasting.common.lib.HexIotaTypes;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class Iota {
|
public abstract class Iota {
|
||||||
@NotNull
|
@NotNull
|
||||||
protected final Object payload;
|
protected final Object payload;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final IotaType<?> type;
|
protected final IotaType<?> type;
|
||||||
|
|
||||||
protected Iota(@NotNull IotaType<?> type, @NotNull Object payload) {
|
protected Iota(@NotNull IotaType<?> type, @NotNull Object payload) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
@ -37,6 +38,10 @@ public abstract class Iota {
|
||||||
*/
|
*/
|
||||||
abstract public @NotNull Tag serialize();
|
abstract public @NotNull Tag serialize();
|
||||||
|
|
||||||
|
public Component display() {
|
||||||
|
return this.type.display(this.serialize());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to see if two iotas have the same type.
|
* Helper method to see if two iotas have the same type.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,10 +26,6 @@ public abstract class IotaType<T extends Iota> {
|
||||||
*/
|
*/
|
||||||
public abstract Component display(Tag tag);
|
public abstract Component display(Tag tag);
|
||||||
|
|
||||||
public Component display(T iota) {
|
|
||||||
return this.display(iota.serialize());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the color associated with this datum type.
|
* Get the color associated with this datum type.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a <i>wrapper</i> for {@link SpellList}.
|
* This is a <i>wrapper</i> for {@link SpellList}.
|
||||||
|
@ -21,6 +22,10 @@ public class ListIota extends Iota {
|
||||||
super(HexIotaTypes.LIST, list);
|
super(HexIotaTypes.LIST, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ListIota(@NotNull List<Iota> list) {
|
||||||
|
this(new SpellList.LList(list));
|
||||||
|
}
|
||||||
|
|
||||||
public SpellList getList() {
|
public SpellList getList() {
|
||||||
return (SpellList) this.payload;
|
return (SpellList) this.payload;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +83,7 @@ public class ListIota extends Iota {
|
||||||
out.add(subiota);
|
out.add(subiota);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ListIota(new SpellList.LList(out));
|
return new ListIota(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,6 +14,8 @@ import org.jetbrains.annotations.Nullable;
|
||||||
public class NullIota extends Iota {
|
public class NullIota extends Iota {
|
||||||
private static final Object NULL_SUBSTITUTE = new Object();
|
private static final Object NULL_SUBSTITUTE = new Object();
|
||||||
|
|
||||||
|
public static final NullIota INSTANCE = new NullIota();
|
||||||
|
|
||||||
public NullIota() {
|
public NullIota() {
|
||||||
// We have to pass *something* here, but there's nothing that actually needs to go there,
|
// We have to pass *something* here, but there's nothing that actually needs to go there,
|
||||||
// so we just do this i guess
|
// so we just do this i guess
|
||||||
|
|
|
@ -2,9 +2,11 @@ package at.petrak.hexcasting.api.spell.mishaps
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||||
import at.petrak.hexcasting.api.misc.HexDamageSources
|
import at.petrak.hexcasting.api.misc.HexDamageSources
|
||||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
|
||||||
import at.petrak.hexcasting.api.spell.Widget
|
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||||
|
import at.petrak.hexcasting.api.spell.iota.DoubleIota
|
||||||
|
import at.petrak.hexcasting.api.spell.iota.GarbageIota
|
||||||
|
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||||
|
import at.petrak.hexcasting.api.spell.iota.Vec3Iota
|
||||||
import at.petrak.hexcasting.api.utils.asTranslatedComponent
|
import at.petrak.hexcasting.api.utils.asTranslatedComponent
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.item.DyeColor
|
import net.minecraft.world.item.DyeColor
|
||||||
|
@ -16,7 +18,7 @@ class MishapDivideByZero(val operand1: Component, val operand2: Component, val s
|
||||||
dyeColor(DyeColor.RED)
|
dyeColor(DyeColor.RED)
|
||||||
|
|
||||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<Iota>) {
|
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<Iota>) {
|
||||||
stack.add(LegacySpellDatum.make(Widget.GARBAGE))
|
stack.add(GarbageIota.INSTANCE)
|
||||||
trulyHurt(ctx.caster, HexDamageSources.OVERCAST, ctx.caster.health / 2)
|
trulyHurt(ctx.caster, HexDamageSources.OVERCAST, ctx.caster.health / 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,14 +29,14 @@ class MishapDivideByZero(val operand1: Component, val operand2: Component, val s
|
||||||
private const val PREFIX = "hexcasting.mishap.divide_by_zero"
|
private const val PREFIX = "hexcasting.mishap.divide_by_zero"
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun of(operand1: Any, operand2: Any, suffix: String = "divide"): MishapDivideByZero {
|
fun of(operand1: Iota, operand2: Iota, suffix: String = "divide"): MishapDivideByZero {
|
||||||
if (suffix == "exponent")
|
if (suffix == "exponent")
|
||||||
return MishapDivideByZero(translate(operand1), powerOf(operand2), suffix)
|
return MishapDivideByZero(translate(operand1), powerOf(operand2), suffix)
|
||||||
return MishapDivideByZero(translate(operand1), translate(operand2), suffix)
|
return MishapDivideByZero(translate(operand1), translate(operand2), suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun tan(angle: Double): MishapDivideByZero {
|
fun tan(angle: DoubleIota): MishapDivideByZero {
|
||||||
val translatedAngle = translate(angle)
|
val translatedAngle = translate(angle)
|
||||||
return MishapDivideByZero(
|
return MishapDivideByZero(
|
||||||
"$PREFIX.sin".asTranslatedComponent(translatedAngle),
|
"$PREFIX.sin".asTranslatedComponent(translatedAngle),
|
||||||
|
@ -58,16 +60,16 @@ class MishapDivideByZero(val operand1: Component, val operand2: Component, val s
|
||||||
fun powerOf(power: Component) = "$PREFIX.power".asTranslatedComponent(power)
|
fun powerOf(power: Component) = "$PREFIX.power".asTranslatedComponent(power)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun powerOf(datum: Any) = when (datum) {
|
fun powerOf(datum: Iota): Component = when {
|
||||||
0.0 -> zerothPower
|
datum is DoubleIota && datum.double == 0.0 -> zerothPower
|
||||||
else -> powerOf(LegacySpellDatum.make(datum).display())
|
else -> datum.display()
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun translate(datum: Any): Component = when (datum) {
|
fun translate(datum: Iota): Component = when {
|
||||||
0.0 -> zero
|
datum is DoubleIota && datum.double == 0.0 -> zero
|
||||||
Vec3.ZERO -> zeroVector
|
datum is Vec3Iota && datum.vec3 == Vec3.ZERO -> zeroVector
|
||||||
else -> LegacySpellDatum.make(datum).display()
|
else -> datum.display()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,12 @@
|
||||||
package at.petrak.hexcasting.api.spell.mishaps
|
package at.petrak.hexcasting.api.spell.mishaps
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
|
||||||
import at.petrak.hexcasting.api.spell.SpellList
|
|
||||||
import at.petrak.hexcasting.api.spell.Widget
|
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
import at.petrak.hexcasting.api.spell.iota.GarbageIota
|
||||||
|
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||||
import at.petrak.hexcasting.api.utils.asTranslatedComponent
|
import at.petrak.hexcasting.api.utils.asTranslatedComponent
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.entity.Entity
|
|
||||||
import net.minecraft.world.entity.LivingEntity
|
|
||||||
import net.minecraft.world.entity.item.ItemEntity
|
|
||||||
import net.minecraft.world.entity.npc.Villager
|
|
||||||
import net.minecraft.world.entity.player.Player
|
|
||||||
import net.minecraft.world.item.DyeColor
|
import net.minecraft.world.item.DyeColor
|
||||||
import net.minecraft.world.phys.Vec3
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value failed some kind of predicate.
|
* The value failed some kind of predicate.
|
||||||
|
@ -30,32 +22,25 @@ class MishapInvalidIota(
|
||||||
dyeColor(DyeColor.GRAY)
|
dyeColor(DyeColor.GRAY)
|
||||||
|
|
||||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<Iota>) {
|
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<Iota>) {
|
||||||
stack[stack.size - 1 - reverseIdx] = LegacySpellDatum.make(Widget.GARBAGE)
|
stack[stack.size - 1 - reverseIdx] = GarbageIota.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun errorMessage(ctx: CastingContext, errorCtx: Context) =
|
override fun errorMessage(ctx: CastingContext, errorCtx: Context) =
|
||||||
error("invalid_value", actionName(errorCtx.action), expected, reverseIdx,
|
error(
|
||||||
perpetrator.display())
|
"invalid_value", actionName(errorCtx.action), expected, reverseIdx,
|
||||||
|
perpetrator.display()
|
||||||
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun ofClass(perpetrator: Iota, reverseIdx: Int, cls: Class<*>): MishapInvalidIota {
|
fun ofType(perpetrator: Iota, reverseIdx: Int, name: String): MishapInvalidIota {
|
||||||
val key = "hexcasting.mishap.invalid_value.class." + when {
|
return of(perpetrator, reverseIdx, "class.$name")
|
||||||
Double::class.java.isAssignableFrom(cls) || Double::class.javaObjectType.isAssignableFrom(cls) -> "double"
|
}
|
||||||
Vec3::class.java.isAssignableFrom(cls) -> "vector"
|
|
||||||
SpellList::class.java.isAssignableFrom(cls) -> "list"
|
|
||||||
Widget::class.java.isAssignableFrom(cls) -> "widget"
|
|
||||||
HexPattern::class.java.isAssignableFrom(cls) -> "pattern"
|
|
||||||
|
|
||||||
ItemEntity::class.java.isAssignableFrom(cls) -> "entity.item"
|
@JvmStatic
|
||||||
Player::class.java.isAssignableFrom(cls) -> "entity.player"
|
fun of(perpetrator: Iota, reverseIdx: Int, name: String, vararg translations: Any): MishapInvalidIota {
|
||||||
Villager::class.java.isAssignableFrom(cls) -> "entity.villager"
|
val key = "hexcasting.mishap.invalid_value.$name"
|
||||||
LivingEntity::class.java.isAssignableFrom(cls) -> "entity.living"
|
return MishapInvalidIota(perpetrator, reverseIdx, key.asTranslatedComponent(*translations))
|
||||||
Entity::class.java.isAssignableFrom(cls) -> "entity"
|
|
||||||
|
|
||||||
else -> "unknown"
|
|
||||||
}
|
|
||||||
return MishapInvalidIota(perpetrator, reverseIdx, key.asTranslatedComponent)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
package at.petrak.hexcasting.api.utils
|
package at.petrak.hexcasting.api.utils
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.spell.SpellList
|
|
||||||
import at.petrak.hexcasting.api.spell.iota.Iota
|
import at.petrak.hexcasting.api.spell.iota.Iota
|
||||||
import at.petrak.hexcasting.api.spell.iota.ListIota
|
import at.petrak.hexcasting.api.spell.iota.ListIota
|
||||||
import at.petrak.hexcasting.api.spell.math.HexCoord
|
import at.petrak.hexcasting.api.spell.math.HexCoord
|
||||||
|
@ -237,7 +236,7 @@ fun Iterable<Iota>.serializeToNBT() =
|
||||||
if (HexIotaTypes.isTooLargeToSerialize(this))
|
if (HexIotaTypes.isTooLargeToSerialize(this))
|
||||||
ListTag()
|
ListTag()
|
||||||
else
|
else
|
||||||
ListIota(SpellList.LList(this.toList())).serialize()
|
ListIota(this.toList()).serialize()
|
||||||
|
|
||||||
// Copy the impl from forge
|
// Copy the impl from forge
|
||||||
fun ItemStack.serializeToNBT(): CompoundTag {
|
fun ItemStack.serializeToNBT(): CompoundTag {
|
||||||
|
|
|
@ -25,7 +25,7 @@ class OpPotionEffect(
|
||||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||||
val target = args.getChecked<LivingEntity>(0, argc)
|
val target = args.getChecked<LivingEntity>(0, argc)
|
||||||
if (target is ArmorStand)
|
if (target is ArmorStand)
|
||||||
throw MishapInvalidIota.ofClass(LegacySpellDatum.make(target), 0, LivingEntity::class.java)
|
throw MishapInvalidIota.ofType(LegacySpellDatum.make(target), 0, LivingEntity::class.java)
|
||||||
val duration = max(args.getChecked(1, argc), 0.0)
|
val duration = max(args.getChecked(1, argc), 0.0)
|
||||||
ctx.assertEntityInRange(target)
|
ctx.assertEntityInRange(target)
|
||||||
val potency = if (this.allowPotency)
|
val potency = if (this.allowPotency)
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package at.petrak.hexcasting.common.items;
|
package at.petrak.hexcasting.common.items;
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.item.IotaHolderItem;
|
import at.petrak.hexcasting.api.item.IotaHolderItem;
|
||||||
import at.petrak.hexcasting.api.spell.DatumType;
|
|
||||||
import at.petrak.hexcasting.api.spell.iota.Iota;
|
import at.petrak.hexcasting.api.spell.iota.Iota;
|
||||||
|
import at.petrak.hexcasting.api.spell.iota.PatternIota;
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
||||||
import at.petrak.hexcasting.api.utils.NBTHelper;
|
import at.petrak.hexcasting.api.utils.NBTHelper;
|
||||||
import at.petrak.hexcasting.client.gui.PatternTooltipGreeble;
|
import at.petrak.hexcasting.client.gui.PatternTooltipGreeble;
|
||||||
import at.petrak.hexcasting.common.entities.EntityWallScroll;
|
import at.petrak.hexcasting.common.entities.EntityWallScroll;
|
||||||
|
import at.petrak.hexcasting.common.lib.HexIotaTypes;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
@ -54,14 +55,16 @@ public class ItemScroll extends Item implements IotaHolderItem {
|
||||||
if (pattern == null) {
|
if (pattern == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
// We store only the data part of the iota; pretend the rest of it's there
|
||||||
var out = new CompoundTag();
|
var out = new CompoundTag();
|
||||||
out.put(LegacySpellDatum.TAG_PATTERN, pattern);
|
out.putString(HexIotaTypes.KEY_TYPE, "hexcasting:pattern");
|
||||||
|
out.put(HexIotaTypes.KEY_DATA, pattern);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canWrite(ItemStack stack, Iota datum) {
|
public boolean canWrite(ItemStack stack, Iota datum) {
|
||||||
return datum != null && datum.getType() == DatumType.PATTERN && !NBTHelper.hasCompound(stack, TAG_PATTERN);
|
return datum instanceof PatternIota && !NBTHelper.hasCompound(stack, TAG_PATTERN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,10 +14,7 @@ import net.minecraft.server.level.ServerLevel;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||||
|
@ -112,7 +109,6 @@ public class HexIotaTypes {
|
||||||
* }
|
* }
|
||||||
* </code>
|
* </code>
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
public static Iota deserialize(CompoundTag tag, ServerLevel world) {
|
public static Iota deserialize(CompoundTag tag, ServerLevel world) {
|
||||||
var type = getTypeFromTag(tag);
|
var type = getTypeFromTag(tag);
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
|
@ -122,10 +118,16 @@ public class HexIotaTypes {
|
||||||
if (dataKey == null) {
|
if (dataKey == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return type.deserialize(tag, world);
|
Iota deserialized;
|
||||||
|
try {
|
||||||
|
deserialized = Objects.requireNonNullElse(type.deserialize(tag, world), NullIota.INSTANCE);
|
||||||
|
} catch (IllegalArgumentException exn) {
|
||||||
|
HexAPI.LOGGER.warn("Caught an exception deserializing an iota", exn);
|
||||||
|
deserialized = GarbageIota.INSTANCE;
|
||||||
|
}
|
||||||
|
return deserialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static Component getDisplay(CompoundTag tag) {
|
public static Component getDisplay(CompoundTag tag) {
|
||||||
var type = getTypeFromTag(tag);
|
var type = getTypeFromTag(tag);
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
|
|
|
@ -386,8 +386,10 @@
|
||||||
"hexcasting.mishap.invalid_value.numvec": "a number or vector",
|
"hexcasting.mishap.invalid_value.numvec": "a number or vector",
|
||||||
"hexcasting.mishap.invalid_value.numlist": "a number or list",
|
"hexcasting.mishap.invalid_value.numlist": "a number or list",
|
||||||
"hexcasting.mishap.invalid_value.list.pattern": "a list of patterns",
|
"hexcasting.mishap.invalid_value.list.pattern": "a list of patterns",
|
||||||
"hexcasting.mishap.invalid_value.int": "an integer",
|
"hexcasting.mishap.invalid_value.double.positive": "a positive number",
|
||||||
"hexcasting.mishap.invalid_value.double.between": "a number between %d and %d",
|
"hexcasting.mishap.invalid_value.double.between": "a number between %d and %d",
|
||||||
|
"hexcasting.mishap.invalid_value.int": "an integer",
|
||||||
|
"hexcasting.mishap.invalid_value.int.positive": "a positive integer",
|
||||||
"hexcasting.mishap.invalid_value.int.between": "an integer between %d and %d",
|
"hexcasting.mishap.invalid_value.int.between": "an integer between %d and %d",
|
||||||
"hexcasting.mishap.not_enough_args": "%s expected %s or more arguments but the stack was only %s tall",
|
"hexcasting.mishap.not_enough_args": "%s expected %s or more arguments but the stack was only %s tall",
|
||||||
"hexcasting.mishap.too_many_close_parens": "Used Retrospection without first using Introspection",
|
"hexcasting.mishap.too_many_close_parens": "Used Retrospection without first using Introspection",
|
||||||
|
|
Loading…
Reference in a new issue