more mishap mishaps

This commit is contained in:
gamma-delta 2022-03-26 11:45:31 -05:00
parent 239762fc01
commit a910b0113a
12 changed files with 223 additions and 55 deletions

View file

@ -3,17 +3,18 @@ package at.petrak.hexcasting.common.casting.mishaps
import at.petrak.hexcasting.api.spell.ParticleSpray
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.items.HexItems
import net.minecraft.Util
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.TranslatableComponent
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.DyeColor
import java.util.regex.Pattern
sealed class Mishap : Throwable() {
/** Mishaps spray half-red, half-this-color. */
abstract fun accentColor(ctx: CastingContext): FrozenColorizer
abstract fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer
open fun particleSpray(ctx: CastingContext): ParticleSpray {
return ParticleSpray.Burst(ctx.position, 0.5)
@ -24,17 +25,18 @@ sealed class Mishap : Throwable() {
*
* You can also mess up the stack with this.
*/
abstract fun execute(ctx: CastingContext, stack: MutableList<SpellDatum<*>>)
abstract fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>)
abstract fun errorMessage(ctx: CastingContext): Component
abstract fun errorMessage(ctx: CastingContext, errorCtx: Context): Component
protected fun dyeColor(color: DyeColor): FrozenColorizer =
FrozenColorizer(HexItems.DYE_COLORIZERS[color]!!.get(), Util.NIL_UUID)
protected fun pushGarbage(stack: MutableList<SpellDatum<*>>) {
stack.add(SpellDatum.make(Widget.GARBAGE))
}
protected fun error(stub: String, vararg args: Any): Component =
TranslatableComponent("hexcasting.mishap.$stub", *args)
protected fun actionName(action: ResourceLocation): Component =
TranslatableComponent("hexcasting.spell.$action")
data class Context(val pattern: Pattern, val action: ResourceLocation?)
}

View file

@ -0,0 +1,21 @@
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.colors.FrozenColorizer
import net.minecraft.network.chat.Component
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack
class MishapBadOffhandItem(val item: ItemStack, val wanted: Component) : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.BROWN)
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
TODO("Not yet implemented")
}
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("bad_offhand_item", actionName(errorCtx.action!!), wanted, item)
}

View file

@ -0,0 +1,42 @@
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.colors.FrozenColorizer
import net.minecraft.network.chat.Component
import net.minecraft.world.InteractionHand
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack
class MishapEntityTooFarAway(val entity: Entity) : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.PINK)
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
// Knock the player's items out of their hands
val items = listOf(
ctx.caster.mainHandItem.copy(),
ctx.caster.offhandItem.copy()
)
for (hand in InteractionHand.values()) {
ctx.caster.setItemInHand(hand, ItemStack.EMPTY.copy())
}
val delta = entity.position().subtract(ctx.position).normalize().scale(2.0)
for (item in items) {
val entity = ItemEntity(
ctx.world,
ctx.position.x, ctx.position.y, ctx.position.z,
item,
delta.x, delta.y, delta.z
)
ctx.world.addWithUUID(entity)
}
}
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("entity_too_far", SpellDatum.make(entity).display(), actionName(errorCtx.action!!))
}

View file

@ -0,0 +1,19 @@
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.colors.FrozenColorizer
import net.minecraft.network.chat.Component
import net.minecraft.world.item.DyeColor
class MishapEvalTooDeep : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.BLUE)
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
ctx.caster.airSupply -= 290
}
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("eval_too_deep")
}

View file

@ -2,20 +2,20 @@ 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.hexmath.HexPattern
import net.minecraft.network.chat.Component
import net.minecraft.world.item.DyeColor
class MishapInvalidPattern(val pattern: HexPattern) : Mishap() {
override fun accentColor(ctx: CastingContext): FrozenColorizer =
class MishapInvalidPattern : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.YELLOW)
override fun execute(ctx: CastingContext, stack: MutableList<SpellDatum<*>>) {
pushGarbage(stack)
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
stack.add(SpellDatum.make(Widget.GARBAGE))
}
override fun errorMessage(ctx: CastingContext): Component =
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("invalid_pattern")
}

