apply division by zero to other forms of division

0^0 is also handled
This commit is contained in:
yrsegal@gmail.com 2022-04-09 20:33:08 -04:00
parent 67d7e20469
commit a3839cfa23
4 changed files with 74 additions and 23 deletions

View file

@ -2,27 +2,59 @@ package at.petrak.hexcasting.common.casting.mishaps
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.Widget
import at.petrak.hexcasting.common.casting.colors.FrozenColorizer
import at.petrak.hexcasting.common.lib.HexDamageSources
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.TextComponent
import net.minecraft.network.chat.TranslatableComponent
import net.minecraft.world.item.DyeColor
import net.minecraft.world.phys.Vec3
class MishapDivideByZero(val numerator: Component, val wasVec: Boolean) : Mishap() {
constructor(number: Double) : this(TextComponent("%d".format(number)), false)
constructor(vec: Vec3) : this(SpellDatum.make(vec).display(), true)
class MishapDivideByZero(val operand1: Component, val operand2: Component, val suffix: String = "divide") : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.RED)
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
stack.add(SpellDatum.make(Widget.GARBAGE))
ctx.caster.hurt(HexDamageSources.OVERCAST, ctx.caster.health / 2)
}
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component {
if (wasVec)
return error("divide_by_zero_vec", numerator)
return error("divide_by_zero", numerator)
return error("divide_by_zero.$suffix", operand1, operand2)
}
companion object {
private const val PREFIX = "hexcasting.mishap.divide_by_zero"
@JvmStatic
fun of(operand1: Any, operand2: Any, suffix: String = "divide"): MishapDivideByZero {
if (suffix == "exponent")
return MishapDivideByZero(translate(operand1), powerOf(operand2), suffix)
return MishapDivideByZero(translate(operand1), translate(operand2), suffix)
}
@JvmStatic
val zero get() = TranslatableComponent("$PREFIX.zero")
@JvmStatic
val zerothPower get() = TranslatableComponent("$PREFIX.zero.power")
@JvmStatic
val zeroVector get() = TranslatableComponent("$PREFIX.zero.vec")
@JvmStatic
fun powerOf(power: Component) = TranslatableComponent("$PREFIX.power", power)
@JvmStatic
fun powerOf(datum: Any) = when (datum) {
0.0 -> zerothPower
else -> powerOf(SpellDatum.make(datum).display())
}
@JvmStatic
fun translate(datum: Any): Component = when (datum) {
0.0 -> zero
Vec3.ZERO -> zeroVector
else -> SpellDatum.make(datum).display()
}
}
}

View file

@ -20,27 +20,23 @@ object OpDivCross : ConstManaOperator {
rhs.map(
{ rnum ->
if (rnum == 0.0)
throw MishapDivideByZero(lnum)
throw MishapDivideByZero.of(lnum, rnum)
lnum / rnum
},
{ rvec ->
if (rvec.x == 0.0 && rvec.y == 0.0 && rvec.z == 0.0)
throw MishapDivideByZero(lnum)
if (rvec.x == 0.0 || rvec.y == 0.0 || rvec.z == 0.0)
throw MishapDivideByZero.of(lnum, rvec)
Vec3(lnum / rvec.x, lnum / rvec.y, lnum / rvec.z)
}
)
}, { lvec ->
rhs.map(
{ rnum ->
if (rnum == 0.0)
throw MishapDivideByZero(lvec)
if (lvec == Vec3.ZERO)
throw MishapDivideByZero.of(lvec, rnum)
lvec.scale(1.0 / rnum)
},
{ rvec ->
if (rvec.x == 0.0 && rvec.y == 0.0 && rvec.z == 0.0)
throw MishapDivideByZero(lvec)
lvec.cross(rvec)
}
{ rvec -> lvec.cross(rvec) }
)
})
)

View file

@ -4,6 +4,8 @@ import at.petrak.hexcasting.api.spell.ConstManaOperator
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.mishaps.MishapDivideByZero
import net.minecraft.network.chat.TranslatableComponent
import net.minecraft.world.phys.Vec3
import kotlin.math.pow
@ -18,12 +20,28 @@ object OpPowProj : ConstManaOperator {
return spellListOf(
lhs.map({ lnum ->
rhs.map(
{ rnum -> lnum.pow(rnum) }, { rvec -> Vec3(lnum.pow(rvec.x), lnum.pow(rvec.y), lnum.pow(rvec.z)) }
{ rnum ->
if (rnum == 0.0 && lnum == 0.0)
throw MishapDivideByZero.of(lnum, rnum, "exponent")
lnum.pow(rnum)
}, { rvec ->
if (lnum == 0.0 && (rvec.x == 0.0 || rvec.y == 0.0 || rvec.z == 0.0))
throw MishapDivideByZero.of(lnum, rvec, "exponent")
Vec3(lnum.pow(rvec.x), lnum.pow(rvec.y), lnum.pow(rvec.z))
}
)
}, { lvec ->
rhs.map(
{ rnum -> Vec3(lvec.x.pow(rnum), lvec.y.pow(rnum), lvec.z.pow(rnum)) },
{ rvec -> rvec.scale(lvec.dot(rvec) / rvec.dot(rvec)) }
{ rnum ->
if (rnum == 0.0 && (lvec.x == 0.0 || lvec.y == 0.0 || lvec.z == 0.0))
throw MishapDivideByZero.of(lvec, rnum, "exponent")
Vec3(lvec.x.pow(rnum), lvec.y.pow(rnum), lvec.z.pow(rnum))
},
{ rvec ->
if (rvec == Vec3.ZERO)
throw MishapDivideByZero.of(lvec, rvec, "project")
rvec.scale(lvec.dot(rvec) / rvec.dot(rvec))
}
)
})
)

View file

@ -318,8 +318,13 @@
"hexcasting.mishap.already_brainswept": "The villager has already been used",
"hexcasting.mishap.no_spell_circle": "%s requires a spell circle",
"hexcasting.mishap.others_name": "Tried to invade %s's privacy",
"hexcasting.mishap.divide_by_zero": "Attempted to divide %s by zero",
"hexcasting.mishap.divide_by_zero_vec": "Attempted to divide %s by a zero vector",
"hexcasting.mishap.divide_by_zero.divide": "Attempted to divide %s by %s",
"hexcasting.mishap.divide_by_zero.project": "Attempted to project %s onto %s",
"hexcasting.mishap.divide_by_zero.exponent": "Attempted to raise %s to the %s",
"hexcasting.mishap.divide_by_zero.zero": "zero",
"hexcasting.mishap.divide_by_zero.zero.power": "zeroth power",
"hexcasting.mishap.divide_by_zero.zero.vec": "the zero vector",
"hexcasting.mishap.divide_by_zero.power": "power of %s",
"hexcasting.mishap.no_akashic_record": "No akashic record at %s",
"hexcasting.landing": "I seem to have discovered a new method of magical arts, in which one draws patterns strange and wild onto a hexagonal grid. It fascinates me. I've decided to start a journal of my thoughts and findings.$(br2)$(l:https://discord.gg/4xxHGYteWk)Discord Server Link/$",