diff --git a/src/main/java/at/petrak/hexcasting/common/casting/colors/FrozenColorizer.java b/src/main/java/at/petrak/hexcasting/common/casting/colors/FrozenColorizer.java index 032dbb25..4afaa191 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/colors/FrozenColorizer.java +++ b/src/main/java/at/petrak/hexcasting/common/casting/colors/FrozenColorizer.java @@ -27,7 +27,8 @@ public record FrozenColorizer(Item item, UUID owner) { public static final String TAG_ITEM = "item"; public static final String TAG_OWNER = "owner"; - public static final FrozenColorizer DEFAULT = new FrozenColorizer(HexItems.DYE_COLORIZERS[0].get(), Util.NIL_UUID); + public static final FrozenColorizer DEFAULT = + new FrozenColorizer(HexItems.DYE_COLORIZERS.get(DyeColor.WHITE).get(), Util.NIL_UUID); public CompoundTag serialize() { var out = new CompoundTag(); @@ -60,7 +61,7 @@ public record FrozenColorizer(Item item, UUID owner) { */ public int getColor(float time, Vec3 position) { if (this.item instanceof ItemDyeColorizer dye) { - return DyeColor.values()[dye.getDyeIdx()].getTextColor() | 0xff_000000; + return dye.getDyeColor().getTextColor() | 0xff_000000; } else if (this.item instanceof ItemPrideColorizer politics) { var colors = politics.getColors(); return morphBetweenColors(colors, new Vec3(0.1, 0.1, 0.1), time / 20 / 20, position); @@ -86,7 +87,7 @@ public record FrozenColorizer(Item item, UUID owner) { } } } - + // randomly scrungle the bits var rand = new Random(this.owner.getLeastSignificantBits() ^ this.owner.getMostSignificantBits()); var hue = rand.nextFloat(); diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt new file mode 100644 index 00000000..9372ad75 --- /dev/null +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/Mishap.kt @@ -0,0 +1,40 @@ +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.world.item.DyeColor + +sealed class Mishap : Throwable() { + /** Mishaps spray half-red, half-this-color. */ + abstract fun accentColor(ctx: CastingContext): FrozenColorizer + + open fun particleSpray(ctx: CastingContext): ParticleSpray { + return ParticleSpray.Burst(ctx.position, 0.5) + } + + /** + * Execute the actual effect, not any sfx. + * + * You can also mess up the stack with this. + */ + abstract fun execute(ctx: CastingContext, stack: MutableList>) + + abstract fun errorMessage(ctx: CastingContext): Component + + protected fun dyeColor(color: DyeColor): FrozenColorizer = + FrozenColorizer(HexItems.DYE_COLORIZERS[color]!!.get(), Util.NIL_UUID) + + protected fun pushGarbage(stack: MutableList>) { + stack.add(SpellDatum.make(Widget.GARBAGE)) + } + + protected fun error(stub: String, vararg args: Any): Component = + TranslatableComponent("hexcasting.mishap.$stub", *args) +} diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidPattern.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidPattern.kt new file mode 100644 index 00000000..df6392a7 --- /dev/null +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidPattern.kt @@ -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 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 = + dyeColor(DyeColor.YELLOW) + + + override fun execute(ctx: CastingContext, stack: MutableList>) { + pushGarbage(stack) + } + + override fun errorMessage(ctx: CastingContext): Component = + error("invalid_pattern") +} \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidSpellDatumType.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidSpellDatumType.kt new file mode 100644 index 00000000..5543ed23 --- /dev/null +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidSpellDatumType.kt @@ -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.Util +import net.minecraft.network.chat.Component +import net.minecraft.world.item.DyeColor + +class MishapInvalidSpellDatumType(val perpetrator: Any) : Mishap() { + override fun accentColor(ctx: CastingContext): FrozenColorizer = + dyeColor(DyeColor.BLACK) + + override fun execute(ctx: CastingContext, stack: MutableList>) { + val msg = this.errorMessage(ctx) + ctx.caster.sendMessage(msg, Util.NIL_UUID) + } + + override fun errorMessage(ctx: CastingContext): Component = + error("invalid_spell_datum_type", this.perpetrator.toString(), this.perpetrator.javaClass.typeName) +} \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidValue.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidValue.kt new file mode 100644 index 00000000..f4b1fc18 --- /dev/null +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapInvalidValue.kt @@ -0,0 +1,53 @@ +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.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.player.Player +import net.minecraft.world.item.DyeColor +import net.minecraft.world.phys.Vec3 + +/** + * The value failed some kind of predicate. + * + * [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 = + dyeColor(DyeColor.GRAY) + + override fun execute(ctx: CastingContext, stack: MutableList>) { + stack[idx] = SpellDatum.make(Widget.GARBAGE) + } + + override fun errorMessage(ctx: CastingContext): Component = + error("invalid_value", TranslatableComponent(expectedKey), perpetrator.display()) + + companion object { + @JvmStatic + fun ofClass(perpetrator: SpellDatum<*>, reverseIdx: 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" + Widget::class.java.isAssignableFrom(cls) -> "widget" + 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" + Entity::class.java.isAssignableFrom(cls) -> "entity" + + else -> "unknown" + } + return MishapInvalidValue(perpetrator, reverseIdx, key) + } + } +} \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapWrongType.kt b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapWrongType.kt new file mode 100644 index 00000000..bb53148b --- /dev/null +++ b/src/main/java/at/petrak/hexcasting/common/casting/mishaps/MishapWrongType.kt @@ -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.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>) { + stack[stack.size - 1 - reverseIdx] = SpellDatum.make(Widget.GARBAGE) + } + + override fun errorMessage(ctx: CastingContext): Component = + error("invalid_value", TranslatableComponent(expectedKey), perpetrator.display()) +} \ No newline at end of file diff --git a/src/main/java/at/petrak/hexcasting/common/items/HexItems.java b/src/main/java/at/petrak/hexcasting/common/items/HexItems.java index 5fa81186..c3389fbf 100644 --- a/src/main/java/at/petrak/hexcasting/common/items/HexItems.java +++ b/src/main/java/at/petrak/hexcasting/common/items/HexItems.java @@ -18,6 +18,8 @@ import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegistryObject; +import java.util.EnumMap; + public class HexItems { public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, HexMod.MOD_ID); public static final CreativeModeTab TAB = new CreativeModeTab(HexMod.MOD_ID) { @@ -77,15 +79,14 @@ public class HexItems { public static final RegistryObject BATTERY = ITEMS.register("battery", () -> new ItemManaBattery(new Item.Properties().stacksTo(1))); - public static final RegistryObject[] DYE_COLORIZERS = new RegistryObject[16]; + public static final EnumMap> DYE_COLORIZERS = new EnumMap<>( + DyeColor.class); public static final RegistryObject[] PRIDE_COLORIZERS = new RegistryObject[14]; static { - for (int i = 0; i < DYE_COLORIZERS.length; i++) { - var dye = DyeColor.values()[i]; - final var finalI = i; - DYE_COLORIZERS[i] = ITEMS.register("dye_colorizer_" + dye.getName(), - () -> new ItemDyeColorizer(finalI, unstackable())); + for (var dye : DyeColor.values()) { + DYE_COLORIZERS.put(dye, ITEMS.register("dye_colorizer_" + dye.getName(), + () -> new ItemDyeColorizer(dye, unstackable()))); } for (int i = 0; i < PRIDE_COLORIZERS.length; i++) { final var finalI = i; diff --git a/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemDyeColorizer.java b/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemDyeColorizer.java index d6ca6fbf..d27d99b3 100644 --- a/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemDyeColorizer.java +++ b/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemDyeColorizer.java @@ -1,16 +1,17 @@ package at.petrak.hexcasting.common.items.colorizer; +import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.Item; public class ItemDyeColorizer extends Item { - private final int dyeIdx; + private final DyeColor dyeColor; - public ItemDyeColorizer(int dyeIdx, Properties pProperties) { + public ItemDyeColorizer(DyeColor dyeColor, Properties pProperties) { super(pProperties); - this.dyeIdx = dyeIdx; + this.dyeColor = dyeColor; } - public int getDyeIdx() { - return dyeIdx; + public DyeColor getDyeColor() { + return dyeColor; } } diff --git a/src/main/resources/assets/hexcasting/lang/en_us.json b/src/main/resources/assets/hexcasting/lang/en_us.json index a9daa08a..343871f7 100644 --- a/src/main/resources/assets/hexcasting/lang/en_us.json +++ b/src/main/resources/assets/hexcasting/lang/en_us.json @@ -248,6 +248,16 @@ "hexcasting.spell.hexcasting:const/vec/nz": "Vector Reflection -Z", "hexcasting.spell.hexcasting:const/vec/0": "Vector Reflection Zero", + "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.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/$",