executing patterns as spells
:)
This commit is contained in:
parent
65b04c0372
commit
fff3cf5691
15 changed files with 172 additions and 120 deletions
|
@ -1,6 +1,7 @@
|
||||||
package at.petrak.hexcasting.api.cap;
|
package at.petrak.hexcasting.api.cap;
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
import at.petrak.hexcasting.api.spell.SpellDatum;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -9,10 +10,12 @@ public interface SpellHolder {
|
||||||
|
|
||||||
boolean canDrawManaFromInventory();
|
boolean canDrawManaFromInventory();
|
||||||
|
|
||||||
|
boolean hasSpell();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
List<HexPattern> getPatterns();
|
List<SpellDatum<?>> getPatterns(ServerLevel level);
|
||||||
|
|
||||||
void writePatterns(List<HexPattern> patterns, int mana);
|
void writePatterns(List<SpellDatum<?>> patterns, int mana);
|
||||||
|
|
||||||
void clearPatterns();
|
void clearPatterns();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.mod.HexApiSounds;
|
||||||
import at.petrak.hexcasting.api.mod.HexConfig;
|
import at.petrak.hexcasting.api.mod.HexConfig;
|
||||||
import at.petrak.hexcasting.api.player.HexPlayerDataHelper;
|
import at.petrak.hexcasting.api.player.HexPlayerDataHelper;
|
||||||
import at.petrak.hexcasting.api.spell.ParticleSpray;
|
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.spell.casting.CastingContext;
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingHarness;
|
import at.petrak.hexcasting.api.spell.casting.CastingHarness;
|
||||||
import at.petrak.hexcasting.api.spell.casting.SpellCircleContext;
|
import at.petrak.hexcasting.api.spell.casting.SpellCircleContext;
|
||||||
|
@ -310,7 +311,7 @@ public abstract class BlockEntityAbstractImpetus extends PaucalBlockEntity imple
|
||||||
if (bs.getBlock() instanceof BlockCircleComponent cc) {
|
if (bs.getBlock() instanceof BlockCircleComponent cc) {
|
||||||
var newPattern = cc.getPattern(tracked, bs, this.level);
|
var newPattern = cc.getPattern(tracked, bs, this.level);
|
||||||
if (newPattern != null) {
|
if (newPattern != null) {
|
||||||
var info = harness.executeNewPattern(newPattern, splayer.getLevel());
|
var info = harness.executeNewIota(SpellDatum.make(newPattern), splayer.getLevel());
|
||||||
if (info.getWasSpellCast()) {
|
if (info.getWasSpellCast()) {
|
||||||
castSpell = true;
|
castSpell = true;
|
||||||
if (info.getHasCastingSound()) {
|
if (info.getHasCastingSound()) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package at.petrak.hexcasting.api.item;
|
package at.petrak.hexcasting.api.item;
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
import at.petrak.hexcasting.api.spell.SpellDatum;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@ -10,10 +11,12 @@ public interface SpellHolderItem extends ManaHolderItem {
|
||||||
|
|
||||||
boolean canDrawManaFromInventory(ItemStack stack);
|
boolean canDrawManaFromInventory(ItemStack stack);
|
||||||
|
|
||||||
@Nullable
|
boolean hasSpell(ItemStack stack);
|
||||||
List<HexPattern> getPatterns(ItemStack stack);
|
|
||||||
|
|
||||||
void writePatterns(ItemStack stack, List<HexPattern> patterns, int mana);
|
@Nullable
|
||||||
|
List<SpellDatum<?>> getSpell(ItemStack stack, ServerLevel level);
|
||||||
|
|
||||||
|
void writePatterns(ItemStack stack, List<SpellDatum<?>> patterns, int mana);
|
||||||
|
|
||||||
void clearPatterns(ItemStack stack);
|
void clearPatterns(ItemStack stack);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,10 @@ import at.petrak.hexcasting.api.mod.HexConfig
|
||||||
import at.petrak.hexcasting.api.mod.HexItemTags
|
import at.petrak.hexcasting.api.mod.HexItemTags
|
||||||
import at.petrak.hexcasting.api.mod.HexStatistics
|
import at.petrak.hexcasting.api.mod.HexStatistics
|
||||||
import at.petrak.hexcasting.api.player.HexPlayerDataHelper
|
import at.petrak.hexcasting.api.player.HexPlayerDataHelper
|
||||||
import at.petrak.hexcasting.api.spell.Operator
|
import at.petrak.hexcasting.api.spell.*
|
||||||
import at.petrak.hexcasting.api.spell.ParticleSpray
|
import at.petrak.hexcasting.api.spell.math.HexDir
|
||||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
|
||||||
import at.petrak.hexcasting.api.spell.Widget
|
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.Mishap
|
import at.petrak.hexcasting.api.spell.mishaps.*
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapDisallowedSpell
|
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapError
|
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapTooManyCloseParens
|
|
||||||
import at.petrak.hexcasting.api.utils.HexDamageSources
|
import at.petrak.hexcasting.api.utils.HexDamageSources
|
||||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||||
import at.petrak.hexcasting.api.utils.asCompound
|
import at.petrak.hexcasting.api.utils.asCompound
|
||||||
|
@ -39,7 +34,7 @@ class CastingHarness private constructor(
|
||||||
var stack: MutableList<SpellDatum<*>>,
|
var stack: MutableList<SpellDatum<*>>,
|
||||||
var localIota: SpellDatum<*>,
|
var localIota: SpellDatum<*>,
|
||||||
var parenCount: Int,
|
var parenCount: Int,
|
||||||
var parenthesized: List<HexPattern>,
|
var parenthesized: List<SpellDatum<*>>,
|
||||||
var escapeNext: Boolean,
|
var escapeNext: Boolean,
|
||||||
val ctx: CastingContext,
|
val ctx: CastingContext,
|
||||||
val prepackagedColorizer: FrozenColorizer? // for trinkets with colorizers
|
val prepackagedColorizer: FrozenColorizer? // for trinkets with colorizers
|
||||||
|
@ -52,33 +47,46 @@ class CastingHarness private constructor(
|
||||||
) : this(mutableListOf(), SpellDatum.make(Widget.NULL), 0, mutableListOf(), false, ctx, prepackagedColorizer)
|
) : this(mutableListOf(), SpellDatum.make(Widget.NULL), 0, mutableListOf(), false, ctx, prepackagedColorizer)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a pattern, do all the updating/side effects/etc required.
|
* Given an iota, do all the updating/side effects/etc required.
|
||||||
*/
|
*/
|
||||||
fun executeNewPattern(newPat: HexPattern, world: ServerLevel): ControllerInfo {
|
fun executeNewIota(iota: SpellDatum<*>, world: ServerLevel): ControllerInfo {
|
||||||
val result = this.getUpdate(newPat, world)
|
val result = this.getUpdate(iota, world)
|
||||||
this.applyFunctionalData(result.newData)
|
this.applyFunctionalData(result.newData)
|
||||||
return this.performSideEffects(result.sideEffects)
|
return this.performSideEffects(result.sideEffects)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getUpdate(iota: SpellDatum<*>, world: ServerLevel): CastResult {
|
||||||
|
// wouldn't it be nice to be able to go paren'
|
||||||
|
// i guess i'll call it paren2
|
||||||
|
val paren2 = this.handleParentheses(iota)
|
||||||
|
if (paren2 != null) {
|
||||||
|
return CastResult(
|
||||||
|
paren2,
|
||||||
|
listOf()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (iota.getType() == DatumType.PATTERN) {
|
||||||
|
updateWithPattern(iota.payload as HexPattern, world)
|
||||||
|
} else {
|
||||||
|
CastResult(
|
||||||
|
this.getFunctionalData(),
|
||||||
|
listOf(OperatorSideEffect.DoMishap(MishapUnescapedValue(iota),
|
||||||
|
Mishap.Context(HexPattern(HexDir.WEST), null))),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the server gets a packet from the client with a new pattern,
|
* When the server gets a packet from the client with a new pattern,
|
||||||
* handle it functionally.
|
* handle it functionally.
|
||||||
*/
|
*/
|
||||||
fun getUpdate(newPat: HexPattern, world: ServerLevel): CastResult {
|
fun updateWithPattern(newPat: HexPattern, world: ServerLevel): CastResult {
|
||||||
if (this.ctx.spellCircle == null)
|
if (this.ctx.spellCircle == null)
|
||||||
this.ctx.caster.awardStat(HexStatistics.PATTERNS_DRAWN)
|
this.ctx.caster.awardStat(HexStatistics.PATTERNS_DRAWN)
|
||||||
|
|
||||||
var operatorIdPair: Pair<Operator, ResourceLocation>? = null
|
var operatorIdPair: Pair<Operator, ResourceLocation>? = null
|
||||||
try {
|
try {
|
||||||
// wouldn't it be nice to be able to go paren'
|
|
||||||
// i guess i'll call it paren2
|
|
||||||
val paren2 = this.handleParentheses(newPat)
|
|
||||||
if (paren2 != null) {
|
|
||||||
return CastResult(
|
|
||||||
paren2,
|
|
||||||
listOf(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't catch this one
|
// Don't catch this one
|
||||||
operatorIdPair = PatternRegistry.matchPatternAndID(newPat, world)
|
operatorIdPair = PatternRegistry.matchPatternAndID(newPat, world)
|
||||||
|
@ -186,17 +194,19 @@ class CastingHarness private constructor(
|
||||||
* Return a non-null value if we handled this in some sort of parenthesey way,
|
* Return a non-null value if we handled this in some sort of parenthesey way,
|
||||||
* either escaping it onto the stack or changing the parenthese-handling state.
|
* either escaping it onto the stack or changing the parenthese-handling state.
|
||||||
*/
|
*/
|
||||||
private fun handleParentheses(newPat: HexPattern): FunctionalData? {
|
private fun handleParentheses(iota: SpellDatum<*>): FunctionalData? {
|
||||||
val operator = try {
|
val operator = (iota.payload as? HexPattern)?.let {
|
||||||
PatternRegistry.matchPattern(newPat, this.ctx.world)
|
try {
|
||||||
} catch (mishap: Mishap) {
|
PatternRegistry.matchPattern(it, this.ctx.world)
|
||||||
null
|
} catch (mishap: Mishap) {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (this.parenCount > 0) {
|
return if (this.parenCount > 0) {
|
||||||
if (this.escapeNext) {
|
if (this.escapeNext) {
|
||||||
val newParens = this.parenthesized.toMutableList()
|
val newParens = this.parenthesized.toMutableList()
|
||||||
newParens.add(newPat)
|
newParens.add(iota)
|
||||||
this.getFunctionalData().copy(
|
this.getFunctionalData().copy(
|
||||||
escapeNext = false,
|
escapeNext = false,
|
||||||
parenthesized = newParens
|
parenthesized = newParens
|
||||||
|
@ -208,7 +218,7 @@ class CastingHarness private constructor(
|
||||||
} else if (operator == Widget.OPEN_PAREN) {
|
} else if (operator == Widget.OPEN_PAREN) {
|
||||||
// we have escaped the parens onto the stack; we just also record our count.
|
// we have escaped the parens onto the stack; we just also record our count.
|
||||||
val newParens = this.parenthesized.toMutableList()
|
val newParens = this.parenthesized.toMutableList()
|
||||||
newParens.add(newPat)
|
newParens.add(iota)
|
||||||
this.getFunctionalData().copy(
|
this.getFunctionalData().copy(
|
||||||
parenthesized = newParens,
|
parenthesized = newParens,
|
||||||
parenCount = this.parenCount + 1
|
parenCount = this.parenCount + 1
|
||||||
|
@ -217,7 +227,7 @@ class CastingHarness private constructor(
|
||||||
val newParenCount = this.parenCount - 1
|
val newParenCount = this.parenCount - 1
|
||||||
if (newParenCount == 0) {
|
if (newParenCount == 0) {
|
||||||
val newStack = this.stack.toMutableList()
|
val newStack = this.stack.toMutableList()
|
||||||
newStack.add(SpellDatum.make(this.parenthesized.map { SpellDatum.make(it) }))
|
newStack.add(SpellDatum.make(this.parenthesized.toList()))
|
||||||
this.getFunctionalData().copy(
|
this.getFunctionalData().copy(
|
||||||
stack = newStack,
|
stack = newStack,
|
||||||
parenCount = newParenCount,
|
parenCount = newParenCount,
|
||||||
|
@ -229,7 +239,7 @@ class CastingHarness private constructor(
|
||||||
// we have this situation: "(()"
|
// we have this situation: "(()"
|
||||||
// we need to add the close paren
|
// we need to add the close paren
|
||||||
val newParens = this.parenthesized.toMutableList()
|
val newParens = this.parenthesized.toMutableList()
|
||||||
newParens.add(newPat)
|
newParens.add(iota)
|
||||||
this.getFunctionalData().copy(
|
this.getFunctionalData().copy(
|
||||||
parenCount = newParenCount,
|
parenCount = newParenCount,
|
||||||
parenthesized = newParens
|
parenthesized = newParens
|
||||||
|
@ -237,14 +247,14 @@ class CastingHarness private constructor(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val newParens = this.parenthesized.toMutableList()
|
val newParens = this.parenthesized.toMutableList()
|
||||||
newParens.add(newPat)
|
newParens.add(iota)
|
||||||
this.getFunctionalData().copy(
|
this.getFunctionalData().copy(
|
||||||
parenthesized = newParens
|
parenthesized = newParens
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (this.escapeNext) {
|
} else if (this.escapeNext) {
|
||||||
val newStack = this.stack.toMutableList()
|
val newStack = this.stack.toMutableList()
|
||||||
newStack.add(SpellDatum.make(newPat))
|
newStack.add(iota)
|
||||||
this.getFunctionalData().copy(
|
this.getFunctionalData().copy(
|
||||||
stack = newStack,
|
stack = newStack,
|
||||||
escapeNext = false,
|
escapeNext = false,
|
||||||
|
@ -390,10 +400,13 @@ class CastingHarness private constructor(
|
||||||
val localTag = nbt.getCompound(TAG_LOCAL)
|
val localTag = nbt.getCompound(TAG_LOCAL)
|
||||||
val localIota = SpellDatum.DeserializeFromNBT(localTag, ctx.world)
|
val localIota = SpellDatum.DeserializeFromNBT(localTag, ctx.world)
|
||||||
|
|
||||||
val parenthesized = mutableListOf<HexPattern>()
|
val parenthesized = mutableListOf<SpellDatum<*>>()
|
||||||
val parenTag = nbt.getList(TAG_PARENTHESIZED, Tag.TAG_COMPOUND)
|
val parenTag = nbt.getList(TAG_PARENTHESIZED, Tag.TAG_COMPOUND)
|
||||||
for (subtag in parenTag) {
|
for (subtag in parenTag) {
|
||||||
parenthesized.add(HexPattern.DeserializeFromNBT(subtag.asCompound))
|
if (subtag.asCompound.size() > 1)
|
||||||
|
parenthesized.add(SpellDatum.make(HexPattern.DeserializeFromNBT(subtag.asCompound)))
|
||||||
|
else
|
||||||
|
parenthesized.add(SpellDatum.DeserializeFromNBT(nbt, ctx.world))
|
||||||
}
|
}
|
||||||
|
|
||||||
val parenCount = nbt.getInt(TAG_PAREN_COUNT)
|
val parenCount = nbt.getInt(TAG_PAREN_COUNT)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package at.petrak.hexcasting.api.spell.casting
|
package at.petrak.hexcasting.api.spell.casting
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A change to the data in a CastHarness after a pattern is drawn.
|
* A change to the data in a CastHarness after a pattern is drawn.
|
||||||
|
@ -11,7 +10,7 @@ import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||||
data class FunctionalData(
|
data class FunctionalData(
|
||||||
val stack: List<SpellDatum<*>>,
|
val stack: List<SpellDatum<*>>,
|
||||||
val parenCount: Int,
|
val parenCount: Int,
|
||||||
val parenthesized: List<HexPattern>,
|
val parenthesized: List<SpellDatum<*>>,
|
||||||
val escapeNext: Boolean,
|
val escapeNext: Boolean,
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package at.petrak.hexcasting.api.spell.mishaps
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||||
|
import at.petrak.hexcasting.api.spell.DatumType
|
||||||
|
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||||
|
import at.petrak.hexcasting.api.spell.Widget
|
||||||
|
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.world.item.DyeColor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value was a naked iota without being Considered or Retrospected.
|
||||||
|
*/
|
||||||
|
class MishapUnescapedValue(
|
||||||
|
val perpetrator: SpellDatum<*>
|
||||||
|
) : Mishap() {
|
||||||
|
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||||
|
dyeColor(DyeColor.GRAY)
|
||||||
|
|
||||||
|
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
|
||||||
|
val idx = stack.indexOfLast { it.getType() == DatumType.LIST }
|
||||||
|
if (idx != -1)
|
||||||
|
stack[idx] = SpellDatum.make(Widget.GARBAGE)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
|
||||||
|
error(
|
||||||
|
"unescaped",
|
||||||
|
perpetrator.display()
|
||||||
|
)
|
||||||
|
}
|
|
@ -277,7 +277,7 @@ public class RegisterClientStuff {
|
||||||
private static void registerPackagedSpellOverrides(ItemPackagedSpell item) {
|
private static void registerPackagedSpellOverrides(ItemPackagedSpell item) {
|
||||||
ItemProperties.register(item, ItemPackagedSpell.HAS_PATTERNS_PRED,
|
ItemProperties.register(item, ItemPackagedSpell.HAS_PATTERNS_PRED,
|
||||||
(stack, level, holder, holderID) ->
|
(stack, level, holder, holderID) ->
|
||||||
item.getPatterns(stack) != null ? 1f : 0f
|
item.hasSpell(stack) ? 1f : 0f
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,6 @@ import at.petrak.hexcasting.api.spell.SpellDatum
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingHarness
|
import at.petrak.hexcasting.api.spell.casting.CastingHarness
|
||||||
import at.petrak.hexcasting.api.spell.casting.OperatorSideEffect
|
import at.petrak.hexcasting.api.spell.casting.OperatorSideEffect
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidIota
|
|
||||||
import net.minecraft.network.chat.TranslatableComponent
|
|
||||||
|
|
||||||
object OpEval : Operator {
|
object OpEval : Operator {
|
||||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||||
|
@ -23,13 +20,8 @@ object OpEval : Operator {
|
||||||
|
|
||||||
val sideEffects = mutableListOf<OperatorSideEffect>()
|
val sideEffects = mutableListOf<OperatorSideEffect>()
|
||||||
|
|
||||||
for (pat in instrs) {
|
for (insn in instrs) {
|
||||||
val pattern = if (pat.payload is HexPattern) {
|
val res = harness.getUpdate(insn, ctx.world)
|
||||||
pat.payload
|
|
||||||
} else {
|
|
||||||
throw MishapInvalidIota(SpellDatum.make(instrs), 0, TranslatableComponent("hexcasting.mishap.invalid_value.list.pattern"))
|
|
||||||
}
|
|
||||||
val res = harness.getUpdate(pattern, ctx.world)
|
|
||||||
sideEffects.addAll(res.sideEffects)
|
sideEffects.addAll(res.sideEffects)
|
||||||
if (res.sideEffects.any { it is OperatorSideEffect.DoMishap }) {
|
if (res.sideEffects.any { it is OperatorSideEffect.DoMishap }) {
|
||||||
break
|
break
|
||||||
|
|
|
@ -7,10 +7,7 @@ import at.petrak.hexcasting.api.spell.SpellDatum
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingHarness
|
import at.petrak.hexcasting.api.spell.casting.CastingHarness
|
||||||
import at.petrak.hexcasting.api.spell.casting.OperatorSideEffect
|
import at.petrak.hexcasting.api.spell.casting.OperatorSideEffect
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidIota
|
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
||||||
import net.minecraft.network.chat.TranslatableComponent
|
|
||||||
|
|
||||||
object OpForEach : Operator {
|
object OpForEach : Operator {
|
||||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||||
|
@ -33,17 +30,8 @@ object OpForEach : Operator {
|
||||||
harness.stack.addAll(stack)
|
harness.stack.addAll(stack)
|
||||||
harness.stack.add(subdatum)
|
harness.stack.add(subdatum)
|
||||||
harness.localIota = localIota
|
harness.localIota = localIota
|
||||||
for (pat in instrs) {
|
for (insn in instrs) {
|
||||||
val pattern = if (pat.payload is HexPattern) {
|
val res = harness.getUpdate(insn, ctx.world)
|
||||||
pat.payload
|
|
||||||
} else {
|
|
||||||
throw MishapInvalidIota(
|
|
||||||
SpellDatum.make(instrs),
|
|
||||||
1,
|
|
||||||
TranslatableComponent("hexcasting.mishap.invalid_value.list.pattern")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val res = harness.getUpdate(pattern, ctx.world)
|
|
||||||
sideEffects.addAll(res.sideEffects)
|
sideEffects.addAll(res.sideEffects)
|
||||||
if (res.sideEffects.any { it is OperatorSideEffect.DoMishap }) {
|
if (res.sideEffects.any { it is OperatorSideEffect.DoMishap }) {
|
||||||
return OperationResult(harness.stack, harness.localIota, sideEffects)
|
return OperationResult(harness.stack, harness.localIota, sideEffects)
|
||||||
|
|
|
@ -20,13 +20,13 @@ class OpErase : SpellOperator {
|
||||||
val spellHolder = HexCapabilities.getCapability(it, HexCapabilities.SPELL)
|
val spellHolder = HexCapabilities.getCapability(it, HexCapabilities.SPELL)
|
||||||
val datumHolder = HexCapabilities.getCapability(it, HexCapabilities.DATUM)
|
val datumHolder = HexCapabilities.getCapability(it, HexCapabilities.DATUM)
|
||||||
|
|
||||||
(spellHolder.isPresent && spellHolder.get().patterns != null) ||
|
(spellHolder.isPresent && spellHolder.get().hasSpell()) ||
|
||||||
(datumHolder.isPresent && datumHolder.get().writeDatum(null, true))
|
(datumHolder.isPresent && datumHolder.get().writeDatum(null, true))
|
||||||
}
|
}
|
||||||
val spellHolder = HexCapabilities.getCapability(handStack, HexCapabilities.SPELL)
|
val spellHolder = HexCapabilities.getCapability(handStack, HexCapabilities.SPELL)
|
||||||
val datumHolder = HexCapabilities.getCapability(handStack, HexCapabilities.DATUM)
|
val datumHolder = HexCapabilities.getCapability(handStack, HexCapabilities.DATUM)
|
||||||
|
|
||||||
if ((!spellHolder.isPresent || spellHolder.get().patterns == null) &&
|
if ((!spellHolder.isPresent || !spellHolder.get().hasSpell()) &&
|
||||||
(!datumHolder.isPresent || datumHolder.get().readDatum(ctx.world) == null ||
|
(!datumHolder.isPresent || datumHolder.get().readDatum(ctx.world) == null ||
|
||||||
!datumHolder.get().writeDatum(null, true))) {
|
!datumHolder.get().writeDatum(null, true))) {
|
||||||
throw MishapBadOffhandItem.of(handStack, hand, "eraseable")
|
throw MishapBadOffhandItem.of(handStack, hand, "eraseable")
|
||||||
|
@ -41,13 +41,13 @@ class OpErase : SpellOperator {
|
||||||
val spellHolder = HexCapabilities.getCapability(it, HexCapabilities.SPELL)
|
val spellHolder = HexCapabilities.getCapability(it, HexCapabilities.SPELL)
|
||||||
val datumHolder = HexCapabilities.getCapability(it, HexCapabilities.DATUM)
|
val datumHolder = HexCapabilities.getCapability(it, HexCapabilities.DATUM)
|
||||||
|
|
||||||
(spellHolder.isPresent && spellHolder.get().patterns != null) ||
|
(spellHolder.isPresent && spellHolder.get().hasSpell()) ||
|
||||||
(datumHolder.isPresent && datumHolder.get().writeDatum(null, true))
|
(datumHolder.isPresent && datumHolder.get().writeDatum(null, true))
|
||||||
}
|
}
|
||||||
val spellHolder = HexCapabilities.getCapability(handStack, HexCapabilities.SPELL)
|
val spellHolder = HexCapabilities.getCapability(handStack, HexCapabilities.SPELL)
|
||||||
val datumHolder = HexCapabilities.getCapability(handStack, HexCapabilities.DATUM)
|
val datumHolder = HexCapabilities.getCapability(handStack, HexCapabilities.DATUM)
|
||||||
|
|
||||||
if (spellHolder.isPresent && spellHolder.get().patterns != null)
|
if (spellHolder.isPresent && spellHolder.get().hasSpell())
|
||||||
spellHolder.get().clearPatterns()
|
spellHolder.get().clearPatterns()
|
||||||
|
|
||||||
if (datumHolder.isPresent && datumHolder.get().writeDatum(null, true))
|
if (datumHolder.isPresent && datumHolder.get().writeDatum(null, true))
|
||||||
|
|
|
@ -7,13 +7,10 @@ import at.petrak.hexcasting.api.spell.RenderedSpell
|
||||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||||
import at.petrak.hexcasting.api.spell.SpellOperator
|
import at.petrak.hexcasting.api.spell.SpellOperator
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
|
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
|
||||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
|
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.api.utils.ManaHelper
|
||||||
import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell
|
import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell
|
||||||
import net.minecraft.network.chat.TranslatableComponent
|
|
||||||
import net.minecraft.world.entity.item.ItemEntity
|
import net.minecraft.world.entity.item.ItemEntity
|
||||||
|
|
||||||
class OpMakePackagedSpell<T : ItemPackagedSpell>(val itemType: T, val cost: Int) : SpellOperator {
|
class OpMakePackagedSpell<T : ItemPackagedSpell>(val itemType: T, val cost: Int) : SpellOperator {
|
||||||
|
@ -23,18 +20,17 @@ class OpMakePackagedSpell<T : ItemPackagedSpell>(val itemType: T, val cost: Int)
|
||||||
ctx: CastingContext
|
ctx: CastingContext
|
||||||
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
|
||||||
val entity = args.getChecked<ItemEntity>(0)
|
val entity = args.getChecked<ItemEntity>(0)
|
||||||
val patternsRaw = args.getChecked<List<SpellDatum<*>>>(1)
|
val patterns = args.getChecked<List<SpellDatum<*>>>(1)
|
||||||
|
|
||||||
val patterns = patternsRaw.map {
|
val (handStack, hand) = ctx.getHeldItemToOperateOn {
|
||||||
if (it.payload is HexPattern)
|
val spellHolder = HexCapabilities.getCapability(it, HexCapabilities.SPELL)
|
||||||
it.payload
|
it.`is`(itemType) && spellHolder.isPresent && !spellHolder.get().hasSpell()
|
||||||
else
|
|
||||||
throw MishapInvalidIota(SpellDatum.make(patternsRaw), 0, TranslatableComponent("hexcasting.mishap.invalid_value.list.pattern"))
|
|
||||||
}
|
}
|
||||||
|
val spellHolder = HexCapabilities.getCapability(handStack, HexCapabilities.SPELL)
|
||||||
val (handStack, hand) = ctx.getHeldItemToOperateOn { it.`is`(itemType) }
|
|
||||||
if (!handStack.`is`(itemType)) {
|
if (!handStack.`is`(itemType)) {
|
||||||
throw MishapBadOffhandItem(handStack, hand, itemType.description)
|
throw MishapBadOffhandItem(handStack, hand, itemType.description)
|
||||||
|
} else if (spellHolder.get().hasSpell()) {
|
||||||
|
throw MishapBadOffhandItem.of(handStack, hand, "iota.write")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.assertEntityInRange(entity)
|
ctx.assertEntityInRange(entity)
|
||||||
|
@ -53,12 +49,12 @@ class OpMakePackagedSpell<T : ItemPackagedSpell>(val itemType: T, val cost: Int)
|
||||||
return Triple(Spell(entity, patterns), cost, listOf(ParticleSpray.Burst(entity.position(), 0.5)))
|
return Triple(Spell(entity, patterns), cost, listOf(ParticleSpray.Burst(entity.position(), 0.5)))
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class Spell(val itemEntity: ItemEntity, val patterns: List<HexPattern>) : RenderedSpell {
|
private inner class Spell(val itemEntity: ItemEntity, val patterns: List<SpellDatum<*>>) : RenderedSpell {
|
||||||
override fun cast(ctx: CastingContext) {
|
override fun cast(ctx: CastingContext) {
|
||||||
val (handStack) = ctx.getHeldItemToOperateOn { it.`is`(itemType) }
|
val (handStack) = ctx.getHeldItemToOperateOn { it.`is`(itemType) }
|
||||||
val spellHolder = HexCapabilities.getCapability(handStack, HexCapabilities.SPELL)
|
val spellHolder = HexCapabilities.getCapability(handStack, HexCapabilities.SPELL)
|
||||||
if (spellHolder.isPresent
|
if (spellHolder.isPresent
|
||||||
&& spellHolder.get().patterns == null
|
&& !spellHolder.get().hasSpell()
|
||||||
&& itemEntity.isAlive
|
&& itemEntity.isAlive
|
||||||
) {
|
) {
|
||||||
val entityStack = itemEntity.item.copy()
|
val entityStack = itemEntity.item.copy()
|
||||||
|
|
|
@ -2,6 +2,7 @@ package at.petrak.hexcasting.common.items.magic;
|
||||||
|
|
||||||
import at.petrak.hexcasting.HexMod;
|
import at.petrak.hexcasting.HexMod;
|
||||||
import at.petrak.hexcasting.api.item.SpellHolderItem;
|
import at.petrak.hexcasting.api.item.SpellHolderItem;
|
||||||
|
import at.petrak.hexcasting.api.spell.SpellDatum;
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingContext;
|
import at.petrak.hexcasting.api.spell.casting.CastingContext;
|
||||||
import at.petrak.hexcasting.api.spell.casting.CastingHarness;
|
import at.petrak.hexcasting.api.spell.casting.CastingHarness;
|
||||||
import at.petrak.hexcasting.api.utils.NBTHelper;
|
import at.petrak.hexcasting.api.utils.NBTHelper;
|
||||||
|
@ -11,6 +12,7 @@ import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.ListTag;
|
import net.minecraft.nbt.ListTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.sounds.SoundSource;
|
import net.minecraft.sounds.SoundSource;
|
||||||
import net.minecraft.stats.Stat;
|
import net.minecraft.stats.Stat;
|
||||||
|
@ -50,23 +52,32 @@ public abstract class ItemPackagedSpell extends ItemManaHolder implements SpellH
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<HexPattern> getPatterns(ItemStack stack) {
|
public boolean hasSpell(ItemStack stack) {
|
||||||
|
return NBTHelper.hasCompound(stack, TAG_PATTERNS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<SpellDatum<?>> getSpell(ItemStack stack, ServerLevel level) {
|
||||||
var patsTag = NBTHelper.getList(stack, TAG_PATTERNS, Tag.TAG_COMPOUND);
|
var patsTag = NBTHelper.getList(stack, TAG_PATTERNS, Tag.TAG_COMPOUND);
|
||||||
|
|
||||||
if (patsTag == null)
|
if (patsTag == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var out = new ArrayList<HexPattern>();
|
var out = new ArrayList<SpellDatum<?>>();
|
||||||
for (var patTag : patsTag) {
|
for (var patTag : patsTag) {
|
||||||
out.add(HexPattern.DeserializeFromNBT((CompoundTag) patTag));
|
CompoundTag tag = NBTHelper.getAsCompound(patTag);
|
||||||
|
if (tag.size() > 1)
|
||||||
|
out.add(SpellDatum.make(HexPattern.DeserializeFromNBT(tag)));
|
||||||
|
else
|
||||||
|
out.add(SpellDatum.DeserializeFromNBT(tag, level));
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writePatterns(ItemStack stack, List<HexPattern> patterns, int mana) {
|
public void writePatterns(ItemStack stack, List<SpellDatum<?>> patterns, int mana) {
|
||||||
ListTag patsTag = new ListTag();
|
ListTag patsTag = new ListTag();
|
||||||
for (HexPattern pat : patterns)
|
for (SpellDatum<?> pat : patterns)
|
||||||
patsTag.add(pat.serializeToNBT());
|
patsTag.add(pat.serializeToNBT());
|
||||||
|
|
||||||
NBTHelper.putList(stack, TAG_PATTERNS, patsTag);
|
NBTHelper.putList(stack, TAG_PATTERNS, patsTag);
|
||||||
|
@ -83,19 +94,23 @@ public abstract class ItemPackagedSpell extends ItemManaHolder implements SpellH
|
||||||
@Override
|
@Override
|
||||||
public InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand usedHand) {
|
public InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand usedHand) {
|
||||||
var stack = player.getItemInHand(usedHand);
|
var stack = player.getItemInHand(usedHand);
|
||||||
List<HexPattern> patterns = getPatterns(stack);
|
if (!hasSpell(stack)) {
|
||||||
if (patterns == null) {
|
|
||||||
return InteractionResultHolder.fail(stack);
|
return InteractionResultHolder.fail(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (world.isClientSide) {
|
if (world.isClientSide) {
|
||||||
return InteractionResultHolder.success(stack);
|
return InteractionResultHolder.success(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<SpellDatum<?>> instrs = getSpell(stack, (ServerLevel) world);
|
||||||
|
if (instrs == null) {
|
||||||
|
return InteractionResultHolder.fail(stack);
|
||||||
|
}
|
||||||
var sPlayer = (ServerPlayer) player;
|
var sPlayer = (ServerPlayer) player;
|
||||||
var ctx = new CastingContext(sPlayer, usedHand);
|
var ctx = new CastingContext(sPlayer, usedHand);
|
||||||
var harness = new CastingHarness(ctx);
|
var harness = new CastingHarness(ctx);
|
||||||
for (var pattern : patterns) {
|
for (var insn : instrs) {
|
||||||
var info = harness.executeNewPattern(pattern, sPlayer.getLevel());
|
var info = harness.executeNewIota(insn, sPlayer.getLevel());
|
||||||
if (info.getWasPrevPatternInvalid()) {
|
if (info.getWasPrevPatternInvalid()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
package at.petrak.hexcasting.common.lib;
|
package at.petrak.hexcasting.common.lib;
|
||||||
|
|
||||||
import at.petrak.hexcasting.api.cap.Colorizer;
|
import at.petrak.hexcasting.api.cap.*;
|
||||||
import at.petrak.hexcasting.api.cap.DataHolder;
|
import at.petrak.hexcasting.api.item.ColorizerItem;
|
||||||
import at.petrak.hexcasting.api.cap.ManaHolder;
|
import at.petrak.hexcasting.api.item.DataHolderItem;
|
||||||
import at.petrak.hexcasting.api.cap.SpellHolder;
|
import at.petrak.hexcasting.api.item.ManaHolderItem;
|
||||||
|
import at.petrak.hexcasting.api.item.SpellHolderItem;
|
||||||
import at.petrak.hexcasting.api.mod.HexConfig;
|
import at.petrak.hexcasting.api.mod.HexConfig;
|
||||||
import at.petrak.hexcasting.api.item.*;
|
|
||||||
import at.petrak.hexcasting.api.spell.SpellDatum;
|
import at.petrak.hexcasting.api.spell.SpellDatum;
|
||||||
import at.petrak.hexcasting.api.cap.HexCapabilities;
|
|
||||||
import at.petrak.hexcasting.common.items.HexItems;
|
import at.petrak.hexcasting.common.items.HexItems;
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
@ -18,7 +16,9 @@ import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec;
|
import net.minecraftforge.common.ForgeConfigSpec;
|
||||||
import net.minecraftforge.common.capabilities.*;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
|
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||||
|
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.common.util.NonNullSupplier;
|
import net.minecraftforge.common.util.NonNullSupplier;
|
||||||
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
||||||
|
@ -51,44 +51,48 @@ public class HexCapabilityHandler {
|
||||||
public static void attachCaps(AttachCapabilitiesEvent<ItemStack> evt) {
|
public static void attachCaps(AttachCapabilitiesEvent<ItemStack> evt) {
|
||||||
ItemStack stack = evt.getObject();
|
ItemStack stack = evt.getObject();
|
||||||
if (stack.getItem() instanceof ManaHolderItem holder)
|
if (stack.getItem() instanceof ManaHolderItem holder)
|
||||||
evt.addCapability(MANA_HOLDER_CAPABILITY, provide(HexCapabilities.MANA,
|
evt.addCapability(MANA_HOLDER_CAPABILITY, provide(stack, HexCapabilities.MANA,
|
||||||
() -> new ItemBasedManaHolder(holder, stack)));
|
() -> new ItemBasedManaHolder(holder, stack)));
|
||||||
else if (stack.is(HexItems.AMETHYST_DUST.get()))
|
else if (stack.is(HexItems.AMETHYST_DUST.get()))
|
||||||
evt.addCapability(MANA_ITEM_CAPABILITY, provide(HexCapabilities.MANA,
|
evt.addCapability(MANA_ITEM_CAPABILITY, provide(stack, HexCapabilities.MANA,
|
||||||
() -> new StaticManaHolder(HexConfig.dustManaAmount, 3, stack)));
|
() -> new StaticManaHolder(HexConfig.dustManaAmount, 3, stack)));
|
||||||
else if (stack.is(Items.AMETHYST_SHARD))
|
else if (stack.is(Items.AMETHYST_SHARD))
|
||||||
evt.addCapability(MANA_ITEM_CAPABILITY, provide(HexCapabilities.MANA,
|
evt.addCapability(MANA_ITEM_CAPABILITY, provide(stack, HexCapabilities.MANA,
|
||||||
() -> new StaticManaHolder(HexConfig.shardManaAmount, 2, stack)));
|
() -> new StaticManaHolder(HexConfig.shardManaAmount, 2, stack)));
|
||||||
else if (stack.is(HexItems.CHARGED_AMETHYST.get()))
|
else if (stack.is(HexItems.CHARGED_AMETHYST.get()))
|
||||||
evt.addCapability(MANA_ITEM_CAPABILITY, provide(HexCapabilities.MANA,
|
evt.addCapability(MANA_ITEM_CAPABILITY, provide(stack, HexCapabilities.MANA,
|
||||||
() -> new StaticManaHolder(HexConfig.chargedCrystalManaAmount, 1, stack)));
|
() -> new StaticManaHolder(HexConfig.chargedCrystalManaAmount, 1, stack)));
|
||||||
|
|
||||||
if (stack.getItem() instanceof DataHolderItem holder)
|
if (stack.getItem() instanceof DataHolderItem holder)
|
||||||
evt.addCapability(DATA_HOLDER_CAPABILITY, provide(HexCapabilities.DATUM,
|
evt.addCapability(DATA_HOLDER_CAPABILITY, provide(stack, HexCapabilities.DATUM,
|
||||||
() -> new ItemBasedDataHolder(holder, stack)));
|
() -> new ItemBasedDataHolder(holder, stack)));
|
||||||
else if (stack.is(Items.PUMPKIN_PIE)) // haha yes
|
else if (stack.is(Items.PUMPKIN_PIE)) // haha yes
|
||||||
evt.addCapability(DATA_ITEM_CAPABILITY, provide(HexCapabilities.DATUM,
|
evt.addCapability(DATA_ITEM_CAPABILITY, provide(stack, HexCapabilities.DATUM,
|
||||||
() -> new StaticDatumHolder((s) -> SpellDatum.make(Math.PI * s.getCount()), stack)));
|
() -> new StaticDatumHolder((s) -> SpellDatum.make(Math.PI * s.getCount()), stack)));
|
||||||
|
|
||||||
if (stack.getItem() instanceof SpellHolderItem holder)
|
if (stack.getItem() instanceof SpellHolderItem holder)
|
||||||
evt.addCapability(SPELL_HOLDER_CAPABILITY, provide(HexCapabilities.SPELL,
|
evt.addCapability(SPELL_HOLDER_CAPABILITY, provide(stack, HexCapabilities.SPELL,
|
||||||
() -> new ItemBasedSpellHolder(holder, stack)));
|
() -> new ItemBasedSpellHolder(holder, stack)));
|
||||||
|
|
||||||
if (stack.getItem() instanceof ColorizerItem colorizer)
|
if (stack.getItem() instanceof ColorizerItem colorizer)
|
||||||
evt.addCapability(COLORIZER_CAPABILITY, provide(HexCapabilities.COLOR,
|
evt.addCapability(COLORIZER_CAPABILITY, provide(stack, HexCapabilities.COLOR,
|
||||||
() -> new ItemBasedColorizer(colorizer, stack)));
|
() -> new ItemBasedColorizer(colorizer, stack)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <CAP> SimpleProvider<CAP> provide(Capability<CAP> capability, NonNullSupplier<CAP> supplier) {
|
private static <CAP> SimpleProvider<CAP> provide(ItemStack stack, Capability<CAP> capability, NonNullSupplier<CAP> supplier) {
|
||||||
return new SimpleProvider<>(capability, LazyOptional.of(supplier));
|
return new SimpleProvider<>(stack, capability, LazyOptional.of(supplier));
|
||||||
}
|
}
|
||||||
|
|
||||||
private record SimpleProvider<CAP>(Capability<CAP> capability,
|
private record SimpleProvider<CAP>(ItemStack stack,
|
||||||
|
Capability<CAP> capability,
|
||||||
LazyOptional<CAP> instance) implements ICapabilityProvider {
|
LazyOptional<CAP> instance) implements ICapabilityProvider {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||||
|
if (stack.isEmpty())
|
||||||
|
return LazyOptional.empty();
|
||||||
|
|
||||||
return cap == capability ? instance.cast() : LazyOptional.empty();
|
return cap == capability ? instance.cast() : LazyOptional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,12 +249,17 @@ public class HexCapabilityHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<HexPattern> getPatterns() {
|
public boolean hasSpell() {
|
||||||
return holder.getPatterns(stack);
|
return holder.hasSpell(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writePatterns(List<HexPattern> patterns, int mana) {
|
public @Nullable List<SpellDatum<?>> getPatterns(ServerLevel level) {
|
||||||
|
return holder.getSpell(stack, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writePatterns(List<SpellDatum<?>> patterns, int mana) {
|
||||||
holder.writePatterns(stack, patterns, mana);
|
holder.writePatterns(stack, patterns, mana);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package at.petrak.hexcasting.common.network;
|
package at.petrak.hexcasting.common.network;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.mod.HexItemTags;
|
||||||
import at.petrak.hexcasting.api.player.HexPlayerDataHelper;
|
import at.petrak.hexcasting.api.player.HexPlayerDataHelper;
|
||||||
|
import at.petrak.hexcasting.api.spell.SpellDatum;
|
||||||
import at.petrak.hexcasting.api.spell.casting.ControllerInfo;
|
import at.petrak.hexcasting.api.spell.casting.ControllerInfo;
|
||||||
import at.petrak.hexcasting.api.spell.casting.ResolvedPattern;
|
import at.petrak.hexcasting.api.spell.casting.ResolvedPattern;
|
||||||
import at.petrak.hexcasting.api.spell.casting.ResolvedPatternValidity;
|
import at.petrak.hexcasting.api.spell.casting.ResolvedPatternValidity;
|
||||||
import at.petrak.hexcasting.api.spell.math.HexCoord;
|
import at.petrak.hexcasting.api.spell.math.HexCoord;
|
||||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
||||||
import at.petrak.hexcasting.api.mod.HexItemTags;
|
|
||||||
import at.petrak.hexcasting.common.lib.HexSounds;
|
import at.petrak.hexcasting.common.lib.HexSounds;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
@ -74,7 +75,7 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern
|
||||||
if (autoFail) {
|
if (autoFail) {
|
||||||
clientInfo = new ControllerInfo(false, false, harness.getStack().isEmpty(), true, harness.generateDescs());
|
clientInfo = new ControllerInfo(false, false, harness.getStack().isEmpty(), true, harness.generateDescs());
|
||||||
} else {
|
} else {
|
||||||
clientInfo = harness.executeNewPattern(this.pattern, sender.getLevel());
|
clientInfo = harness.executeNewIota(SpellDatum.make(this.pattern), sender.getLevel());
|
||||||
|
|
||||||
if (clientInfo.getWasSpellCast() && clientInfo.getHasCastingSound()) {
|
if (clientInfo.getWasSpellCast() && clientInfo.getHasCastingSound()) {
|
||||||
sender.level.playSound(null, sender.getX(), sender.getY(), sender.getZ(),
|
sender.level.playSound(null, sender.getX(), sender.getY(), sender.getZ(),
|
||||||
|
|
|
@ -336,6 +336,7 @@
|
||||||
"hexcasting.spell.unknown": "Special Handler",
|
"hexcasting.spell.unknown": "Special Handler",
|
||||||
|
|
||||||
"hexcasting.mishap.invalid_pattern": "That pattern isn't associated with any action",
|
"hexcasting.mishap.invalid_pattern": "That pattern isn't associated with any action",
|
||||||
|
"hexcasting.mishap.unescaped": "Expected to evaluate a pattern, but evaluated %s instead",
|
||||||
"hexcasting.mishap.invalid_value": "%s expected %s at index %s of the stack, but got %s",
|
"hexcasting.mishap.invalid_value": "%s expected %s at index %s of the stack, but got %s",
|
||||||
"hexcasting.mishap.invalid_value.class.double": "a number",
|
"hexcasting.mishap.invalid_value.class.double": "a number",
|
||||||
"hexcasting.mishap.invalid_value.class.vector": "a vector",
|
"hexcasting.mishap.invalid_value.class.vector": "a vector",
|
||||||
|
|
Loading…
Reference in a new issue