alright alwinfy do your worst
This commit is contained in:
commit
26853c6e30
33 changed files with 259 additions and 136 deletions
|
@ -114,7 +114,7 @@ object HexMod {
|
|||
|
||||
@SubscribeEvent
|
||||
fun printPatternCount(evt: FMLLoadCompleteEvent) {
|
||||
HexMod.getLogger().info(
|
||||
getLogger().info(
|
||||
PatternRegistry.getPatternCountInfo()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package at.petrak.hexcasting.api.misc;
|
||||
|
||||
import at.petrak.hexcasting.api.cap.Colorizer;
|
||||
import at.petrak.hexcasting.api.mod.HexApiItems;
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities;
|
||||
import at.petrak.hexcasting.api.mod.HexApiItems;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -38,7 +41,12 @@ public record FrozenColorizer(ItemStack item, UUID owner) {
|
|||
if (tag.isEmpty())
|
||||
return FrozenColorizer.DEFAULT.get();
|
||||
try {
|
||||
var item = ItemStack.of(tag.getCompound(TAG_STACK));
|
||||
ItemStack item;
|
||||
if (tag.contains("item", Tag.TAG_STRING) && !tag.contains(TAG_STACK, Tag.TAG_COMPOUND)) {
|
||||
item = new ItemStack(ForgeRegistries.ITEMS.getValue(new ResourceLocation(tag.getString("item"))));
|
||||
} else {
|
||||
item = ItemStack.of(tag.getCompound(TAG_STACK));
|
||||
}
|
||||
var uuid = tag.getUUID(TAG_OWNER);
|
||||
return new FrozenColorizer(item, uuid);
|
||||
} catch (NullPointerException exn) {
|
||||
|
|
|
@ -362,12 +362,10 @@ class CastingHarness private constructor(
|
|||
@JvmStatic
|
||||
fun DeserializeFromNBT(nbt: Tag, ctx: CastingContext): CastingHarness {
|
||||
return try {
|
||||
val nbt = nbt as CompoundTag
|
||||
|
||||
val stack = mutableListOf<SpellDatum<*>>()
|
||||
val stackTag = nbt.getList(TAG_STACK, Tag.TAG_COMPOUND.toInt())
|
||||
val stackTag = (nbt as CompoundTag).getList(TAG_STACK, Tag.TAG_COMPOUND.toInt())
|
||||
for (subtag in stackTag) {
|
||||
val datum = SpellDatum.DeserializeFromNBT(subtag as CompoundTag, ctx)
|
||||
val datum = SpellDatum.DeserializeFromNBT(subtag as CompoundTag, ctx.world)
|
||||
stack.add(datum)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package at.petrak.hexcasting.api.spell.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.spell.ParticleSpray
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.utils.HexDamageSources
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.entity.npc.Villager
|
||||
|
@ -11,7 +11,7 @@ import net.minecraft.world.item.DyeColor
|
|||
|
||||
class MishapAlreadyBrainswept(val villager: Villager) : Mishap() {
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.LIME)
|
||||
dyeColor(DyeColor.GREEN)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
|
||||
villager.hurt(HexDamageSources.OVERCAST, villager.health)
|
||||
|
|
|
@ -13,7 +13,7 @@ import net.minecraft.world.phys.Vec3
|
|||
|
||||
class MishapBadBrainsweep(val villager: Villager, val pos: BlockPos) : Mishap() {
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.LIME)
|
||||
dyeColor(DyeColor.GREEN)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
|
||||
villager.hurt(HexDamageSources.OVERCAST, villager.health)
|
||||
|
|
|
@ -1,30 +1,31 @@
|
|||
package at.petrak.hexcasting.api.spell.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
class MishapBadItem(val item: ItemStack, val wanted: Component) : Mishap() {
|
||||
class MishapBadItem(val item: ItemEntity, 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<*>>) {
|
||||
// not really sure what to do here?
|
||||
item.deltaMovement = item.deltaMovement.add((Math.random() - 0.5) * 0.05, 1.0, (Math.random() - 0.5) * 0.05)
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component {
|
||||
if (item.isEmpty)
|
||||
return if (item.item.isEmpty)
|
||||
error("no_item", actionName(errorCtx.action), wanted)
|
||||
return error("bad_item", actionName(errorCtx.action), wanted, item)
|
||||
else
|
||||
error("bad_item", actionName(errorCtx.action), wanted, item.item)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun of(item: ItemStack, stub: String): MishapBadItem {
|
||||
fun of(item: ItemEntity, stub: String): MishapBadItem {
|
||||
return MishapBadItem(item, TranslatableComponent("hexcasting.mishap.bad_item.$stub"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.api.spell.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.item.CasterItem
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
|
@ -15,12 +16,12 @@ class MishapEntityTooFarAway(val entity: Entity) : Mishap() {
|
|||
|
||||
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()
|
||||
)
|
||||
val items = mutableListOf<ItemStack>()
|
||||
for (hand in InteractionHand.values()) {
|
||||
ctx.caster.setItemInHand(hand, ItemStack.EMPTY.copy())
|
||||
if (hand != ctx.castingHand || ctx.caster.getItemInHand(hand).item !is CasterItem) {
|
||||
items.add(ctx.caster.getItemInHand(hand).copy())
|
||||
ctx.caster.setItemInHand(hand, ItemStack.EMPTY)
|
||||
}
|
||||
}
|
||||
|
||||
val delta = entity.position().subtract(ctx.position).normalize().scale(0.5)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.api.spell.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.item.CasterItem
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
|
@ -15,12 +16,12 @@ class MishapLocationTooFarAway(val location: Vec3) : Mishap() {
|
|||
|
||||
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()
|
||||
)
|
||||
val items = mutableListOf<ItemStack>()
|
||||
for (hand in InteractionHand.values()) {
|
||||
ctx.caster.setItemInHand(hand, ItemStack.EMPTY.copy())
|
||||
if (hand != ctx.castingHand || ctx.caster.getItemInHand(hand).item !is CasterItem) {
|
||||
items.add(ctx.caster.getItemInHand(hand).copy())
|
||||
ctx.caster.setItemInHand(hand, ItemStack.EMPTY)
|
||||
}
|
||||
}
|
||||
|
||||
val delta = location.subtract(ctx.position).normalize().scale(0.5)
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package at.petrak.hexcasting.api.spell.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
||||
class MishapNoSpellCircle : Mishap() {
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.PURPLE)
|
||||
dyeColor(DyeColor.LIGHT_BLUE)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
|
||||
ctx.caster.inventory.dropAll()
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package at.petrak.hexcasting.api.spell.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.effect.MobEffectInstance
|
||||
import net.minecraft.world.effect.MobEffects
|
||||
|
@ -11,7 +11,7 @@ import net.minecraft.world.item.DyeColor
|
|||
|
||||
class MishapOthersName(val other: Player) : Mishap() {
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.ORANGE)
|
||||
dyeColor(DyeColor.BLACK)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
|
||||
val effect = MobEffectInstance(MobEffects.BLINDNESS, 20 * 60)
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package at.petrak.hexcasting.api.spell.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
||||
class MishapTooManyCloseParens : Mishap() {
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.PINK)
|
||||
dyeColor(DyeColor.ORANGE)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
|
||||
stack.add(SpellDatum.make(errorCtx.pattern))
|
||||
|
|
|
@ -71,7 +71,6 @@ object RenderLib {
|
|||
|
||||
val n = points.size
|
||||
for ((i, pair) in points.zipWithNext().withIndex()) {
|
||||
val i = i.toFloat()
|
||||
val (p1, p2) = pair
|
||||
// https://github.com/not-fl3/macroquad/blob/master/src/shapes.rs#L163
|
||||
// GuiComponent::innerFill line 52
|
||||
|
@ -89,8 +88,8 @@ object RenderLib {
|
|||
fun color(time: Float): BlockPos =
|
||||
BlockPos(Mth.lerp(time, r1, r2).toInt(), Mth.lerp(time, g1, g2).toInt(), Mth.lerp(time, b1, b2).toInt())
|
||||
|
||||
val color1 = color(i / n)
|
||||
val color2 = color((i + 1) / n)
|
||||
val color1 = color(i.toFloat() / n)
|
||||
val color2 = color((i + 1f) / n)
|
||||
buf.vertex(mat, p1.x + tx, p1.y + ty, z).color(color1.x, color1.y, color1.z, a).endVertex()
|
||||
buf.vertex(mat, p1.x - tx, p1.y - ty, z).color(color1.x, color1.y, color1.z, a).endVertex()
|
||||
buf.vertex(mat, p2.x + tx, p2.y + ty, z).color(color2.x, color2.y, color2.z, a).endVertex()
|
||||
|
|
|
@ -128,9 +128,9 @@ public class RegisterPatterns {
|
|||
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("qq", HexDir.SOUTH_WEST), prefix("less_eq"),
|
||||
new OpCompare((a, b) -> a <= b));
|
||||
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("ad", HexDir.EAST), prefix("equals"),
|
||||
new OpCompare((a, b) -> Math.abs(a - b) < 0.0001));
|
||||
new OpEquality(false));
|
||||
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("da", HexDir.EAST), prefix("not_equals"),
|
||||
new OpCompare((a, b) -> Math.abs(a - b) >= 0.0001));
|
||||
new OpEquality(true));
|
||||
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("dw", HexDir.NORTH_WEST), prefix("not"),
|
||||
OpNot.INSTANCE);
|
||||
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("aw", HexDir.NORTH_EAST), prefix("identity"),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package at.petrak.hexcasting.common.casting.operators
|
||||
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
|
||||
|
@ -19,14 +19,14 @@ object OpTheCoolerRead : ConstManaOperator {
|
|||
val stack = target.item
|
||||
val datumHolder = stack.getCapability(HexCapabilities.DATUM).resolve()
|
||||
if (!datumHolder.isPresent)
|
||||
throw MishapBadItem.of(stack, "iota.read")
|
||||
throw MishapBadItem.of(target, "iota.read")
|
||||
|
||||
ctx.assertEntityInRange(target)
|
||||
|
||||
|
||||
val datum = datumHolder.get().readDatum(ctx.world)
|
||||
?: datumHolder.get().emptyDatum()
|
||||
?: throw MishapBadItem.of(stack, "iota.read")
|
||||
?: throw MishapBadItem.of(target, "iota.read")
|
||||
return listOf(datum)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.logic
|
||||
|
||||
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.api.spell.casting.CastingContext
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import kotlin.math.abs
|
||||
|
||||
class OpEquality(val invert: Boolean) : ConstManaOperator {
|
||||
override val argc = 2
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val lhs = args[0]
|
||||
val rhs = args[1]
|
||||
|
||||
return spellListOf(if (checkEquals(lhs.payload, rhs.payload) != invert) 1.0 else 0.0)
|
||||
}
|
||||
|
||||
private fun checkEquals(a: Any, b: Any, recursionsLeft: Int = 64): Boolean {
|
||||
return when {
|
||||
a is Double && b is Double -> abs(a - b) < 0.0001
|
||||
a is Vec3 && b is Vec3 -> a.subtract(b).lengthSqr() < 0.0000001
|
||||
a is List<*> && b is List<*> -> {
|
||||
if (a.size != b.size || recursionsLeft == 0)
|
||||
return false
|
||||
for (i in a.indices)
|
||||
if (!checkEquals((a[i] as SpellDatum<*>).payload, (b[i] as SpellDatum<*>).payload, recursionsLeft - 1))
|
||||
return false
|
||||
true
|
||||
}
|
||||
else -> a == b
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
|||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.Widget
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
object OpIdentityKindOf : ConstManaOperator {
|
||||
override val argc = 1
|
||||
|
@ -13,7 +14,7 @@ object OpIdentityKindOf : ConstManaOperator {
|
|||
return spellListOf(
|
||||
when (args[0].payload) {
|
||||
Widget.NULL -> 0.0
|
||||
0.0 -> Widget.NULL
|
||||
0.0, Vec3.ZERO -> Widget.NULL
|
||||
else -> args[0].payload
|
||||
}
|
||||
)
|
||||
|
|
|
@ -5,12 +5,13 @@ import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
|||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.Widget
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
object OpNot : ConstManaOperator {
|
||||
override val argc = 1
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val falsy = args[0].payload == Widget.NULL || args[0].payload == 0.0
|
||||
val falsy = args[0].payload == Widget.NULL || args[0].payload == 0.0 || args[0].payload == Vec3.ZERO
|
||||
return spellListOf(if (falsy) 1.0 else 0.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,8 @@ import at.petrak.hexcasting.api.spell.RenderedSpell
|
|||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellOperator
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.network.HexMessages
|
||||
import at.petrak.hexcasting.common.network.MsgAddMotionAck
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
|
||||
object OpAddMotion : SpellOperator {
|
||||
override val argc: Int
|
||||
|
@ -27,6 +23,7 @@ object OpAddMotion : SpellOperator {
|
|||
var motionForCost = motion.lengthSqr()
|
||||
if (ctx.hasBeenGivenMotion(target))
|
||||
motionForCost++
|
||||
ctx.markEntityAsMotionAdded(target)
|
||||
return Triple(
|
||||
Spell(target, motion),
|
||||
(motionForCost * 10_000f).toInt(),
|
||||
|
@ -43,13 +40,7 @@ object OpAddMotion : SpellOperator {
|
|||
|
||||
private data class Spell(val target: Entity, val motion: Vec3) : RenderedSpell {
|
||||
override fun cast(ctx: CastingContext) {
|
||||
if (target is ServerPlayer) {
|
||||
// Player movement is apparently handled on the client; who knew
|
||||
// There's apparently some magic flag I can set to auto-sync it but I can't find it
|
||||
HexMessages.getNetwork().send(PacketDistributor.PLAYER.with { target }, MsgAddMotionAck(motion))
|
||||
}
|
||||
target.deltaMovement = target.deltaMovement.add(motion)
|
||||
ctx.markEntityAsMotionAdded(target)
|
||||
target.push(motion.x, motion.y, motion.z)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ class OpConjure(val light: Boolean) : SpellOperator {
|
|||
val block = if (this.light) HexBlocks.CONJURED_LIGHT else HexBlocks.CONJURED_BLOCK
|
||||
val state = block.get().getStateForPlacement(placeContext)
|
||||
if (state != null) {
|
||||
ctx.world.setBlock(pos, state, 2)
|
||||
ctx.world.setBlock(pos, state, 5)
|
||||
|
||||
val colorizer = HexPlayerDataHelper.getColorizer(ctx.caster)
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ import at.petrak.hexcasting.api.spell.RenderedSpell
|
|||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellOperator
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import at.petrak.hexcasting.common.items.HexItems
|
||||
import at.petrak.hexcasting.common.items.magic.ItemManaHolder
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
|
@ -42,9 +42,14 @@ object OpMakeBattery : SpellOperator {
|
|||
|
||||
ctx.assertEntityInRange(entity)
|
||||
|
||||
if (!ManaHelper.isManaItem(entity.item) || ManaHelper.extractMana(entity.item, drainForBatteries = true, simulate = true) <= 0) {
|
||||
throw MishapBadItem.of(
|
||||
if (!ManaHelper.isManaItem(entity.item) || ManaHelper.extractMana(
|
||||
entity.item,
|
||||
drainForBatteries = true,
|
||||
simulate = true
|
||||
) <= 0
|
||||
) {
|
||||
throw MishapBadItem.of(
|
||||
entity,
|
||||
"mana"
|
||||
)
|
||||
}
|
||||
|
@ -59,7 +64,10 @@ object OpMakeBattery : SpellOperator {
|
|||
val entityStack = itemEntity.item.copy()
|
||||
val manaAmt = ManaHelper.extractMana(entityStack, drainForBatteries = true)
|
||||
if (manaAmt > 0) {
|
||||
ctx.caster.setItemInHand(hand, ItemManaHolder.withMana(ItemStack(HexItems.BATTERY.get()), manaAmt, manaAmt))
|
||||
ctx.caster.setItemInHand(
|
||||
hand,
|
||||
ItemManaHolder.withMana(ItemStack(HexItems.BATTERY.get()), manaAmt, manaAmt)
|
||||
)
|
||||
}
|
||||
|
||||
itemEntity.item = entityStack
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.ParticleSpray
|
||||
import at.petrak.hexcasting.api.spell.RenderedSpell
|
||||
|
@ -7,11 +8,10 @@ import at.petrak.hexcasting.api.spell.SpellDatum
|
|||
import at.petrak.hexcasting.api.spell.SpellOperator
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidIota
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
|
@ -36,9 +36,14 @@ class OpMakePackagedSpell<T : ItemPackagedSpell>(val itemType: T, val cost: Int)
|
|||
}
|
||||
|
||||
ctx.assertEntityInRange(entity)
|
||||
if (!ManaHelper.isManaItem(entity.item) || ManaHelper.extractMana(entity.item, drainForBatteries = true, simulate = true) <= 0) {
|
||||
throw MishapBadItem.of(
|
||||
if (!ManaHelper.isManaItem(entity.item) || ManaHelper.extractMana(
|
||||
entity.item,
|
||||
drainForBatteries = true,
|
||||
simulate = true
|
||||
) <= 0
|
||||
) {
|
||||
throw MishapBadItem.of(
|
||||
entity,
|
||||
"mana"
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.spells
|
||||
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.ParticleSpray
|
||||
import at.petrak.hexcasting.api.spell.RenderedSpell
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellOperator
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
|
||||
object OpRecharge : SpellOperator {
|
||||
|
@ -37,7 +37,7 @@ object OpRecharge : SpellOperator {
|
|||
|
||||
if (!ManaHelper.isManaItem(entity.item)) {
|
||||
throw MishapBadItem.of(
|
||||
entity.item,
|
||||
entity,
|
||||
"mana"
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,13 +8,10 @@ import at.petrak.hexcasting.api.spell.SpellDatum
|
|||
import at.petrak.hexcasting.api.spell.SpellOperator
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.player.HexPlayerDataHelper
|
||||
import at.petrak.hexcasting.common.network.HexMessages
|
||||
import at.petrak.hexcasting.common.network.MsgAddMotionAck
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.minecraftforge.event.entity.living.LivingEvent
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
|
@ -60,8 +57,7 @@ object OpFlight : SpellOperator {
|
|||
target.abilities.flying = true
|
||||
target.onUpdateAbilities()
|
||||
// Launch the player into the air to really emphasize the flight
|
||||
HexMessages.getNetwork()
|
||||
.send(PacketDistributor.PLAYER.with { target }, MsgAddMotionAck(Vec3(0.0, 1.0, 0.0)))
|
||||
target.push(0.0, 1.0, 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ public class ItemSlate extends BlockItem implements DataHolderItem {
|
|||
var tag = stack.getTag();
|
||||
if (tag != null && tag.contains("BlockEntityTag", Tag.TAG_COMPOUND)) {
|
||||
var bet = tag.getCompound("BlockEntityTag");
|
||||
return bet.contains(BlockEntitySlate.TAG_PATTERN, Tag.TAG_COMPOUND);
|
||||
return bet.contains(BlockEntitySlate.TAG_PATTERN, Tag.TAG_COMPOUND) && !bet.getCompound(BlockEntitySlate.TAG_PATTERN).isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ public class ItemSlate extends BlockItem implements DataHolderItem {
|
|||
}
|
||||
|
||||
var patTag = beTag.getCompound(BlockEntitySlate.TAG_PATTERN);
|
||||
if (patTag.isEmpty())
|
||||
return null;
|
||||
var out = new CompoundTag();
|
||||
out.put(SpellDatum.TAG_PATTERN, patTag);
|
||||
return out;
|
||||
|
@ -61,17 +63,12 @@ public class ItemSlate extends BlockItem implements DataHolderItem {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!stack.hasTag())
|
||||
return true;
|
||||
|
||||
var beTag = stack.getTagElement("BlockEntityTag");
|
||||
return beTag == null || !beTag.contains(BlockEntitySlate.TAG_PATTERN, Tag.TAG_COMPOUND);
|
||||
return readDatumTag(stack) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDatum(ItemStack stack, SpellDatum<?> datum) {
|
||||
if (this.canWrite(stack, datum) && datum.getPayload() instanceof HexPattern pat) {
|
||||
CompoundTag tag = stack.getOrCreateTag();
|
||||
var beTag = stack.getOrCreateTagElement("BlockEntityTag");
|
||||
beTag.put(BlockEntitySlate.TAG_PATTERN, pat.serializeToNBT());
|
||||
}
|
||||
|
|
|
@ -28,8 +28,6 @@ public class HexMessages {
|
|||
MsgNewSpellPatternAck::deserialize, MsgNewSpellPatternAck::handle);
|
||||
NETWORK.registerMessage(messageIdx++, MsgShiftScrollSyn.class, MsgShiftScrollSyn::serialize,
|
||||
MsgShiftScrollSyn::deserialize, MsgShiftScrollSyn::handle);
|
||||
NETWORK.registerMessage(messageIdx++, MsgAddMotionAck.class, MsgAddMotionAck::serialize,
|
||||
MsgAddMotionAck::deserialize, MsgAddMotionAck::handle);
|
||||
NETWORK.registerMessage(messageIdx++, MsgBlinkAck.class, MsgBlinkAck::serialize,
|
||||
MsgBlinkAck::deserialize, MsgBlinkAck::handle);
|
||||
NETWORK.registerMessage(messageIdx++, MsgSentinelStatusUpdateAck.class, MsgSentinelStatusUpdateAck::serialize,
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
package at.petrak.hexcasting.common.network;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Sent server->client to synchronize OpAddMotion when the target is a player.
|
||||
*/
|
||||
public record MsgAddMotionAck(Vec3 addedMotion) {
|
||||
public static MsgAddMotionAck deserialize(ByteBuf buffer) {
|
||||
var buf = new FriendlyByteBuf(buffer);
|
||||
var x = buf.readDouble();
|
||||
var y = buf.readDouble();
|
||||
var z = buf.readDouble();
|
||||
return new MsgAddMotionAck(new Vec3(x, y, z));
|
||||
}
|
||||
|
||||
public void serialize(ByteBuf buffer) {
|
||||
var buf = new FriendlyByteBuf(buffer);
|
||||
buf.writeDouble(this.addedMotion.x);
|
||||
buf.writeDouble(this.addedMotion.y);
|
||||
buf.writeDouble(this.addedMotion.z);
|
||||
}
|
||||
|
||||
public void handle(Supplier<NetworkEvent.Context> ctx) {
|
||||
ctx.get().enqueueWork(() ->
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
|
||||
var player = Minecraft.getInstance().player;
|
||||
var motion = player.getDeltaMovement();
|
||||
player.setDeltaMovement(motion.add(this.addedMotion));
|
||||
})
|
||||
);
|
||||
ctx.get().setPacketHandled(true);
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ version = "${file.jarVersion}"
|
|||
displayName = "Hexcasting"
|
||||
displayURL = "https://github.com/gamma-delta/HexMod"
|
||||
logoFile = "logo.png"
|
||||
credits = "Alwinfy for visual effects, proofreading, and code help; Kra3tor for sound effects; Falkory for textures; and all of Vazcord for alpha-testing and supporting me!"
|
||||
credits = "Falkory for textures; Wiresegal for lots of polish; Alwinfy for visual effects, proofreading, and code help; Kra3tor for sound effects; naj77 for the nice logo; and all of my wonderful patrons for supporting me!"
|
||||
authors = "petrak@ (aka gamma-delta)"
|
||||
description = "Cast powerful Hexes on the fly by drawing patterns with a staff."
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@
|
|||
"hexcasting.spell.hexcasting:undo": "Novice's Gambit",
|
||||
"hexcasting.spell.hexcasting:const/null": "Nullary Reflection",
|
||||
"hexcasting.spell.hexcasting:duplicate": "Gemini Decomposition",
|
||||
"hexcasting.spell.hexcasting:duplicate_n": "Gemini Gambit",
|
||||
"hexcasting.spell.hexcasting:duplicate_n": "Gemini's Gambit",
|
||||
"hexcasting.spell.hexcasting:swap": "Jester's Gambit",
|
||||
"hexcasting.spell.hexcasting:fisherman": "Fisherman's Gambit",
|
||||
"hexcasting.spell.hexcasting:swizzle": "Swindler's Gambit",
|
||||
|
@ -418,8 +418,8 @@
|
|||
|
||||
"hexcasting.entry.101": "Hexing 101",
|
||||
"hexcasting.page.101.1": "Casting a _Hex is quite difficult-- no wonder this art was lost to time! I'll have to re-read my notes carefully.$(br2)I can start a _Hex by pressing $(k:use) with a $(item)Staff/$ in my hand-- this will cause a hexagonal grid of dots to appear in front of me. Then I can click and drag from dot to dot to draw patterns in the _media of the grid; finishing a pattern will run its corresponding action (more on that later).",
|
||||
"hexcasting.page.101.2": "Once my stack is empty once again (usually by casting a spell), the grid will disappear as the _media I've stored up is released. I can also press Escape if I want to quit early.$(br2)So how do patterns work? In short:$(li)$(italic)Patterns/$ will execute...$(li)$(italic)Actions/$, which manipulate...$(li)$(italic)The Stack/$, which is a list of...$(li)$(italic)Iotas/$, which are simply units of information.",
|
||||
"hexcasting.page.101.3": "First, $(thing)patterns/$. These are essential-- they're what I use to manipulate the _media around me. Certain patterns, when drawn, will cause $(thing)actions/$ to happen. Actions are what actually $(italic)do/$ the magic; all patterns influence _media in particular ways, and when those influences end up doing something useful, we call it an action.$(br2)_Media can be fickle: if I draw an invalid pattern, I'll get some garbage result on my stack (read on...)",
|
||||
"hexcasting.page.101.2": "Once I've drawn enough patterns to cast a spell, the grid will disappear as the _media I've stored up is released. Holding $(k:sneak) while using my staff will also clear the grid, if I don't mind the chance of mishap. (It seems that the more _media I've built up, the more likely I'll meet misfortune.)$(br2)So how do patterns work? In short:$(li)$(italic)Patterns/$ will execute...$(li)$(italic)Actions/$, which manipulate...$(li)$(italic)The Stack/$, which is a list of...$(li)$(italic)Iotas/$, which are simply units of information.",
|
||||
"hexcasting.page.101.3": "First, $(thing)patterns/$. These are essential-- they're what I use to manipulate the _media around me. Certain patterns, when drawn, will cause $(thing)actions/$ to happen. Actions are what actually $(italic)do/$ the magic; all patterns influence _media in particular ways, and when those influences end up doing something useful, we call it an action.$(br2)_Media can be fickle: if I draw an invalid pattern, I'll get some garbage result somewhere on my stack (read on...)",
|
||||
"hexcasting.page.101.4.header": "An Example",
|
||||
"hexcasting.page.101.4": "It's interesting to note that the $(italic)rotation/$ of a pattern doesn't seem to matter at all. These two patterns both perform an action called $(l:patterns/basics#hexcasting:get_caster)$(action)Mind's Reflection/$, for example.",
|
||||
"hexcasting.page.101.5": "A _Hex is cast by drawing (valid) actions in sequence. Each action might do one of a few things:$(li)Gather some information about the environment, leaving it on the top of the stack;$(li)manipulate the info gathered (e.g. adding two numbers); or$(li)perform some magical effect, like summoning lightning or an explosion. (These actions are called \"spells.\")$(p)When I start casting a _Hex, it creates an empty stack. Actions manipulate the top of that stack.",
|
||||
|
@ -430,7 +430,7 @@
|
|||
"hexcasting.page.101.10": "That aside, it doesn't seem like anyone has done much research on exactly how $(italic)much/$ any particular piece of amethyst is valued. The best I can tell, an $(item)Amethyst Shard/$ is worth about five pieces of $(item)Amethyst Dust/$, and a $(item)Charged Amethyst Crystal/$ is worth about ten.$(br2)Strangely enough, it seems like no other form of amethyst is suitable to be used in the casting of a _Hex. I suspect that whole blocks or crystals are too solid to be easily unraveled into _media.",
|
||||
"hexcasting.page.101.11": "It's also worth noting that each action will consume the _media it needs immediately, rather than all at once when the Hex finishes. Also, an action will always consume entire items-- an action that only requires one $(item)Amethyst Dust/$'s worth of _media will consume an entire $(item)Charged Amethyst Crystal/$, if that's all that's present in my inventory.$(br2)Thus, it might be a good idea to bring dust for spellcasting too-- waste not, want not...",
|
||||
"hexcasting.page.101.12": "I should also be careful to make sure I actually have enough Amethyst in my inventory-- some old texts say that Nature is happy to use one's own mind as payment instead. They describe the feeling as awful but strangely euphoric, \"[...] an effervescent dissolution into light and energy...\"$(br)Perhaps that's why all the old practitioners of the art went mad. I can't imagine burning pieces of my mind for power is $(italic)healthy/$.",
|
||||
"hexcasting.page.101.13": "Maybe something's changed, though. In my experiments, I've never managed to do it; if I run out of _media, the spell will simply fail to cast, as if some barrier is blocking it from harming me. $(br2)It would be interesting to get to the bottom of the mystery, but for now I suppose it'll keep me safe.",
|
||||
"hexcasting.page.101.13": "Maybe something's changed, though. In my experiments, I've never managed to do it; if I run out of _media, the spell will simply fail to cast, as if some barrier is blocking it from harming me. $(br2)It would be interesting to get to the bottom of that mystery, but for now I suppose it'll keep me safe.",
|
||||
"hexcasting.page.101.14": "I have also found an amusing tidbit on why so many practitioners of magic in general seem to go mad, which I may like as some light and flavorful reading not canonical to my world.$(br2)$(italic)Content Warning: some body horror and suggestive elements./$",
|
||||
"hexcasting.page.101.14.link_text": "Goblin Punch",
|
||||
"hexcasting.page.101.15": "Finally, it seems spells have a maximum range of influence, about 32 blocks from my position. Trying to affect anything outside of that will cause the spell to fail.",
|
||||
|
@ -444,8 +444,32 @@
|
|||
|
||||
"hexcasting.entry.mishaps": "Mishaps",
|
||||
"hexcasting.page.mishaps.1": "Unfortunately, I am not (yet) a perfect being. I make mistakes from time to time in my study and casting of _Hexes; for example, misdrawing a pattern, or trying to an invoke an action with the wrong iotas. And Nature usually doesn't look too kindly on my mistakes-- causing what is called a $(italic)mishap/$.",
|
||||
"hexcasting.page.mishaps.2": "A pattern that causes a mishap will glow red in my grid. Depending on the type of mistake, I can also expect a certain deleterious effect and a spray of sparks as the mishandled _media curdles into light of a given color.$(br2)I also get a helpful error message in my chat, but a nagging feeling tells that will change once the \"mod updates,\" whatever that means. I shouldn't rely on always having it.",
|
||||
"hexcasting.page.mishaps.3": "Fortunately, although the bad effects of mishaps are certainly $(italic)annoying/$, none of them are especially destructive in the long term. Nothing better to do than dust myself off and try again ... but I should strive for perfection anyways.$(br2)Following is a list of mishaps I have compiled.",
|
||||
"hexcasting.page.mishaps.2": "A pattern that causes a mishap will glow red in my grid. Depending on the type of mistake, I can also expect a certain deleterious effect and a spray of red and colorful sparks as the mishandled _media curdles into light of a given color.$(br2)I also get a helpful error message in my chat, but a nagging feeling tells that will change once the \"mod updates,\" whatever that means. I shouldn't rely on always having it.",
|
||||
"hexcasting.page.mishaps.3": "Fortunately, although the bad effects of mishaps are certainly $(italic)annoying/$, none of them are especially destructive in the long term. Nothing better to do than dust myself off and try again ... but I should strive for better anyways.$(br2)Following is a list of mishaps I have compiled.",
|
||||
"hexcasting.page.mishaps.4.title": "Invalid Pattern",
|
||||
"hexcasting.page.mishaps.4": "The pattern drawn is not associated with any action.$(br2)Causes yellow sparks, and a $(item)Garbage/$ will be pushed to the top of my stack.",
|
||||
"hexcasting.page.mishaps.5.title": "Not Enough Iotas",
|
||||
"hexcasting.page.mishaps.5": "The action required more iotas than were on the stack.$(br2)Causes light gray sparks, and as many $(item)Garbage/$s as would be required to fill up the argument count will be pushed.",
|
||||
"hexcasting.page.mishaps.6.title": "Incorrect Iota",
|
||||
"hexcasting.page.mishaps.6": "The action that was executed expected an iota of a certain type for an argument, but it got something invalid. If multiple iotas are invalid, the error message will only tell me about the error deepest in the stack.$(br2)Causes dark gray sparks, and the invalid iota will be replaced with $(item)Garbage/$.",
|
||||
"hexcasting.page.mishaps.7.title": "Vector Out of Ambit",
|
||||
"hexcasting.page.mishaps.7": "The action tried to affect the world at a point that was out of my range.$(br2)Causes magenta sparks, and the items in my hands will be yanked out and flung towards the offending location.",
|
||||
"hexcasting.page.mishaps.8.title": "Entity Out of Ambit",
|
||||
"hexcasting.page.mishaps.8": "The action tried to affect an entity that was out of my range.$(br2)Causes pink sparks, and the items in my hands will be yanked out and flung towards the offending entity.",
|
||||
"hexcasting.page.mishaps.9.title": "Mathematical Error",
|
||||
"hexcasting.page.mishaps.9": "The action did something offensive to the laws of mathematics, such as dividing by zero.$(br2)Causes red sparks, pushes a $(item)Garbage/$ to my stack, and my mind will be ablated, stealing half the vigor I have remaining.",
|
||||
"hexcasting.page.mishaps.10.title": "Incorrect Item",
|
||||
"hexcasting.page.mishaps.10": "The action requires some sort of item, but the item I supplied was not suitable$(br2)Causes brown sparks. If the offending item was in my hand, it will be flung to the floor. If it was in entity form, it will be flung in the air.",
|
||||
"hexcasting.page.mishaps.11.title": "Incorrect Block",
|
||||
"hexcasting.page.mishaps.11": "The action requires some sort of block at a target location, but the block supplied was not suitable.$(br2)Causes bright green sparks, and causes an ephemeral explosion at the given location; it will harm me and others, but will not destroy any blocks.",
|
||||
"hexcasting.page.mishaps.12.title": "Hasty Retrospection",
|
||||
"hexcasting.page.mishaps.12": "I attempted to draw $(action)Retrospection/$ without first drawing $(action)Introspection/$.$(br2)Causes orange sparks, and pushes the pattern for $(action)Retrospection/$ to the stack as a pattern iota.",
|
||||
"hexcasting.page.mishaps.13.title": "Delve Too Deep",
|
||||
"hexcasting.page.mishaps.13": "Evaluated too many patterns from one action.$(br2)Causes dark blue sparks, and chokes all the air out of me.",
|
||||
"hexcasting.page.mishaps.14.title": "Transgress Other",
|
||||
"hexcasting.page.mishaps.14": "I attempted to save a reference to another player to a permanent medium.$(br2)Causes black sparks, and robs me of my sight for approximately one minute.",
|
||||
"hexcasting.page.mishaps.15.title": "Invalid Iota Type",
|
||||
"hexcasting.page.mishaps.15": "A bug in the mod caused an iota of an invalid type. $(l:https://https://github.com/gamma-delta/HexMod/issues)Please open a bug report!/$$(br2)Causes black sparks.",
|
||||
|
||||
"hexcasting.entry.stack": "Stacks",
|
||||
"hexcasting.page.stack.1": "A $(thing)Stack/$, also known as a \"LIFO\", is a concept borrowed from computer science. In short, it's a collection of things designed so that you can only interact with the most recently used thing.$(br2)Think of a stack of plates, where new plates are added to the top: if you want to interact with a plate halfway down the stack, you have to remove the plates above it in order to get ahold of it.",
|
||||
|
@ -461,14 +485,23 @@
|
|||
"hexcasting.entry.influences": "Influences",
|
||||
"hexcasting.page.influences.1": "Influences are ... strange, to say the least. Whereas most iotas seem to represent something about the world, influences represent something more... abstract, or formless.$(br2)For example, one influence I've named Null seems to represent nothing at all. It's created when there isn't a suitable answer to a question asked, such as an $(l:patterns/basics#hexcasting:raycast)$(action)Archer's Distillation/$ facing the sky.",
|
||||
"hexcasting.page.influences.2": "In addition, I've discovered a curious triplet of influences I've named Consideration, Introspection, and Retrospection. They seem to have properties of both patterns and other influences, yet act very differently. I can use these to add patterns to my stack as iotas, instead of matching them to actions. $(l:patterns/patterns_as_iotas)My notes on the subject are here/$.",
|
||||
"hexcasting.page.influences.3": "Finally, there seems to be an infinite family of influences that just seem to be a tangled mess of _media. I've named them $(action)Garbage/$, as they are completely useless. They seem to appear in my stack at random, like pests, when I drawn an invalid pattern. Turning my (admittedly very poor) ethereal senses towards them, I see only a nonsense jumble.",
|
||||
"hexcasting.page.influences.3": "Finally, there seems to be an infinite family of influences that just seem to be a tangled mess of _media. I've named them $(action)Garbage/$, as they are completely useless. They seem to appear in my stack at various places in response to $(l:casting/mishaps)mishaps/$. They appear to my senses as a nonsense jumble.",
|
||||
|
||||
"hexcasting.entry.mishaps2": "Enlightened Mishaps",
|
||||
"hexcasting.page.mishaps2.1": "I have discovered new and horrifying modes of failure. I must not succumb to them.",
|
||||
"hexcasting.page.mishaps2.2.title": "Inert Mindflay",
|
||||
"hexcasting.page.mishaps2.2": "Attempted to flay the mind of a villager that I have either already used, or of a character not suitable for the target block.$(br2)Causes dark green sparks, and kills the subject.",
|
||||
"hexcasting.page.mishaps2.3.title": "Lack Spell Circle",
|
||||
"hexcasting.page.mishaps2.3": "Tried to cast an action requiring a spell circle without a spell circle.$(br2)Causes light blue sparks, and upends my inventory onto the ground.",
|
||||
"hexcasting.page.mishaps2.4.title": "Lack Akashic Record",
|
||||
"hexcasting.page.mishaps2.4": "Tried to access an akashic record at a location where there isn't one.$(br2)Causes purple sparks, and steals away some of my experience.",
|
||||
|
||||
|
||||
"_comment": "Items",
|
||||
|
||||
"hexcasting.entry.amethyst": "Amethyst",
|
||||
"hexcasting.page.amethyst.1": "It seems that I'll find three different forms of amethyst when breaking a crystal inside a geode. The smallest denomination seems to be a small pile of shimmering dust, worth a relatively small amount of _media.",
|
||||
"hexcasting.page.amethyst.2": "The second is a whole shard of amethyst, of the type non-Hexers might be used to. This has about as much _media inside as five $(item)Amethyst Dust/$s.",
|
||||
"hexcasting.page.amethyst.2": "The second is a whole shard of amethyst, of the type non-_Hexcasters might be used to. This has about as much _media inside as five $(item)Amethyst Dust/$s.",
|
||||
"hexcasting.page.amethyst.3": "Finally, I'll rarely find a large crystal crackling with energy. This has about as much _media inside as ten units of $(item)Amethyst Dust/$s (or two $(item)Amethyst Shard/$s).",
|
||||
"hexcasting.page.amethyst.4": "$(italic)The old man sighed and raised a hand toward the fire. He unlocked a part of his brain that held the memories of the mountains around them. He pulled the energies from those lands, as he learned to do in Terisia City with Drafna, Hurkyl, the archimandrite, and the other mages of the Ivory Towers. He concentrated, and the flames writhed as they rose from the logs, twisting upon themselves until they finally formed a soft smile./$",
|
||||
|
||||
|
@ -745,7 +778,7 @@
|
|||
|
||||
"hexcasting.entry.akashic_patterns": "Akashic Patterns",
|
||||
"hexcasting.page.akashic_patterns.akashic/read": "Read the iota associated with the given pattern out of the akashic library with its record at the given position. This has no range limit. Costs about one $(item)Amethyst Dust/$.",
|
||||
"hexcasting.page.akashic_patterns.akashic/write": "Associate the iota with the given pattern in the akashic library with its record at the given position. Costs about one $(item)Amethyst Dust/$.",
|
||||
"hexcasting.page.akashic_patterns.akashic/write": "Associate the iota with the given pattern in the akashic library with its record at the given position. This $(italic)does/$ have a range limit. Costs about one $(item)Amethyst Dust/$.",
|
||||
|
||||
"_comment": "Normal Spells",
|
||||
|
||||
|
@ -793,7 +826,7 @@
|
|||
"hexcasting.page.hexcasting_spell.recharge.1": "Recharge a _media-containing item in my other hand. Costs about one $(item)Charged Amethyst/$.",
|
||||
"hexcasting.page.hexcasting_spell.recharge.2": "This spell is cast in a similar method to the crafting spells; an entity representing a dropped stack of $(item)Amethyst/$ is provided, and recharges the _media battery of the item in my other hand.$(br2)This spell $(italic)cannot/$ recharge the item farther than its original battery size.",
|
||||
"hexcasting.page.hexcasting_spell.erase.1": "Clear a _Hex-containing item in my other hand. Costs about one $(item)Amethyst Dust/$.",
|
||||
"hexcasting.page.hexcasting_spell.erase.2": "The spell will also void all the _media stored inside the item, releasing it back to Nature and returning the item to a perfectly clean slate. This way, I can re-use $(item)Trinket/$s I have put an erroneous spell into, for example.",
|
||||
"hexcasting.page.hexcasting_spell.erase.2": "The spell will also void all the _media stored inside the item, releasing it back to Nature and returning the item to a perfectly clean slate. This way, I can re-use $(item)Trinket/$s I have put an erroneous spell into, for example.$(br2)This also works to clear a $(item)Focus/$ or $(item)Spellbook/$.",
|
||||
|
||||
"hexcasting.entry.sentinels": "Sentinels",
|
||||
"hexcasting.page.sentinels.1": "$(italic)Hence, away! Now all is well,$(br)One aloof stand sentinel./$$(br2)A $(thing)Sentinel/$ is a mysterious force I can summon to assist in the casting of _Hexes, like a familiar or guardian spirit. It appears as a spinning geometric shape to my eyes, but is invisible to everyone else.",
|
||||
|
|
|
@ -3,6 +3,5 @@
|
|||
"description": "hexcasting.entry.greatwork.desc",
|
||||
"icon": "minecraft:music_disc_11",
|
||||
"sortnum": 3,
|
||||
"secret": true,
|
||||
"entry_color": "54398a"
|
||||
}
|
||||
|
|
|
@ -13,6 +13,70 @@
|
|||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "hexcasting.page.mishaps.2"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "hexcasting.page.mishaps.3"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.4.title",
|
||||
"text": "hexcasting.page.mishaps.4"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.5.title",
|
||||
"text": "hexcasting.page.mishaps.5"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.6.title",
|
||||
"text": "hexcasting.page.mishaps.6"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.7.title",
|
||||
"text": "hexcasting.page.mishaps.7"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.8.title",
|
||||
"text": "hexcasting.page.mishaps.8"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.9.title",
|
||||
"text": "hexcasting.page.mishaps.9"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.10.title",
|
||||
"text": "hexcasting.page.mishaps.10"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.11.title",
|
||||
"text": "hexcasting.page.mishaps.11"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.12.title",
|
||||
"text": "hexcasting.page.mishaps.12"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.13.title",
|
||||
"text": "hexcasting.page.mishaps.13"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.14.title",
|
||||
"text": "hexcasting.page.mishaps.14"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps.15.title",
|
||||
"text": "hexcasting.page.mishaps.15"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "hexcasting.entry.mishaps2",
|
||||
"category": "hexcasting:casting",
|
||||
"icon": "minecraft:flint_and_steel",
|
||||
"sortnum": 3,
|
||||
"advancement": "hexcasting:enlightenment",
|
||||
"entry_color": "54398a",
|
||||
"pages": [
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "hexcasting.page.mishaps2.1"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps2.2.title",
|
||||
"text": "hexcasting.page.mishaps2.2"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps2.3.title",
|
||||
"text": "hexcasting.page.mishaps2.3"
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"title": "hexcasting.page.mishaps2.4.title",
|
||||
"text": "hexcasting.page.mishaps2.4"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -42,7 +42,7 @@
|
|||
"type": "hexcasting:pattern",
|
||||
"op_id": "hexcasting:equals",
|
||||
"anchor": "hexcasting:equals",
|
||||
"input": "number, number",
|
||||
"input": "any, any",
|
||||
"output": "number",
|
||||
"text": "hexcasting.page.logic.equals"
|
||||
},
|
||||
|
@ -50,7 +50,7 @@
|
|||
"type": "hexcasting:pattern",
|
||||
"op_id": "hexcasting:not_equals",
|
||||
"anchor": "hexcasting:not_equals",
|
||||
"input": "number, number",
|
||||
"input": "any, any",
|
||||
"output": "number",
|
||||
"text": "hexcasting.page.logic.not_equals"
|
||||
},
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 37 KiB |
Loading…
Reference in a new issue