diff --git a/Common/src/main/java/at/petrak/hexcasting/api/spell/SpellDatum.kt b/Common/src/main/java/at/petrak/hexcasting/api/spell/SpellDatum.kt index cee4515f..9ac22246 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/spell/SpellDatum.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/spell/SpellDatum.kt @@ -15,6 +15,7 @@ import net.minecraft.server.level.ServerLevel import net.minecraft.world.entity.Entity import net.minecraft.world.phys.Vec3 import java.util.* +import kotlin.math.abs /** * Data allowed into a spell. @@ -99,6 +100,21 @@ class SpellDatum private constructor(val payload: T) { else -> DatumType.OTHER } + // Todo: make more things use this + fun equalsWithDoubleTolerance(other: SpellDatum<*>): Boolean { + if (this == other) { + return true + } + val tolerance = 0.0001 + if (this.payload is Double && other.payload is Double) { + return abs(this.payload - other.payload) < tolerance + } + if (this.payload is Vec3 && other.payload is Vec3) { + return this.payload.distanceToSqr(other.payload) < tolerance * tolerance + } + return false + } + companion object { @JvmStatic fun make(payload: Any): SpellDatum<*> = @@ -181,11 +197,23 @@ class SpellDatum private constructor(val payload: T) { throw IllegalArgumentException("Expected exactly one kv pair: $nbt") return when (val key = keys.iterator().next()) { - TAG_DOUBLE -> TextComponent(String.format("%.4f", nbt.getDouble(TAG_DOUBLE))).withStyle(ChatFormatting.GREEN) + TAG_DOUBLE -> TextComponent( + String.format( + "%.4f", + nbt.getDouble(TAG_DOUBLE) + ) + ).withStyle(ChatFormatting.GREEN) TAG_VEC3 -> { val vec = HexUtils.DeserializeVec3FromNBT(nbt.getLongArray(key)) // the focus color is really more red, but we don't want to show an error-y color - TextComponent(String.format("(%.2f, %.2f, %.2f)", vec.x, vec.y, vec.z)).withStyle(ChatFormatting.LIGHT_PURPLE) + TextComponent( + String.format( + "(%.2f, %.2f, %.2f)", + vec.x, + vec.y, + vec.z + ) + ).withStyle(ChatFormatting.LIGHT_PURPLE) } TAG_LIST -> { val out = TextComponent("[").withStyle(ChatFormatting.WHITE) @@ -203,7 +231,10 @@ class SpellDatum private constructor(val payload: T) { } TAG_WIDGET -> { val widget = Widget.valueOf(nbt.getString(key)) - if (widget == Widget.GARBAGE) TextComponent("arimfexendrapuse").withStyle(ChatFormatting.DARK_GRAY, ChatFormatting.OBFUSCATED) + if (widget == Widget.GARBAGE) TextComponent("arimfexendrapuse").withStyle( + ChatFormatting.DARK_GRAY, + ChatFormatting.OBFUSCATED + ) // use dark purple instead of pink, so that vec3 can be pink instead of error red else TextComponent(widget.toString()).withStyle(ChatFormatting.DARK_PURPLE) } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpAnd.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpAnd.kt index f3d2f800..1a2099e2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpAnd.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpAnd.kt @@ -18,7 +18,7 @@ object OpAnd : ConstManaOperator { if (firstParam.right().isPresent) { val list1 = firstParam.right().get() val list2 = args.getChecked(1) - return spellListOf(list1.filter { it in list2 }) + return spellListOf(list1.filter { x -> list2.any { x.equalsWithDoubleTolerance(it) } }) } val num1 = firstParam.left().get().roundToInt() diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpOr.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpOr.kt index a94117c1..d31e87e6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpOr.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpOr.kt @@ -18,7 +18,7 @@ object OpOr : ConstManaOperator { if (firstParam.right().isPresent) { val list1 = firstParam.right().get() val list2 = args.getChecked(1) - return spellListOf(list1 + list2.filter { it !in list1 }) + return spellListOf(list1 + list2.filter { x -> list1.none { x.equalsWithDoubleTolerance(it) } }) } val num1 = firstParam.left().get().roundToInt() diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpToSet.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpToSet.kt index f007dfba..bf1ce261 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpToSet.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpToSet.kt @@ -2,7 +2,6 @@ package at.petrak.hexcasting.common.casting.operators.math.bit import at.petrak.hexcasting.api.spell.ConstManaOperator import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked -import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.api.spell.SpellList import at.petrak.hexcasting.api.spell.casting.CastingContext @@ -12,6 +11,14 @@ object OpToSet : ConstManaOperator { override fun execute(args: List>, ctx: CastingContext): List> { val payload = args.getChecked(0) - return spellListOf(payload.toSet().toList()) + // augh + val out = mutableListOf>() + // i am not sure of a better way to do this + for (v in payload) { + if (out.none { it.equalsWithDoubleTolerance(v) }) { + out.add(v) + } + } + return out } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpXor.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpXor.kt index 72297fdd..4fa114eb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpXor.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/math/bit/OpXor.kt @@ -18,7 +18,9 @@ object OpXor : ConstManaOperator { if (firstParam.right().isPresent) { val list1 = firstParam.right().get() val list2 = args.getChecked(1) - return spellListOf(list1.filter { it !in list2 } + list2.filter { it !in list1 }) + return spellListOf( + list1.filter { x1 -> list2.none { x1.equalsWithDoubleTolerance(it) } } + + list2.filter { x2 -> list1.none { x2.equalsWithDoubleTolerance(it) } }) } val num1 = firstParam.left().get().roundToInt()