View file

@ -8,14 +8,14 @@ import net.minecraft.network.chat.Component
import net.minecraft.world.item.DyeColor
class MishapInvalidSpellDatumType(val perpetrator: Any) : Mishap() {
override fun accentColor(ctx: CastingContext): FrozenColorizer =
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.BLACK)
override fun execute(ctx: CastingContext, stack: MutableList<SpellDatum<*>>) {
val msg = this.errorMessage(ctx)
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
val msg = this.errorMessage(ctx, errorCtx)
ctx.caster.sendMessage(msg, Util.NIL_UUID)
}
override fun errorMessage(ctx: CastingContext): Component =
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("invalid_spell_datum_type", this.perpetrator.toString(), this.perpetrator.javaClass.typeName)
}

View file

@ -10,6 +10,7 @@ import net.minecraft.network.chat.TranslatableComponent
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.phys.Vec3
@ -19,21 +20,31 @@ import net.minecraft.world.phys.Vec3
*
* [MishapInvalidValue.idx] is the absolute index in the stack.
*/
class MishapInvalidValue(val perpetrator: SpellDatum<*>, val idx: Int, val expectedKey: String) : Mishap() {
override fun accentColor(ctx: CastingContext): FrozenColorizer =
class MishapInvalidValue(
val perpetrator: SpellDatum<*>,
val idx: Int,
val expectedKey: String
) : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.GRAY)
override fun execute(ctx: CastingContext, stack: MutableList<SpellDatum<*>>) {
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
stack[idx] = SpellDatum.make(Widget.GARBAGE)
}
override fun errorMessage(ctx: CastingContext): Component =
error("invalid_value", TranslatableComponent(expectedKey), perpetrator.display())
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error(
"invalid_value",
actionName(errorCtx.action!!),
idx,
TranslatableComponent(expectedKey),
perpetrator.display()
)
companion object {
@JvmStatic
fun ofClass(perpetrator: SpellDatum<*>, reverseIdx: Int, cls: Class<*>): MishapInvalidValue {
val key = "hexcasting.mishap.invalid_value.class" + when {
fun ofClass(perpetrator: SpellDatum<*>, idx: Int, cls: Class<*>): MishapInvalidValue {
val key = "hexcasting.mishap.invalid_value.class." + when {
Double::class.java.isAssignableFrom(cls) -> "double"
Vec3::class.java.isAssignableFrom(cls) -> "vector"
List::class.java.isAssignableFrom(cls) -> "list"
@ -41,13 +52,14 @@ class MishapInvalidValue(val perpetrator: SpellDatum<*>, val idx: Int, val expec
HexPattern::class.java.isAssignableFrom(cls) -> "pattern"
ItemEntity::class.java.isAssignableFrom(cls) -> "entity.item"
LivingEntity::class.java.isAssignableFrom(cls) -> "entity.living"
Player::class.java.isAssignableFrom(cls) -> "entity.player"
Villager::class.java.isAssignableFrom(cls) -> "entity.player"
LivingEntity::class.java.isAssignableFrom(cls) -> "entity.living"
Entity::class.java.isAssignableFrom(cls) -> "entity"
else -> "unknown"
}
return MishapInvalidValue(perpetrator, reverseIdx, key)
return MishapInvalidValue(perpetrator, idx, key)
}
}
}

View file

@ -0,0 +1,42 @@
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.colors.FrozenColorizer
import net.minecraft.network.chat.Component
import net.minecraft.world.InteractionHand
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack
import net.minecraft.world.phys.Vec3
class MishapLocationTooFarAway(val location: Vec3) : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.MAGENTA)
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
// Knock the player's items out of their hands
val items = listOf(
ctx.caster.mainHandItem.copy(),
ctx.caster.offhandItem.copy()
)
for (hand in InteractionHand.values()) {
ctx.caster.setItemInHand(hand, ItemStack.EMPTY.copy())
}
val delta = location.subtract(ctx.position).normalize().scale(2.0)
for (item in items) {
val entity = ItemEntity(
ctx.world,
ctx.position.x, ctx.position.y, ctx.position.z,
item,
delta.x, delta.y, delta.z
)
ctx.world.addWithUUID(entity)
}
}
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("location_too_far", SpellDatum.make(location).display(), actionName(errorCtx.action!!))
}

View file

@ -0,0 +1,21 @@
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 net.minecraft.network.chat.Component
import net.minecraft.world.item.DyeColor
class MishapNotEnoughArgs(val expected: Int, val got: Int) : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.LIGHT_GRAY)
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
for (i in expected until got)
stack.add(SpellDatum.make(Widget.GARBAGE))
}
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("not_enough_args", actionName(errorCtx.action!!), expected, got)
}

View file

@ -0,0 +1,20 @@
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.colors.FrozenColorizer
import at.petrak.hexcasting.hexmath.HexPattern
import net.minecraft.network.chat.Component
import net.minecraft.world.item.DyeColor
class MishapTooManyCloseParens(val paren: HexPattern) : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.PINK)
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
stack.add(SpellDatum.make(paren))
}
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("too_many_close_parens")
}

View file

@ -1,21 +0,0 @@
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 net.minecraft.network.chat.Component
import net.minecraft.network.chat.TranslatableComponent
import net.minecraft.world.item.DyeColor
class MishapWrongType(val perpetrator: SpellDatum<*>, val reverseIdx: Int, val expectedKey: String) : Mishap() {
override fun accentColor(ctx: CastingContext): FrozenColorizer =
dyeColor(DyeColor.GRAY)
override fun execute(ctx: CastingContext, stack: MutableList<SpellDatum<*>>) {
stack[stack.size - 1 - reverseIdx] = SpellDatum.make(Widget.GARBAGE)
}
override fun errorMessage(ctx: CastingContext): Component =
error("invalid_value", TranslatableComponent(expectedKey), perpetrator.display())
}

View file

@ -250,13 +250,23 @@
"hexcasting.mishap.invalid_pattern": "That pattern isn't associated with any action.",
"hexcasting.mishap.invalid_spell_datum_type": "Tried to use a value of invalid type as a SpellDatum: %s (class %s). This is a bug in the mod.",
"hexcasting.mishap.invalid_value": "Expected %s, but got %s",
"hexcasting.mishap.invalid_value.class.entity": "entity",
"hexcasting.mishap.invalid_value.class.number": "number",
"hexcasting.mishap.invalid_value.class.number": "number",
"hexcasting.mishap.invalid_value.class.number": "number",
"hexcasting.mishap.invalid_value.class.number": "number",
"hexcasting.mishap.invalid_value.class.number": "number",
"hexcasting.mishap.invalid_value": "%s expected %s at index %s, but got %s",
"hexcasting.mishap.invalid_value.class.double": "a number",
"hexcasting.mishap.invalid_value.class.vector": "a vector",
"hexcasting.mishap.invalid_value.class.list": "a list",
"hexcasting.mishap.invalid_value.class.widget": "an influence",
"hexcasting.mishap.invalid_value.class.pattern": "a pattern",
"hexcasting.mishap.invalid_value.class.entity.item": "an item entity",
"hexcasting.mishap.invalid_value.class.entity.player": "a player",
"hexcasting.mishap.invalid_value.class.entity.villager": "a villager",
"hexcasting.mishap.invalid_value.class.entity.living": "a living entity",
"hexcasting.mishap.invalid_value.class.entity": "an entity",
"hexcasting.mishap.not_enough_args": "%s expected %s arguments but the stack was only %s tall",
"hexcasting.mishap.too_many_close_parens": "Used Retrospection without first using Introspection",
"hexcasting.mishap.location_too_far": "%s is out of range for %s",
"hexcasting.mishap.entity_too_far": "%s is out of range for %s",
"hexcasting.mishap.eval_too_deep": "Recursively evaluated too deep",
"hexcasting.mishap.bad_offhand_item": "%s needs %s in the other hand but got %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/$",