Merge pull request #496 from Talia-12/1.20.1

1.20.1
This commit is contained in:
petrak@ 2023-07-20 10:24:34 -04:00 committed by GitHub
commit 3e3cf73150
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
136 changed files with 1103 additions and 313 deletions

View file

@ -2,8 +2,8 @@ Hello, intrepid Github reader!
The "flavor text" words for things in this mod and the internal names are different. (Sorry.) The "flavor text" words for things in this mod and the internal names are different. (Sorry.)
- A "Hex" is a `Cast`, cast through a [`CastingHarness`](api/casting/eval/vm/CastingVM.kt) - A "Hex" is a `Continuation`, cast through a [`CastingVM`](api/casting/eval/vm/CastingVM.kt)
- A "Pattern" is a [`HexPattern`](api/casting/math/HexPattern.kt) - A "Pattern" is a [`HexPattern`](api/casting/math/HexPattern.kt)
- An "Action" is an [`Operator`](api/casting/castables/Action.kt) - An "Action" is an [`Action`](api/casting/castables/Action.kt)
- An action that pushes a spell is a [`Spell`](api/casting/castables/SpellAction.kt) - An action that pushes a spell is a [`Spell`](api/casting/castables/SpellAction.kt)

View file

@ -1,7 +1,13 @@
package at.petrak.hexcasting.api.casting package at.petrak.hexcasting.api.casting
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
interface RenderedSpell { interface RenderedSpell {
fun cast(env: CastingEnvironment) fun cast(env: CastingEnvironment)
fun cast(env: CastingEnvironment, image: CastingImage): CastingImage? {
cast(env)
return null
}
} }

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.engine;
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic; import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic;
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator; import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.Iota;
import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.api.casting.math.HexPattern;
import at.petrak.hexcasting.api.casting.mishaps.Mishap; import at.petrak.hexcasting.api.casting.mishaps.Mishap;
@ -65,10 +66,11 @@ public class ArithmeticEngine {
* @param pattern The pattern that was drawn, used to determine which operators are candidates. * @param pattern The pattern that was drawn, used to determine which operators are candidates.
* @param iotas The current stack. * @param iotas The current stack.
* @param startingLength The length of the stack before the operator executes (used for errors). * @param startingLength The length of the stack before the operator executes (used for errors).
* @param env The casting environment.
* @return The iotas to be added to the stack. * @return The iotas to be added to the stack.
* @throws Mishap mishaps if invalid input to the operators is given by the caster. * @throws Mishap mishaps if invalid input to the operators is given by the caster.
*/ */
public Iterable<Iota> run(HexPattern pattern, Stack<Iota> iotas, int startingLength) throws Mishap { public Iterable<Iota> run(HexPattern pattern, Stack<Iota> iotas, int startingLength, CastingEnvironment env) throws Mishap {
var candidates = operators.get(pattern); var candidates = operators.get(pattern);
if (candidates == null) if (candidates == null)
throw new InvalidOperatorException("the pattern " + pattern + " is not an operator."); // throw new InvalidOperatorException("the pattern " + pattern + " is not an operator."); //
@ -84,7 +86,7 @@ public class ArithmeticEngine {
} }
Collections.reverse(args); Collections.reverse(args);
var op = resolveCandidates(args, hash, candidates); var op = resolveCandidates(args, hash, candidates);
return op.apply(args); return op.apply(args, env);
} }
private Operator resolveCandidates(List<Iota> args, HashCons hash, OpCandidates candidates) { private Operator resolveCandidates(List<Iota> args, HashCons hash, OpCandidates candidates) {

View file

@ -1,6 +1,7 @@
package at.petrak.hexcasting.api.casting.arithmetic.operator; package at.petrak.hexcasting.api.casting.arithmetic.operator;
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate; import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.Iota;
import at.petrak.hexcasting.api.casting.iota.IotaType; import at.petrak.hexcasting.api.casting.iota.IotaType;
import at.petrak.hexcasting.api.casting.mishaps.Mishap; import at.petrak.hexcasting.api.casting.mishaps.Mishap;
@ -36,10 +37,11 @@ public abstract class Operator {
/** /**
* The method called when this Operator is actually acting on the stack, for real. * The method called when this Operator is actually acting on the stack, for real.
* @param iotas An iterable of iotas with {@link Operator#arity} elements that satisfied {@link Operator#accepts}. * @param iotas An iterable of iotas with {@link Operator#arity} elements that satisfied {@link Operator#accepts}.
* @param env The casting environment, to make use of if this operator needs it.
* @return the iotas that this operator will return to the stack (with the first element of the returned iterable being placed deepest into the stack, and the last element on top of the stack). * @return the iotas that this operator will return to the stack (with the first element of the returned iterable being placed deepest into the stack, and the last element on top of the stack).
* @throws Mishap if the Operator mishaps for any reason it will be passed up the chain. * @throws Mishap if the Operator mishaps for any reason it will be passed up the chain.
*/ */
public abstract @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) throws Mishap; public abstract @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) throws Mishap;
/** /**
* A helper method to take an iota that you know is of iotaType and returning it as an iota of that type. * A helper method to take an iota that you know is of iotaType and returning it as an iota of that type.

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.operator;
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate; import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.Iota;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -20,7 +21,7 @@ public class OperatorBinary extends Operator {
} }
@Override @Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) { public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) {
var it = iotas.iterator(); var it = iotas.iterator();
return List.of(inner.apply(it.next(), it.next())); return List.of(inner.apply(it.next(), it.next()));
} }

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.operator;
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate; import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.Iota;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -20,7 +21,7 @@ public class OperatorUnary extends Operator {
} }
@Override @Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) { public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) {
return List.of(inner.apply(iotas.iterator().next())); return List.of(inner.apply(iotas.iterator().next()));
} }
} }

View file

@ -3,6 +3,8 @@ package at.petrak.hexcasting.api.casting.arithmetic.predicates;
import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.Iota;
import at.petrak.hexcasting.api.casting.iota.IotaType; import at.petrak.hexcasting.api.casting.iota.IotaType;
import java.util.List;
/** /**
* Used to determine whether a given iota is an acceptable type for the operator that is storing this. It must be strictly a function * Used to determine whether a given iota is an acceptable type for the operator that is storing this. It must be strictly a function
* of the passed Iota's IotaType, or the caching done by ArithmeticEngine will be invalid. * of the passed Iota's IotaType, or the caching done by ArithmeticEngine will be invalid.
@ -18,6 +20,14 @@ public interface IotaPredicate {
return new Or(left, right); return new Or(left, right);
} }
static IotaPredicate any(IotaPredicate... any) {
return new Any(any);
}
static IotaPredicate any(List<IotaPredicate> any) {
return new Any(any.toArray(IotaPredicate[]::new));
}
/** /**
* The resulting IotaPredicate returns true if the given iota's type is type. * The resulting IotaPredicate returns true if the given iota's type is type.
*/ */
@ -32,6 +42,18 @@ public interface IotaPredicate {
} }
} }
record Any(IotaPredicate[] any) implements IotaPredicate {
@Override
public boolean test(Iota iota) {
for (var i : any) {
if (i.test(iota))
return true;
}
return false;
}
}
record OfType(IotaType<?> type) implements IotaPredicate { record OfType(IotaType<?> type) implements IotaPredicate {
@Override @Override
public boolean test(Iota iota) { public boolean test(Iota iota) {

View file

@ -14,7 +14,7 @@ import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
*/ */
interface ConstMediaAction : Action { interface ConstMediaAction : Action {
val argc: Int val argc: Int
val mediaCost: Int val mediaCost: Long
get() = 0 get() = 0
fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota>

View file

@ -24,7 +24,7 @@ data class OperationAction(val pattern: HexPattern) : Action {
stack.addAll(stackList) stack.addAll(stackList)
val startingLength = stackList.size val startingLength = stackList.size
return try { return try {
val ret: Iterable<Iota> = HexArithmetics.getEngine().run(pattern, stack, startingLength) val ret: Iterable<Iota> = HexArithmetics.getEngine().run(pattern, stack, startingLength, env)
ret.forEach(Consumer { e: Iota -> stack.add(e) }) ret.forEach(Consumer { e: Iota -> stack.add(e) })
val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + 1) // TODO: maybe let operators figure out how many ops to consume? val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + 1) // TODO: maybe let operators figure out how many ops to consume?
OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE) OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)

View file

@ -64,5 +64,5 @@ interface SpellAction : Action {
return OperationResult(image2, sideEffects, continuation, sound) return OperationResult(image2, sideEffects, continuation, sound)
} }
data class Result(val effect: RenderedSpell, val cost: Int, val particles: List<ParticleSpray>, val opCount: Long = 1) data class Result(val effect: RenderedSpell, val cost: Long, val particles: List<ParticleSpray>, val opCount: Long = 1)
} }

View file

@ -4,17 +4,20 @@ import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound
import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.iota.Iota
/** /**
* The result of doing something to a cast harness. * The result of doing something to a cast harness.
* *
* Contains the next thing to execute after this is finished, the modified state of the stack, * Contains the iota that was executed to produce this CastResult,
* the next thing to execute after this is finished, the modified state of the stack,
* and side effects, as well as display information for the client. * and side effects, as well as display information for the client.
*/ */
data class CastResult( data class CastResult(
val continuation: SpellContinuation, val cast: Iota,
val newData: CastingImage?, val continuation: SpellContinuation,
val sideEffects: List<OperatorSideEffect>, val newData: CastingImage?,
val resolutionType: ResolvedPatternType, val sideEffects: List<OperatorSideEffect>,
val sound: EvalSound, val resolutionType: ResolvedPatternType,
val sound: EvalSound,
) )

View file

@ -62,6 +62,15 @@ public abstract class CastingEnvironment {
public void precheckAction(PatternShapeMatch match) throws Mishap { public void precheckAction(PatternShapeMatch match) throws Mishap {
// TODO: this doesn't let you select special handlers. // TODO: this doesn't let you select special handlers.
// Might be worth making a "no casting" tag on each thing // Might be worth making a "no casting" tag on each thing
ResourceLocation key = actionKey(match);
if (!HexConfig.server().isActionAllowed(key)) {
throw new MishapDisallowedSpell();
}
}
@Nullable
protected ResourceLocation actionKey(PatternShapeMatch match) {
ResourceLocation key; ResourceLocation key;
if (match instanceof PatternShapeMatch.Normal normal) { if (match instanceof PatternShapeMatch.Normal normal) {
key = normal.key.location(); key = normal.key.location();
@ -72,9 +81,7 @@ public abstract class CastingEnvironment {
} else { } else {
key = null; key = null;
} }
if (!HexConfig.server().isActionAllowed(key)) { return key;
throw new MishapDisallowedSpell();
}
} }
/** /**

View file

@ -2,15 +2,20 @@ package at.petrak.hexcasting.api.casting.eval.env;
import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.api.casting.ParticleSpray; import at.petrak.hexcasting.api.casting.ParticleSpray;
import at.petrak.hexcasting.api.casting.PatternShapeMatch;
import at.petrak.hexcasting.api.casting.circles.BlockEntityAbstractImpetus; import at.petrak.hexcasting.api.casting.circles.BlockEntityAbstractImpetus;
import at.petrak.hexcasting.api.casting.circles.CircleExecutionState; import at.petrak.hexcasting.api.casting.circles.CircleExecutionState;
import at.petrak.hexcasting.api.casting.eval.CastResult; import at.petrak.hexcasting.api.casting.eval.CastResult;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.eval.MishapEnvironment; import at.petrak.hexcasting.api.casting.eval.MishapEnvironment;
import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect; import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect;
import at.petrak.hexcasting.api.casting.mishaps.Mishap;
import at.petrak.hexcasting.api.casting.mishaps.MishapDisallowedSpell;
import at.petrak.hexcasting.api.mod.HexConfig;
import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.pigment.FrozenPigment;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel; 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;
@ -55,6 +60,17 @@ public class CircleCastEnv extends CastingEnvironment {
return new CircleMishapEnv(this.world, this.execState); return new CircleMishapEnv(this.world, this.execState);
} }
@Override
public void precheckAction(PatternShapeMatch match) throws Mishap {
super.precheckAction(match);
ResourceLocation key = actionKey(match);
if (!HexConfig.server().isActionAllowedInCircles(key)) {
throw new MishapDisallowedSpell("disallowed_circle");
}
}
@Override @Override
public void postExecution(CastResult result) { public void postExecution(CastResult result) {
// we always want to play this sound one at a time // we always want to play this sound one at a time

View file

@ -2,12 +2,16 @@ package at.petrak.hexcasting.api.casting.eval.env;
import at.petrak.hexcasting.api.casting.eval.CastResult; import at.petrak.hexcasting.api.casting.eval.CastResult;
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound; import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
import at.petrak.hexcasting.api.casting.iota.PatternIota;
import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.pigment.FrozenPigment;
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds; import at.petrak.hexcasting.common.lib.hex.HexEvalSounds;
import at.petrak.hexcasting.common.msgs.MsgNewSpiralPatternsS2C;
import at.petrak.hexcasting.xplat.IXplatAbstractions; import at.petrak.hexcasting.xplat.IXplatAbstractions;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import java.util.List;
public class PackagedItemCastEnv extends PlayerBasedCastEnv { public class PackagedItemCastEnv extends PlayerBasedCastEnv {
protected EvalSound sound = HexEvalSounds.NOTHING; protected EvalSound sound = HexEvalSounds.NOTHING;
@ -19,6 +23,15 @@ public class PackagedItemCastEnv extends PlayerBasedCastEnv {
@Override @Override
public void postExecution(CastResult result) { public void postExecution(CastResult result) {
super.postExecution(result); super.postExecution(result);
if (result.component1() instanceof PatternIota patternIota) {
var packet = new MsgNewSpiralPatternsS2C(
this.caster.getUUID(), List.of(patternIota.getPattern()), 140
);
IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet);
IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet);
}
// TODO: how do we know when to actually play this sound? // TODO: how do we know when to actually play this sound?
this.sound = this.sound.greaterOf(result.getSound()); this.sound = this.sound.greaterOf(result.getSound());
} }
@ -56,7 +69,10 @@ public class PackagedItemCastEnv extends PlayerBasedCastEnv {
public FrozenPigment getPigment() { public FrozenPigment getPigment() {
var casterStack = this.caster.getItemInHand(this.castingHand); var casterStack = this.caster.getItemInHand(this.castingHand);
var casterHexHolder = IXplatAbstractions.INSTANCE.findHexHolder(casterStack); var casterHexHolder = IXplatAbstractions.INSTANCE.findHexHolder(casterStack);
return casterHexHolder.getPigment(); var hexHolderPigment = casterHexHolder.getPigment();
if (hexHolderPigment != null)
return hexHolderPigment;
return IXplatAbstractions.INSTANCE.getPigment(this.caster);
} }
public EvalSound getSound() { public EvalSound getSound() {

View file

@ -47,7 +47,7 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
} }
@Override @Override
public @Nullable ServerPlayer getCaster() { public ServerPlayer getCaster() {
return this.caster; return this.caster;
} }
@ -189,6 +189,8 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
protected long extractMediaFromInventory(long costLeft, boolean allowOvercast) { protected long extractMediaFromInventory(long costLeft, boolean allowOvercast) {
List<ADMediaHolder> sources = MediaHelper.scanPlayerForMediaStuff(this.caster); List<ADMediaHolder> sources = MediaHelper.scanPlayerForMediaStuff(this.caster);
var startCost = costLeft;
for (var source : sources) { for (var source : sources) {
var found = MediaHelper.extractMedia(source, (int) costLeft, true, false); var found = MediaHelper.extractMedia(source, (int) costLeft, true, false);
costLeft -= found; costLeft -= found;
@ -212,6 +214,8 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
costLeft -= actuallyTaken; costLeft -= actuallyTaken;
} }
this.caster.awardStat(HexStatistics.MEDIA_USED, (int) (startCost - costLeft));
return costLeft; return costLeft;
} }
@ -227,8 +231,8 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
} }
@Override @Override
public void produceParticles(ParticleSpray particles, FrozenPigment colorizer) { public void produceParticles(ParticleSpray particles, FrozenPigment pigment) {
particles.sprayParticles(this.world, colorizer); particles.sprayParticles(this.world, pigment);
} }
@Override @Override

View file

@ -9,8 +9,7 @@ import at.petrak.hexcasting.api.casting.iota.PatternIota;
import at.petrak.hexcasting.api.casting.math.HexCoord; import at.petrak.hexcasting.api.casting.math.HexCoord;
import at.petrak.hexcasting.api.mod.HexStatistics; import at.petrak.hexcasting.api.mod.HexStatistics;
import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.pigment.FrozenPigment;
import at.petrak.hexcasting.common.msgs.MsgNewSpellPatternC2S; import at.petrak.hexcasting.common.msgs.*;
import at.petrak.hexcasting.common.msgs.MsgNewSpellPatternS2C;
import at.petrak.hexcasting.xplat.IXplatAbstractions; import at.petrak.hexcasting.xplat.IXplatAbstractions;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
@ -35,6 +34,14 @@ public class StaffCastEnv extends PlayerBasedCastEnv {
public void postExecution(CastResult result) { public void postExecution(CastResult result) {
super.postExecution(result); super.postExecution(result);
if (result.component1() instanceof PatternIota patternIota) {
var packet = new MsgNewSpiralPatternsS2C(
this.caster.getUUID(), List.of(patternIota.getPattern()), Integer.MAX_VALUE
);
IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet);
IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet);
}
// we always want to play this sound one at a time // we always want to play this sound one at a time
var sound = result.getSound().sound(); var sound = result.getSound().sound();
if (sound != null) { if (sound != null) {
@ -111,6 +118,15 @@ public class StaffCastEnv extends PlayerBasedCastEnv {
IXplatAbstractions.INSTANCE.sendPacketToPlayer(sender, IXplatAbstractions.INSTANCE.sendPacketToPlayer(sender,
new MsgNewSpellPatternS2C(clientInfo, resolvedPatterns.size() - 1)); new MsgNewSpellPatternS2C(clientInfo, resolvedPatterns.size() - 1));
IMessage packet;
if (clientInfo.isStackClear()) {
packet = new MsgClearSpiralPatternsS2C(sender.getUUID());
} else {
packet = new MsgNewSpiralPatternsS2C(sender.getUUID(), List.of(msg.pattern()), Integer.MAX_VALUE);
}
IXplatAbstractions.INSTANCE.sendPacketToPlayer(sender, packet);
IXplatAbstractions.INSTANCE.sendPacketTracking(sender, packet);
if (clientInfo.getResolutionType().getSuccess()) { if (clientInfo.getResolutionType().getSuccess()) {
// Somehow we lost spraying particles on each new pattern, so do it here // Somehow we lost spraying particles on each new pattern, so do it here
// this also nicely prevents particle spam on trinkets // this also nicely prevents particle spam on trinkets

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.api.casting.eval.sideeffects
import at.petrak.hexcasting.api.casting.ParticleSpray import at.petrak.hexcasting.api.casting.ParticleSpray
import at.petrak.hexcasting.api.casting.RenderedSpell import at.petrak.hexcasting.api.casting.RenderedSpell
import at.petrak.hexcasting.api.casting.eval.env.PlayerBasedCastEnv
import at.petrak.hexcasting.api.casting.eval.vm.CastingVM import at.petrak.hexcasting.api.casting.eval.vm.CastingVM
import at.petrak.hexcasting.api.casting.mishaps.Mishap import at.petrak.hexcasting.api.casting.mishaps.Mishap
import at.petrak.hexcasting.api.mod.HexStatistics import at.petrak.hexcasting.api.mod.HexStatistics
@ -36,7 +37,7 @@ sealed class OperatorSideEffect {
) : ) :
OperatorSideEffect() { OperatorSideEffect() {
override fun performEffect(harness: CastingVM): Boolean { override fun performEffect(harness: CastingVM): Boolean {
this.spell.cast(harness.env) this.spell.cast(harness.env, harness.image)?.let { harness.image = it }
if (awardStat) if (awardStat)
harness.env.caster?.awardStat(HexStatistics.SPELLS_CAST) harness.env.caster?.awardStat(HexStatistics.SPELLS_CAST)
@ -44,9 +45,9 @@ sealed class OperatorSideEffect {
} }
} }
data class ConsumeMedia(val amount: Int) : OperatorSideEffect() { data class ConsumeMedia(val amount: Long) : OperatorSideEffect() {
override fun performEffect(harness: CastingVM): Boolean { override fun performEffect(harness: CastingVM): Boolean {
val leftoverMedia = harness.env.extractMedia(this.amount.toLong()) val leftoverMedia = harness.env.extractMedia(this.amount)
return leftoverMedia > 0 return leftoverMedia > 0
} }
} }

View file

@ -80,11 +80,12 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
// ALSO TODO need to add reader macro-style things // ALSO TODO need to add reader macro-style things
try { try {
this.handleParentheses(iota)?.let { (data, resolutionType) -> this.handleParentheses(iota)?.let { (data, resolutionType) ->
return@executeInner CastResult(continuation, data, listOf(), resolutionType, HexEvalSounds.NORMAL_EXECUTE) return@executeInner CastResult(iota, continuation, data, listOf(), resolutionType, HexEvalSounds.NORMAL_EXECUTE)
} }
} catch (e: MishapTooManyCloseParens) { } catch (e: MishapTooManyCloseParens) {
// This is ridiculous and needs to be fixed // This is ridiculous and needs to be fixed
return CastResult( return CastResult(
iota,
continuation, continuation,
null, null,
listOf( listOf(
@ -106,6 +107,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
// This means something very bad has happened // This means something very bad has happened
exception.printStackTrace() exception.printStackTrace()
return CastResult( return CastResult(
iota,
continuation, continuation,
null, null,
listOf( listOf(

View file

@ -3,14 +3,12 @@ package at.petrak.hexcasting.api.casting.eval.vm
import at.petrak.hexcasting.api.casting.SpellList import at.petrak.hexcasting.api.casting.SpellList
import at.petrak.hexcasting.api.casting.eval.CastResult import at.petrak.hexcasting.api.casting.eval.CastResult
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.utils.getList import at.petrak.hexcasting.common.lib.hex.HexContinuationTypes
import at.petrak.hexcasting.api.utils.hasList
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
// TODO this should probably be a registry too
/** /**
* A single frame of evaluation during the execution of a spell. * A single frame of evaluation during the execution of a spell.
* *
@ -24,7 +22,7 @@ import net.minecraft.server.level.ServerLevel
* Once the stack of frames is empty, there are no more computations to run, so we're done. * Once the stack of frames is empty, there are no more computations to run, so we're done.
* *
*/ */
sealed interface ContinuationFrame { interface ContinuationFrame {
/** /**
* Step the evaluation forward once. * Step the evaluation forward once.
* For Evaluate, this consumes one pattern; for ForEach this queues the next iteration of the outer loop. * For Evaluate, this consumes one pattern; for ForEach this queues the next iteration of the outer loop.
@ -49,34 +47,62 @@ sealed interface ContinuationFrame {
*/ */
fun size(): Int fun size(): Int
val type: Type<*>
interface Type<U : ContinuationFrame> {
fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): U?
}
companion object { companion object {
/**
* Takes a tag containing the ContinuationFrame.Type resourcelocation and the serialized continuation frame, and returns
* the deserialized continuation frame.
*/
@JvmStatic @JvmStatic
fun fromNBT(tag: CompoundTag, world: ServerLevel): ContinuationFrame { fun fromNBT(tag: CompoundTag, world: ServerLevel): ContinuationFrame {
return when (tag.getString("type")) { val type = getTypeFromTag(tag) ?: return FrameEvaluate(SpellList.LList(0, listOf()), false)
"evaluate" -> FrameEvaluate(
HexIotaTypes.LIST.deserialize(
tag.getList("patterns", Tag.TAG_COMPOUND),
world
)!!.list,
tag.getBoolean("isMetacasting")
)
"end" -> FrameFinishEval return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { type.deserializeFromNBT(it, world) }
"foreach" -> FrameForEach( ?: FrameEvaluate(SpellList.LList(0, listOf()), false)
HexIotaTypes.LIST.deserialize(tag.getList("data", Tag.TAG_COMPOUND), world)!!.list, }
HexIotaTypes.LIST.deserialize(tag.getList("code", Tag.TAG_COMPOUND), world)!!.list,
if (tag.hasList("base", Tag.TAG_COMPOUND))
HexIotaTypes.LIST.deserialize(tag.getList("base", Tag.TAG_COMPOUND), world)!!.list.toList()
else
null,
HexIotaTypes.LIST.deserialize(
tag.getList("accumulator", Tag.TAG_COMPOUND),
world
)!!.list.toMutableList()
)
else -> FrameEvaluate(SpellList.LList(0, listOf()), false) /**
* Takes a continuation frame and serializes it along with its type.
*/
@JvmStatic
fun toNBT(frame: ContinuationFrame): CompoundTag {
val type = frame.type
val typeId = HexContinuationTypes.REGISTRY.getKey(type)
?: throw IllegalStateException(
"Tried to serialize an unregistered continuation type. Continuation: " + frame
+ " ; Type" + type.javaClass.typeName)
val data = frame.serializeToNBT()
val out = CompoundTag()
out.putString(HexContinuationTypes.KEY_TYPE, typeId.toString())
out.put(HexContinuationTypes.KEY_DATA, data)
return out
}
/**
* This method attempts to find the type from the `type` key.
* See [ContinuationFrame.serializeToNBT] for the storage format.
*
* @return `null` if it cannot get the type.
*/
private fun getTypeFromTag(tag: CompoundTag): Type<*>? {
if (!tag.contains(HexContinuationTypes.KEY_TYPE, Tag.TAG_STRING.toInt())) {
return null
} }
val typeKey = tag.getString(HexContinuationTypes.KEY_TYPE)
if (!ResourceLocation.isValidResourceLocation(typeKey)) {
return null
}
val typeLoc = ResourceLocation(typeKey)
return HexContinuationTypes.REGISTRY[typeLoc]
} }
} }
} }

View file

@ -4,9 +4,14 @@ import at.petrak.hexcasting.api.casting.SpellList
import at.petrak.hexcasting.api.casting.eval.CastResult import at.petrak.hexcasting.api.casting.eval.CastResult
import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.ListIota
import at.petrak.hexcasting.api.utils.NBTBuilder import at.petrak.hexcasting.api.utils.NBTBuilder
import at.petrak.hexcasting.api.utils.getList
import at.petrak.hexcasting.api.utils.serializeToNBT import at.petrak.hexcasting.api.utils.serializeToNBT
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
/** /**
@ -39,15 +44,31 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont
} }
} else { } else {
// If there are no patterns (e.g. empty Hermes), just return OK. // If there are no patterns (e.g. empty Hermes), just return OK.
CastResult(continuation, null, listOf(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES) CastResult(ListIota(list), continuation, null, listOf(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES)
} }
} }
override fun serializeToNBT() = NBTBuilder { override fun serializeToNBT() = NBTBuilder {
"type" %= "evaluate"
"patterns" %= list.serializeToNBT() "patterns" %= list.serializeToNBT()
"isMetacasting" %= isMetacasting "isMetacasting" %= isMetacasting
} }
override fun size() = list.size() override fun size() = list.size()
override val type: ContinuationFrame.Type<*> = TYPE
companion object {
@JvmField
val TYPE: ContinuationFrame.Type<FrameEvaluate> = object : ContinuationFrame.Type<FrameEvaluate> {
override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): FrameEvaluate {
return FrameEvaluate(
HexIotaTypes.LIST.deserialize(
tag.getList("patterns", Tag.TAG_COMPOUND),
world
)!!.list,
tag.getBoolean("isMetacasting"))
}
}
}
} }

View file

@ -3,8 +3,10 @@ package at.petrak.hexcasting.api.casting.eval.vm
import at.petrak.hexcasting.api.casting.eval.CastResult import at.petrak.hexcasting.api.casting.eval.CastResult
import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.NullIota
import at.petrak.hexcasting.api.utils.NBTBuilder import at.petrak.hexcasting.api.utils.NBTBuilder
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
import net.minecraft.nbt.CompoundTag
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
/** /**
@ -22,6 +24,7 @@ object FrameFinishEval : ContinuationFrame {
harness: CastingVM harness: CastingVM
): CastResult { ): CastResult {
return CastResult( return CastResult(
NullIota(),
continuation, continuation,
null, null,
listOf(), listOf(),
@ -30,9 +33,14 @@ object FrameFinishEval : ContinuationFrame {
) )
} }
override fun serializeToNBT() = NBTBuilder { override fun serializeToNBT() = CompoundTag()
"type" %= "end"
}
override fun size() = 0 override fun size() = 0
@JvmField
val TYPE: ContinuationFrame.Type<FrameFinishEval> = object : ContinuationFrame.Type<FrameFinishEval> {
override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel) = FrameFinishEval
}
override val type = TYPE
} }

View file

@ -6,8 +6,13 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.casting.iota.ListIota
import at.petrak.hexcasting.api.utils.NBTBuilder import at.petrak.hexcasting.api.utils.NBTBuilder
import at.petrak.hexcasting.api.utils.getList
import at.petrak.hexcasting.api.utils.hasList
import at.petrak.hexcasting.api.utils.serializeToNBT import at.petrak.hexcasting.api.utils.serializeToNBT
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
/** /**
@ -52,8 +57,6 @@ data class FrameForEach(
// If we still have data to process... // If we still have data to process...
val (stackTop, newImage, newCont) = if (data.nonEmpty) { val (stackTop, newImage, newCont) = if (data.nonEmpty) {
// Increment the evaluation depth,
// push the next datum to the top of the stack, // push the next datum to the top of the stack,
val cont2 = continuation val cont2 = continuation
// put the next Thoth object back on the stack for the next Thoth cycle, // put the next Thoth object back on the stack for the next Thoth cycle,
@ -68,6 +71,7 @@ data class FrameForEach(
val tStack = stack.toMutableList() val tStack = stack.toMutableList()
tStack.add(stackTop) tStack.add(stackTop)
return CastResult( return CastResult(
ListIota(code),
newCont, newCont,
newImage.copy(stack = tStack), newImage.copy(stack = tStack),
listOf(), listOf(),
@ -77,7 +81,6 @@ data class FrameForEach(
} }
override fun serializeToNBT() = NBTBuilder { override fun serializeToNBT() = NBTBuilder {
"type" %= "foreach"
"data" %= data.serializeToNBT() "data" %= data.serializeToNBT()
"code" %= code.serializeToNBT() "code" %= code.serializeToNBT()
if (baseStack != null) if (baseStack != null)
@ -86,4 +89,27 @@ data class FrameForEach(
} }
override fun size() = data.size() + code.size() + acc.size + (baseStack?.size ?: 0) override fun size() = data.size() + code.size() + acc.size + (baseStack?.size ?: 0)
override val type: ContinuationFrame.Type<*> = TYPE
companion object {
@JvmField
val TYPE: ContinuationFrame.Type<FrameForEach> = object : ContinuationFrame.Type<FrameForEach> {
override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): FrameForEach {
return FrameForEach(
HexIotaTypes.LIST.deserialize(tag.getList("data", Tag.TAG_COMPOUND), world)!!.list,
HexIotaTypes.LIST.deserialize(tag.getList("code", Tag.TAG_COMPOUND), world)!!.list,
if (tag.hasList("base", Tag.TAG_COMPOUND))
HexIotaTypes.LIST.deserialize(tag.getList("base", Tag.TAG_COMPOUND), world)!!.list.toList()
else
null,
HexIotaTypes.LIST.deserialize(
tag.getList("accumulator", Tag.TAG_COMPOUND),
world
)!!.list.toMutableList()
)
}
}
}
} }

View file

@ -23,7 +23,7 @@ sealed interface SpellContinuation {
var self = this var self = this
val frames = mutableListOf<CompoundTag>() val frames = mutableListOf<CompoundTag>()
while (self is NotDone) { while (self is NotDone) {
frames.add(self.frame.serializeToNBT()) frames.add(ContinuationFrame.toNBT(self.frame))
self = self.next self = self.next
} }
return frames return frames

View file

@ -48,7 +48,7 @@ public class ContinuationIota extends Iota {
@Override @Override
public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) { public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) {
return new CastResult(this.getContinuation(), vm.getImage(), List.of(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES); return new CastResult(this, this.getContinuation(), vm.getImage(), List.of(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES);
} }
@Override @Override

View file

@ -54,17 +54,17 @@ public abstract class Iota {
*/ */
public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) { public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) {
return new CastResult( return new CastResult(
this,
continuation, continuation,
null, null, // Should never matter
List.of( List.of(
new OperatorSideEffect.DoMishap( new OperatorSideEffect.DoMishap(
new MishapUnescapedValue(this), new MishapUnescapedValue(this),
new Mishap.Context(new HexPattern(HexDir.WEST, List.of()), null) new Mishap.Context(new HexPattern(HexDir.WEST, List.of()), null)
) )
), // Should never matter ),
ResolvedPatternType.INVALID, ResolvedPatternType.INVALID,
HexEvalSounds.MISHAP HexEvalSounds.MISHAP);
);
} }
/** /**
@ -78,7 +78,7 @@ public abstract class Iota {
* This method is called to determine whether the iota is above the max serialisation depth/serialisation count * This method is called to determine whether the iota is above the max serialisation depth/serialisation count
* limits. It should return every "iota" that is a subelement of this iota. * limits. It should return every "iota" that is a subelement of this iota.
* For example, if you implemented a Map&lt;Iota, Iota&gt;, then it should be an iterable over the keys *and* * For example, if you implemented a Map&lt;Iota, Iota&gt;, then it should be an iterable over the keys *and*
* values of the map. If you implemented a typed List&lt;Double&gt; iota for some reason, you should instad override * values of the map. If you implemented a typed List&lt;Double&gt; iota for some reason, you should instead override
* {@link Iota#size}. * {@link Iota#size}.
*/ */
public @Nullable Iterable<Iota> subIotas() { public @Nullable Iterable<Iota> subIotas() {

View file

@ -17,6 +17,7 @@ import net.minecraft.util.FormattedCharSequence;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Objects; import java.util.Objects;
// Take notes from ForgeRegistryEntry // Take notes from ForgeRegistryEntry
@ -64,7 +65,7 @@ public abstract class IotaType<T extends Iota> {
} }
// We check if it's too big on serialization; if it is we just return a garbage. // We check if it's too big on serialization; if it is we just return a garbage.
if (iota instanceof ListIota listIota && isTooLargeToSerialize(listIota.getList())) { if (isTooLargeToSerialize(List.of(iota), 0)) {
// Garbage will never be too large so we just recurse // Garbage will never be too large so we just recurse
return serialize(new GarbageIota()); return serialize(new GarbageIota());
} }
@ -76,12 +77,16 @@ public abstract class IotaType<T extends Iota> {
} }
public static boolean isTooLargeToSerialize(Iterable<Iota> examinee) { public static boolean isTooLargeToSerialize(Iterable<Iota> examinee) {
return isTooLargeToSerialize(examinee, 1);
}
private static boolean isTooLargeToSerialize(Iterable<Iota> examinee, int startingCount) {
// We don't recurse here, just a work queue (or work stack, if we liked.) // We don't recurse here, just a work queue (or work stack, if we liked.)
// Each element is a found sub-iota, and how deep it is. // Each element is a found sub-iota, and how deep it is.
// //
// TODO: is it worth trying to cache the depth and size statically on a SpellList. // TODO: is it worth trying to cache the depth and size statically on a SpellList.
var listsToExamine = new ArrayDeque<>(Collections.singleton(new Pair<>(examinee, 0))); var listsToExamine = new ArrayDeque<>(Collections.singleton(new Pair<>(examinee, 0)));
int totalEltsFound = 1; // count the first list int totalEltsFound = startingCount; // count the first list
while (!listsToExamine.isEmpty()) { while (!listsToExamine.isEmpty()) {
var iotaPair = listsToExamine.removeFirst(); var iotaPair = listsToExamine.removeFirst();
var sublist = iotaPair.getFirst(); var sublist = iotaPair.getFirst();

View file

@ -115,21 +115,21 @@ public class PatternIota extends Iota {
var sideEffects = result.getSideEffects(); var sideEffects = result.getSideEffects();
return new CastResult( return new CastResult(
this,
cont2, cont2,
result.getNewImage(), result.getNewImage(),
sideEffects, sideEffects,
ResolvedPatternType.EVALUATED, ResolvedPatternType.EVALUATED,
result.getSound() result.getSound());
);
} catch (Mishap mishap) { } catch (Mishap mishap) {
return new CastResult( return new CastResult(
this,
continuation, continuation,
null, null,
List.of(new OperatorSideEffect.DoMishap(mishap, new Mishap.Context(this.getPattern(), castedName))), List.of(new OperatorSideEffect.DoMishap(mishap, new Mishap.Context(this.getPattern(), castedName))),
mishap.resolutionType(vm.getEnv()), mishap.resolutionType(vm.getEnv()),
HexEvalSounds.MISHAP HexEvalSounds.MISHAP);
);
} }
} }

View file

@ -12,13 +12,8 @@ class MishapAlreadyBrainswept(val mob: Mob) : Mishap() {
override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment =
dyeColor(DyeColor.GREEN) dyeColor(DyeColor.GREEN)
<<<<<<< HEAD
override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
mob.hurt(HexDamageSources.overcastDamageFrom(env.caster), mob.health)
=======
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) { override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
mob.hurt(mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.caster), mob.health) mob.hurt(mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.caster), mob.health)
>>>>>>> talia-1.20/1.20.1
} }
override fun particleSpray(ctx: CastingEnvironment) = override fun particleSpray(ctx: CastingEnvironment) =

View file

@ -16,13 +16,8 @@ class MishapBadBlock(val pos: BlockPos, val expected: Component) : Mishap() {
override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment =
dyeColor(DyeColor.LIME) dyeColor(DyeColor.LIME)
<<<<<<< HEAD
override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
env.world.explode(null, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, 0.25f, Explosion.BlockInteraction.NONE)
=======
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) { override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
ctx.world.explode(null, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, 0.25f, Level.ExplosionInteraction.NONE) ctx.world.explode(null, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, 0.25f, Level.ExplosionInteraction.NONE)
>>>>>>> talia-1.20/1.20.1
} }
override fun particleSpray(ctx: CastingEnvironment) = override fun particleSpray(ctx: CastingEnvironment) =

View file

@ -14,13 +14,8 @@ class MishapBadBrainsweep(val mob: Mob, val pos: BlockPos) : Mishap() {
override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment =
dyeColor(DyeColor.GREEN) dyeColor(DyeColor.GREEN)
<<<<<<< HEAD
override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
trulyHurt(mob, HexDamageSources.overcastDamageFrom(env.caster), 1f)
=======
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) { override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
trulyHurt(mob, mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.caster), 1f) trulyHurt(mob, mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.caster), 1f)
>>>>>>> talia-1.20/1.20.1
} }
override fun particleSpray(ctx: CastingEnvironment): ParticleSpray { override fun particleSpray(ctx: CastingEnvironment): ParticleSpray {

View file

@ -0,0 +1,61 @@
package at.petrak.hexcasting.api.client
import at.petrak.hexcasting.api.casting.math.HexPattern
import kotlin.math.min
class ClientCastingStack {
private var patterns = ArrayList<HexPatternRenderHolder>()
private var toRemove = mutableSetOf<HexPatternRenderHolder>()
private var toAdd = ArrayList<HexPatternRenderHolder>()
fun addPattern(pattern: HexPattern?, lifetime: Int) {
if (pattern == null) return
if (patterns.stream().anyMatch { patternRenderHolder -> patternRenderHolder.pattern.hashCode() == pattern.hashCode() }) {
return
}
if (patterns.size > 100) {
patterns.removeAt(0)
}
patterns.add(HexPatternRenderHolder(pattern, lifetime))
}
fun slowClear() {
patterns.forEach { it.lifetime = min(it.lifetime, 140) }
}
fun getPatterns(): List<HexPatternRenderHolder> {
return patterns
}
fun getPattern(index: Int): HexPattern? = patterns.getOrNull(index)?.pattern
fun getPatternHolder(index: Int): HexPatternRenderHolder? = patterns.getOrNull(index)
fun size(): Int {
return patterns.size
}
fun tick() {
// tick without getting a cme
toAdd.forEach { pattern ->
if (patterns.size > 100) {
patterns.removeAt(0)
}
patterns.add(pattern)
}
toAdd.clear()
patterns.forEach { pattern ->
pattern.tick()
if (pattern.lifetime <= 0) {
toRemove.add(pattern)
}
}
patterns.removeAll(toRemove)
toRemove.clear()
}
}

View file

@ -0,0 +1,86 @@
@file:JvmName("ClientRenderHelper")
package at.petrak.hexcasting.api.client
import at.petrak.hexcasting.client.ClientTickCounter
import at.petrak.hexcasting.client.render.drawLineSeq
import at.petrak.hexcasting.client.render.findDupIndices
import at.petrak.hexcasting.client.render.makeZappy
import at.petrak.hexcasting.client.render.screenCol
import at.petrak.hexcasting.xplat.IClientXplatAbstractions
import at.petrak.hexcasting.xplat.IXplatAbstractions
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import kotlin.math.abs
import kotlin.math.cos
import kotlin.math.floor
import kotlin.math.sin
fun renderCastingStack(ps: PoseStack, player: Player, pticks: Float) {
val stack = IClientXplatAbstractions.INSTANCE.getClientCastingStack(player)
for (k in 0 until stack.getPatterns().size) {
val patternRenderHolder = stack.getPatternHolder(k) ?: continue
val pattern = patternRenderHolder.pattern
val lifetime = patternRenderHolder.lifetime
val lifetimeOffset = if (lifetime <= 5f) (5f - lifetime) / 5f else 0f
ps.pushPose()
ps.mulPose(Axis.YP.rotationDegrees(((player.level().gameTime + pticks) * (sin(k * 12.543565f) * 3.4f) * (k / 12.43f) % 360 + (1 + k) * 45f)))
ps.translate(0.0, 1 + sin(k.toDouble()) * 0.75, 0.75 + cos((k / 8.0)) * 0.25 + cos((player.level().gameTime + pticks) / (7 + k / 4)) * 0.065)
ps.scale(1 / 24f * (1 - lifetimeOffset), 1 / 24f * (1 - lifetimeOffset), 1 / 24f * (1 - lifetimeOffset))
ps.translate(0.0, floor((k / 8.0)), 0.0)
ps.translate(0.0, sin((player.level().gameTime + pticks) / (7.0 + k / 8.0)), 0.0)
val oldShader = RenderSystem.getShader()
RenderSystem.setShader { GameRenderer.getPositionColorShader() }
RenderSystem.enableDepthTest()
RenderSystem.disableCull()
val com1 = pattern.getCenter(1f)
val lines1 = pattern.toLines(1f, Vec2.ZERO)
var maxDx = -1f
var maxDy = -1f
for (line in lines1) {
val dx = abs(line.x - com1.x)
if (dx > maxDx) {
maxDx = dx
}
val dy = abs(line.y - com1.y)
if (dy > maxDy) {
maxDy = dy
}
}
val scale = 3.8f.coerceAtMost((16 / 2.5f / maxDx).coerceAtMost(16 / 2.5f / maxDy))
val com2 = pattern.getCenter(scale)
val lines2 = pattern.toLines(scale, com2.negated()).toMutableList()
for (i in lines2.indices) {
val line = lines2[i]
lines2[i] = Vec2(line.x, -line.y)
}
val variance = 0.65f
val speed = 0.1f
val stupidHash = player.hashCode().toDouble()
val zappy: List<Vec2> = makeZappy(lines2, findDupIndices(pattern.positions()),
5, variance, speed, 0.2f, 0f,
1f, stupidHash)
val outer: Int = IXplatAbstractions.INSTANCE.getPigment(player).colorProvider.getColor(
ClientTickCounter.getTotal() / 2f,
patternRenderHolder.getColourPos(player.random))
val rgbOnly = outer and 0x00FFFFFF
var newAlpha = outer ushr 24
if (lifetime <= 60) {
newAlpha = floor((lifetime / 60f * 255).toDouble()).toInt()
}
val newARGB = newAlpha shl 24 or rgbOnly
val inner: Int = screenCol(newARGB)
drawLineSeq(ps.last().pose(), zappy, 0.35f, 0f, newARGB, newARGB)
drawLineSeq(ps.last().pose(), zappy, 0.14f, 0.01f, inner, inner)
ps.popPose()
RenderSystem.setShader { oldShader }
RenderSystem.enableCull()
}
}

View file

@ -0,0 +1,19 @@
package at.petrak.hexcasting.api.client
import at.petrak.hexcasting.api.casting.math.HexPattern
import net.minecraft.util.RandomSource
import net.minecraft.world.phys.Vec3
data class HexPatternRenderHolder(val pattern: HexPattern, var lifetime: Int) {
private var colourPos: Vec3? = null
fun getColourPos(random: RandomSource): Vec3 {
return colourPos ?: let {
Vec3(random.nextDouble(), random.nextDouble(), random.nextDouble()).normalize().scale(3.0).also { colourPos = it }
}
}
fun tick() {
lifetime -= 1
}
}

View file

@ -1,10 +1,10 @@
package at.petrak.hexcasting.api.misc; package at.petrak.hexcasting.api.misc;
public final class MediaConstants { public final class MediaConstants {
public static final int DUST_UNIT = 10000; public static final long DUST_UNIT = 10000;
public static final int SHARD_UNIT = 5 * DUST_UNIT; public static final long SHARD_UNIT = 5 * DUST_UNIT;
public static final int CRYSTAL_UNIT = 10 * DUST_UNIT; public static final long CRYSTAL_UNIT = 10 * DUST_UNIT;
public static final int QUENCHED_SHARD_UNIT = 3 * CRYSTAL_UNIT; public static final long QUENCHED_SHARD_UNIT = 3 * CRYSTAL_UNIT;
public static final int QUENCHED_BLOCK_UNIT = 4 * QUENCHED_SHARD_UNIT; public static final long QUENCHED_BLOCK_UNIT = 4 * QUENCHED_SHARD_UNIT;
} }

View file

@ -13,11 +13,11 @@ import java.util.List;
public class HexConfig { public class HexConfig {
public interface CommonConfigAccess { public interface CommonConfigAccess {
int dustMediaAmount(); long dustMediaAmount();
int shardMediaAmount(); long shardMediaAmount();
int chargedCrystalMediaAmount(); long chargedCrystalMediaAmount();
double mediaToHealthRate(); double mediaToHealthRate();
@ -27,9 +27,9 @@ public class HexConfig {
int artifactCooldown(); int artifactCooldown();
int DEFAULT_DUST_MEDIA_AMOUNT = MediaConstants.DUST_UNIT; long DEFAULT_DUST_MEDIA_AMOUNT = MediaConstants.DUST_UNIT;
int DEFAULT_SHARD_MEDIA_AMOUNT = MediaConstants.SHARD_UNIT; long DEFAULT_SHARD_MEDIA_AMOUNT = MediaConstants.SHARD_UNIT;
int DEFAULT_CHARGED_MEDIA_AMOUNT = MediaConstants.CRYSTAL_UNIT; long DEFAULT_CHARGED_MEDIA_AMOUNT = MediaConstants.CRYSTAL_UNIT;
double DEFAULT_MEDIA_TO_HEALTH_RATE = 2 * MediaConstants.CRYSTAL_UNIT / 20.0; double DEFAULT_MEDIA_TO_HEALTH_RATE = 2 * MediaConstants.CRYSTAL_UNIT / 20.0;
int DEFAULT_CYPHER_COOLDOWN = 8; int DEFAULT_CYPHER_COOLDOWN = 8;

View file

@ -11,9 +11,9 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc;
public class HexStatistics { public class HexStatistics {
public static final ResourceLocation MEDIA_USED = makeCustomStat("media_used", public static final ResourceLocation MEDIA_USED = makeCustomStat("media_used",
mediamount -> StatFormatter.DEFAULT.format(mediamount / MediaConstants.DUST_UNIT)); mediamount -> StatFormatter.DEFAULT.format((int) (mediamount / MediaConstants.DUST_UNIT)));
public static final ResourceLocation MEDIA_OVERCAST = makeCustomStat("media_overcast", public static final ResourceLocation MEDIA_OVERCAST = makeCustomStat("media_overcast",
mediamount -> StatFormatter.DEFAULT.format(mediamount / MediaConstants.DUST_UNIT)); mediamount -> StatFormatter.DEFAULT.format((int) (mediamount / MediaConstants.DUST_UNIT)));
public static final ResourceLocation PATTERNS_DRAWN = makeCustomStat("patterns_drawn", StatFormatter.DEFAULT); public static final ResourceLocation PATTERNS_DRAWN = makeCustomStat("patterns_drawn", StatFormatter.DEFAULT);
public static final ResourceLocation SPELLS_CAST = makeCustomStat("spells_cast", StatFormatter.DEFAULT); public static final ResourceLocation SPELLS_CAST = makeCustomStat("spells_cast", StatFormatter.DEFAULT);

View file

@ -27,7 +27,6 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.joml.Quaternionf;
import org.joml.Vector3f; import org.joml.Vector3f;
import java.util.List; import java.util.List;
@ -85,8 +84,8 @@ public class HexAdditionalRenderers {
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
RenderSystem.lineWidth(5f); RenderSystem.lineWidth(5f);
var colorizer = IXplatAbstractions.INSTANCE.getPigment(owner); var pigment = IXplatAbstractions.INSTANCE.getPigment(owner);
var colProvider = colorizer.getColorProvider(); var colProvider = pigment.getColorProvider();
BiConsumer<float[], float[]> v = (l, r) -> { BiConsumer<float[], float[]> v = (l, r) -> {
int lcolor = colProvider.getColor(time, new Vec3(l[0], l[1], l[2])), int lcolor = colProvider.getColor(time, new Vec3(l[0], l[1], l[2])),
rcolor = colProvider.getColor(time, new Vec3(r[0], r[1], r[2])); rcolor = colProvider.getColor(time, new Vec3(r[0], r[1], r[2]));

View file

@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.math.HexPattern
import at.petrak.hexcasting.api.mod.HexConfig import at.petrak.hexcasting.api.mod.HexConfig
import at.petrak.hexcasting.api.utils.* import at.petrak.hexcasting.api.utils.*
import at.petrak.hexcasting.client.ClientTickCounter import at.petrak.hexcasting.client.ClientTickCounter
import at.petrak.hexcasting.client.gui.GuiSpellcasting
import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.PoseStack import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.Tesselator import com.mojang.blaze3d.vertex.Tesselator
@ -85,7 +86,7 @@ fun drawLineSeq(
Mth.atan2((prev.x * next.y - prev.y * next.x).toDouble(), (prev.x * next.x + prev.y * next.y).toDouble()) Mth.atan2((prev.x * next.y - prev.y * next.x).toDouble(), (prev.x * next.x + prev.y * next.y).toDouble())
.toFloat() .toFloat()
joinAngles[i - 1] = angle joinAngles[i - 1] = angle
val clamp = Math.min(prev.length(), next.length()) / (width * 0.5f) val clamp = prev.length().coerceAtMost(next.length()) / (width * 0.5f)
joinOffsets[i - 1] = Mth.clamp(Mth.sin(angle) / (1 + Mth.cos(angle)), -clamp, clamp) joinOffsets[i - 1] = Mth.clamp(Mth.sin(angle) / (1 + Mth.cos(angle)), -clamp, clamp)
} }

View file

@ -32,8 +32,8 @@ public class BlockBooleanDirectrix extends BlockCircleComponent {
public static final DirectionProperty FACING = BlockStateProperties.FACING; public static final DirectionProperty FACING = BlockStateProperties.FACING;
public static final EnumProperty<State> STATE = EnumProperty.create("state", State.class); public static final EnumProperty<State> STATE = EnumProperty.create("state", State.class);
public BlockBooleanDirectrix(Properties p_49795_) { public BlockBooleanDirectrix(Properties properties) {
super(p_49795_); super(properties);
this.registerDefaultState(this.stateDefinition.any() this.registerDefaultState(this.stateDefinition.any()
.setValue(ENERGIZED, false) .setValue(ENERGIZED, false)
.setValue(STATE, State.NEITHER) .setValue(STATE, State.NEITHER)
@ -57,9 +57,11 @@ public class BlockBooleanDirectrix extends BlockCircleComponent {
return new ControlFlow.Stop(); return new ControlFlow.Stop();
} }
world.setBlockAndUpdate(pos, bs.setValue(STATE, biota.getBool() ? State.TRUE : State.FALSE));
var outputDir = biota.getBool() var outputDir = biota.getBool()
? bs.getValue(FACING) ? bs.getValue(FACING).getOpposite()
: bs.getValue(FACING).getOpposite(); : bs.getValue(FACING);
var imageOut = imageIn.copy(stack, imageIn.getParenCount(), imageIn.getParenthesized(), var imageOut = imageIn.copy(stack, imageIn.getParenCount(), imageIn.getParenthesized(),
imageIn.getEscapeNext(), imageIn.getOpsConsumed(), imageIn.getUserData()); imageIn.getEscapeNext(), imageIn.getOpsConsumed(), imageIn.getUserData());
@ -87,6 +89,13 @@ public class BlockBooleanDirectrix extends BlockCircleComponent {
return 0.5f; return 0.5f;
} }
@Override
public BlockState endEnergized(BlockPos pos, BlockState bs, Level world) {
var newState = bs.setValue(ENERGIZED, false).setValue(STATE, State.NEITHER);
world.setBlockAndUpdate(pos, newState);
return newState;
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) { protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder); super.createBlockStateDefinition(builder);

View file

@ -12,7 +12,7 @@ import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicRecord
object OpAkashicRead : ConstMediaAction { object OpAkashicRead : ConstMediaAction {
override val argc = 2 override val argc = 2
override val mediaCost = MediaConstants.DUST_UNIT override val mediaCost: Long = MediaConstants.DUST_UNIT
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> { override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
val pos = args.getBlockPos(0, argc) val pos = args.getBlockPos(0, argc)

View file

@ -14,7 +14,7 @@ import net.minecraft.world.phys.Vec3
object OpBlockAxisRaycast : ConstMediaAction { object OpBlockAxisRaycast : ConstMediaAction {
override val argc = 2 override val argc = 2
override val mediaCost = MediaConstants.DUST_UNIT / 100 override val mediaCost: Long = MediaConstants.DUST_UNIT / 100
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> { override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
val origin = args.getVec3(0, argc) val origin = args.getVec3(0, argc)
val look = args.getVec3(1, argc) val look = args.getVec3(1, argc)

View file

@ -14,7 +14,7 @@ import net.minecraft.world.phys.Vec3
object OpBlockRaycast : ConstMediaAction { object OpBlockRaycast : ConstMediaAction {
override val argc = 2 override val argc = 2
override val mediaCost = MediaConstants.DUST_UNIT / 100 override val mediaCost: Long = MediaConstants.DUST_UNIT / 100
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> { override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
val origin = args.getVec3(0, argc) val origin = args.getVec3(0, argc)
val look = args.getVec3(1, argc) val look = args.getVec3(1, argc)

View file

@ -8,12 +8,16 @@ import at.petrak.hexcasting.api.casting.getVec3
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.casting.iota.NullIota
import at.petrak.hexcasting.api.misc.MediaConstants import at.petrak.hexcasting.api.misc.MediaConstants
import net.minecraft.world.entity.projectile.ProjectileUtil import net.minecraft.world.entity.Entity
import net.minecraft.world.level.Level
import net.minecraft.world.phys.AABB import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.EntityHitResult
import net.minecraft.world.phys.Vec3
import java.util.function.Predicate
object OpEntityRaycast : ConstMediaAction { object OpEntityRaycast : ConstMediaAction {
override val argc = 2 override val argc = 2
override val mediaCost = MediaConstants.DUST_UNIT / 100 override val mediaCost: Long = MediaConstants.DUST_UNIT / 100
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> { override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
val origin = args.getVec3(0, argc) val origin = args.getVec3(0, argc)
val look = args.getVec3(1, argc) val look = args.getVec3(1, argc)
@ -21,8 +25,9 @@ object OpEntityRaycast : ConstMediaAction {
env.assertVecInRange(origin) env.assertVecInRange(origin)
val entityHitResult = ProjectileUtil.getEntityHitResult( val entityHitResult = getEntityHitResult(
env.caster, env.caster,
env.world,
origin, origin,
endp, endp,
AABB(origin, endp), AABB(origin, endp),
@ -36,4 +41,44 @@ object OpEntityRaycast : ConstMediaAction {
listOf(NullIota()) listOf(NullIota())
} }
} }
fun getEntityHitResult(
entity: Entity?, level: Level, startPos: Vec3, endPos: Vec3,
aabb: AABB, isValid: Predicate<Entity>, maxSqrLength: Double): EntityHitResult? {
var sqrLength = maxSqrLength
var hitEntity: Entity? = null
var hitPos: Vec3? = null
val allValidInAABB: Iterator<*> = level.getEntities(entity, aabb, isValid).iterator()
while (allValidInAABB.hasNext()) {
val nextEntity = allValidInAABB.next() as Entity
val hitBox = nextEntity.boundingBox.inflate(nextEntity.pickRadius.toDouble())
val overlapBox = hitBox.clip(startPos, endPos)
if (hitBox.contains(startPos)) {
if (sqrLength >= 0.0) {
hitEntity = nextEntity
hitPos = overlapBox.orElse(startPos)
sqrLength = 0.0
}
} else if (overlapBox.isPresent) {
val maybePos = overlapBox.get()
val sqrDist = startPos.distanceToSqr(maybePos)
if (sqrDist < sqrLength || sqrLength == 0.0) {
if (nextEntity.rootVehicle === entity?.rootVehicle) {
if (sqrLength == 0.0) {
hitEntity = nextEntity
hitPos = maybePos
}
} else {
hitEntity = nextEntity
hitPos = maybePos
sqrLength = sqrDist
}
}
}
}
return if (hitEntity == null) {
null
} else EntityHitResult(hitEntity, hitPos!!) // hitEntity != null <=> hitPos != null
}
} }

View file

@ -39,7 +39,7 @@ object OpAddMotion : SpellAction {
motion motion
return SpellAction.Result( return SpellAction.Result(
Spell(target, shrunkMotion), Spell(target, shrunkMotion),
(motionForCost * MediaConstants.DUST_UNIT).toInt(), (motionForCost * MediaConstants.DUST_UNIT).toLong(),
listOf( listOf(
ParticleSpray( ParticleSpray(
target.position().add(0.0, target.eyeHeight / 2.0, 0.0), target.position().add(0.0, target.eyeHeight / 2.0, 0.0),

View file

@ -15,7 +15,7 @@ import at.petrak.hexcasting.api.mod.HexTags
import at.petrak.hexcasting.common.casting.actions.spells.great.OpTeleport import at.petrak.hexcasting.common.casting.actions.spells.great.OpTeleport
import net.minecraft.world.entity.Entity import net.minecraft.world.entity.Entity
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
import kotlin.math.roundToInt import kotlin.math.roundToLong
object OpBlink : SpellAction { object OpBlink : SpellAction {
override val argc = 2 override val argc = 2
@ -46,7 +46,7 @@ object OpBlink : SpellAction {
return SpellAction.Result( return SpellAction.Result(
Spell(target, delta), Spell(target, delta),
(MediaConstants.SHARD_UNIT * delta.absoluteValue * 0.5).roundToInt(), (MediaConstants.SHARD_UNIT * delta.absoluteValue * 0.5).roundToLong(),
listOf( listOf(
ParticleSpray.cloud(targetMiddlePos, 2.0, 50), ParticleSpray.cloud(targetMiddlePos, 2.0, 50),
ParticleSpray.burst(targetMiddlePos.add(dvec), 2.0, 100) ParticleSpray.burst(targetMiddlePos.add(dvec), 2.0, 100)

View file

@ -17,7 +17,7 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.material.Fluid import net.minecraft.world.level.material.Fluid
import net.minecraft.world.phys.Vec3 import net.minecraft.world.phys.Vec3
class OpCreateFluid(val cost: Int, val bucket: Item, val cauldron: BlockState, val fluid: Fluid) : SpellAction { class OpCreateFluid(val cost: Long, val bucket: Item, val cauldron: BlockState, val fluid: Fluid) : SpellAction {
override val argc = 1 override val argc = 1
override fun execute( override fun execute(
args: List<Iota>, args: List<Iota>,

View file

@ -29,7 +29,7 @@ class OpExplode(val fire: Boolean) : SpellAction {
val cost = MediaConstants.DUST_UNIT * (3 * clampedStrength + if (fire) 1.0 else 0.125) val cost = MediaConstants.DUST_UNIT * (3 * clampedStrength + if (fire) 1.0 else 0.125)
return SpellAction.Result( return SpellAction.Result(
Spell(pos, strength, this.fire), Spell(pos, strength, this.fire),
cost.toInt(), cost.toLong(),
listOf(ParticleSpray.burst(pos, strength, 50)) listOf(ParticleSpray.burst(pos, strength, 50))
) )
} }

View file

@ -23,6 +23,7 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.phys.Vec3 import net.minecraft.world.phys.Vec3
import kotlin.math.max import kotlin.math.max
import kotlin.math.roundToInt import kotlin.math.roundToInt
import kotlin.math.roundToLong
class OpFlight(val type: Type) : SpellAction { class OpFlight(val type: Type) : SpellAction {
override val argc = 2 override val argc = 2
@ -38,7 +39,7 @@ class OpFlight(val type: Type) : SpellAction {
Type.LimitRange -> theArg * MediaConstants.DUST_UNIT Type.LimitRange -> theArg * MediaConstants.DUST_UNIT
// A second of flight should cost 1 shard // A second of flight should cost 1 shard
Type.LimitTime -> theArg * MediaConstants.SHARD_UNIT Type.LimitTime -> theArg * MediaConstants.SHARD_UNIT
}.roundToInt() }.roundToLong()
// Convert to ticks // Convert to ticks
return SpellAction.Result( return SpellAction.Result(

View file

@ -18,7 +18,7 @@ import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
// TODO: How to handle in circles // TODO: How to handle in circles
class OpMakePackagedSpell<T : ItemPackagedHex>(val itemType: T, val cost: Int) : SpellAction { class OpMakePackagedSpell<T : ItemPackagedHex>(val itemType: T, val cost: Long) : SpellAction {
override val argc = 2 override val argc = 2
override fun execute( override fun execute(
args: List<Iota>, args: List<Iota>,

View file

@ -10,7 +10,7 @@ import net.minecraft.world.entity.LivingEntity
class OpPotionEffect( class OpPotionEffect(
val effect: MobEffect, val effect: MobEffect,
val baseCost: Int, val baseCost: Long,
val allowPotency: Boolean, val allowPotency: Boolean,
val potencyCubic: Boolean, val potencyCubic: Boolean,
) : SpellAction { ) : SpellAction {
@ -36,7 +36,7 @@ class OpPotionEffect(
} }
return SpellAction.Result( return SpellAction.Result(
Spell(effect, target, duration, potency), Spell(effect, target, duration, potency),
cost.toInt(), cost.toLong(),
listOf(ParticleSpray.cloud(target.position().add(0.0, target.eyeHeight / 2.0, 0.0), 1.0)) listOf(ParticleSpray.cloud(target.position().add(0.0, target.eyeHeight / 2.0, 0.0), 1.0))
) )
} }

View file

@ -28,7 +28,7 @@ object OpTheOnlyReasonAnyoneDownloadedPsi : SpellAction {
return SpellAction.Result( return SpellAction.Result(
Spell(target), Spell(target),
(MediaConstants.DUST_UNIT * 1.125).toInt(), (MediaConstants.DUST_UNIT * 1.125).toLong(),
listOf(ParticleSpray.burst(Vec3.atCenterOf(BlockPos(target)), 1.0)) listOf(ParticleSpray.burst(Vec3.atCenterOf(BlockPos(target)), 1.0))
) )
} }

View file

@ -11,10 +11,10 @@ import at.petrak.hexcasting.xplat.IXplatAbstractions
object OpGetSentinelPos : ConstMediaAction { object OpGetSentinelPos : ConstMediaAction {
override val argc = 0 override val argc = 0
override val mediaCost = MediaConstants.DUST_UNIT / 10 override val mediaCost: Long = MediaConstants.DUST_UNIT / 10
override fun execute(args: List<Iota>, ctx: CastingEnvironment): List<Iota> { override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
val sentinel = IXplatAbstractions.INSTANCE.getSentinel(ctx.caster) ?: return listOf(NullIota()) val sentinel = IXplatAbstractions.INSTANCE.getSentinel(env.caster) ?: return listOf(NullIota())
if (sentinel.dimension != ctx.world.dimension()) if (sentinel.dimension != env.world.dimension())
throw MishapLocationInWrongDimension(sentinel.dimension.location()) throw MishapLocationInWrongDimension(sentinel.dimension.location())
return sentinel.position.asActionResult return sentinel.position.asActionResult
} }

View file

@ -14,7 +14,7 @@ import at.petrak.hexcasting.xplat.IXplatAbstractions
// TODO standardize "a negligible amount" of media to be 1/8 a dust // TODO standardize "a negligible amount" of media to be 1/8 a dust
object OpGetSentinelWayfind : ConstMediaAction { object OpGetSentinelWayfind : ConstMediaAction {
override val argc = 1 override val argc = 1
override val mediaCost = MediaConstants.DUST_UNIT / 10 override val mediaCost: Long = MediaConstants.DUST_UNIT / 10
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> { override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
val from = args.getVec3(0, argc) val from = args.getVec3(0, argc)

View file

@ -4,13 +4,14 @@ import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.asActionResult
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.DOUBLE import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.DOUBLE
import kotlin.math.log import kotlin.math.log
object OperatorLog : Operator(2, IotaMultiPredicate.all(IotaPredicate.ofType(DOUBLE))) { object OperatorLog : Operator(2, IotaMultiPredicate.all(IotaPredicate.ofType(DOUBLE))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> { override fun apply(iotas: Iterable<Iota>, env : CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex() val it = iotas.iterator().withIndex()
val value = it.nextDouble(arity) val value = it.nextDouble(arity)
val base = it.nextDouble(arity) val base = it.nextDouble(arity)

View file

@ -4,12 +4,13 @@ import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.asActionResult
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.* import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
object OperatorAppend : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.TRUE)) { object OperatorAppend : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.TRUE)) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> { override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex() val it = iotas.iterator().withIndex()
val list = it.nextList(arity).toMutableList() val list = it.nextList(arity).toMutableList()
list.add(it.next().value) list.add(it.next().value)

View file

@ -3,13 +3,14 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator.list
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.casting.iota.NullIota
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.* import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
import kotlin.math.roundToInt import kotlin.math.roundToInt
object OperatorIndex : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE))) { object OperatorIndex : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> { override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator() val it = iotas.iterator()
val list = downcast(it.next(), LIST).list.toMutableList() val list = downcast(it.next(), LIST).list.toMutableList()
val index = downcast(it.next(), DOUBLE).double val index = downcast(it.next(), DOUBLE).double

View file

@ -4,12 +4,13 @@ import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.asActionResult
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.* import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
object OperatorIndexOf : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.TRUE)) { object OperatorIndexOf : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.TRUE)) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> { override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex() val it = iotas.iterator().withIndex()
val list = it.nextList(arity).toList() val list = it.nextList(arity).toList()
return list.indexOf(it.next().value).asActionResult return list.indexOf(it.next().value).asActionResult

View file

@ -4,13 +4,14 @@ import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.asActionResult
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextInt import at.petrak.hexcasting.common.casting.arithmetic.operator.nextInt
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.* import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
object OperatorRemove : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE))) { object OperatorRemove : Operator(2, IotaMultiPredicate.pair(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> { override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex() val it = iotas.iterator().withIndex()
val list = it.nextList(arity).toMutableList() val list = it.nextList(arity).toMutableList()
val index = it.nextInt(arity) val index = it.nextInt(arity)

View file

@ -5,13 +5,14 @@ import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.asActionResult
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextPositiveIntUnder import at.petrak.hexcasting.common.casting.arithmetic.operator.nextPositiveIntUnder
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.* import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
object OperatorReplace : Operator(3, IotaMultiPredicate.triple(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE), IotaPredicate.TRUE)) { object OperatorReplace : Operator(3, IotaMultiPredicate.triple(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE), IotaPredicate.TRUE)) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> { override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex() val it = iotas.iterator().withIndex()
val list = it.nextList(arity) val list = it.nextList(arity)
val index = it.nextPositiveIntUnder(list.size(), arity) val index = it.nextPositiveIntUnder(list.size(), arity)

View file

@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.asActionResult
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextPositiveIntUnderInclusive import at.petrak.hexcasting.common.casting.arithmetic.operator.nextPositiveIntUnderInclusive
@ -12,7 +13,7 @@ import kotlin.math.max
import kotlin.math.min import kotlin.math.min
object OperatorSlice : Operator(3, IotaMultiPredicate.triple(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE), IotaPredicate.ofType(DOUBLE))) { object OperatorSlice : Operator(3, IotaMultiPredicate.triple(IotaPredicate.ofType(LIST), IotaPredicate.ofType(DOUBLE), IotaPredicate.ofType(DOUBLE))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> { override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex() val it = iotas.iterator().withIndex()
val list = it.nextList(arity).toList() val list = it.nextList(arity).toList()
val index0 = it.nextPositiveIntUnderInclusive(list.size, arity) val index0 = it.nextPositiveIntUnderInclusive(list.size, arity)

View file

@ -3,6 +3,7 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator.list
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.casting.iota.ListIota
import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.casting.iota.NullIota
@ -10,12 +11,11 @@ import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST
object OperatorUnCons : Operator(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST))) { object OperatorUnCons : Operator(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> { override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex() val it = iotas.iterator().withIndex()
val list = it.nextList(arity) val list = it.nextList(arity)
if (list.nonEmpty) { if (list.nonEmpty)
return listOf(ListIota(list.cdr), list.car) return listOf(ListIota(list.cdr), list.car)
}
return listOf(ListIota(list), NullIota()) return listOf(ListIota(list), NullIota())
} }
} }

View file

@ -3,6 +3,7 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator.list
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.casting.iota.ListIota
import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.casting.iota.NullIota
@ -10,7 +11,7 @@ import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.* import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
object OperatorUnappend : Operator(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST))) { object OperatorUnappend : Operator(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> { override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex() val it = iotas.iterator().withIndex()
val list = it.nextList(arity).toMutableList() val list = it.nextList(arity).toMutableList()
val last = list.removeLastOrNull() ?: NullIota() val last = list.removeLastOrNull() ?: NullIota()

View file

@ -4,13 +4,14 @@ import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate
import at.petrak.hexcasting.api.casting.asActionResult import at.petrak.hexcasting.api.casting.asActionResult
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
import at.petrak.hexcasting.common.casting.actions.math.bit.OpToSet import at.petrak.hexcasting.common.casting.actions.math.bit.OpToSet
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.LIST
object OperatorUnique : Operator(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST))) { object OperatorUnique : Operator(1, IotaMultiPredicate.all(IotaPredicate.ofType(LIST))) {
override fun apply(iotas: Iterable<Iota>): Iterable<Iota> { override fun apply(iotas: Iterable<Iota>, env: CastingEnvironment): Iterable<Iota> {
val it = iotas.iterator().withIndex() val it = iotas.iterator().withIndex()
val list = it.nextList(OpToSet.argc) val list = it.nextList(OpToSet.argc)
val out = mutableListOf<Iota>() val out = mutableListOf<Iota>()

View file

@ -4,6 +4,7 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator.vec;
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate; import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate; import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate;
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator; import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.Iota;
import at.petrak.hexcasting.api.casting.iota.Vec3Iota; import at.petrak.hexcasting.api.casting.iota.Vec3Iota;
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
@ -20,7 +21,7 @@ public class OperatorPack extends Operator {
public static OperatorPack INSTANCE = new OperatorPack(); public static OperatorPack INSTANCE = new OperatorPack();
@Override @Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) { public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) {
var it = iotas.iterator(); var it = iotas.iterator();
return List.of(new Vec3Iota(new Vec3( return List.of(new Vec3Iota(new Vec3(
downcast(it.next(), HexIotaTypes.DOUBLE).getDouble(), downcast(it.next(), HexIotaTypes.DOUBLE).getDouble(),

View file

@ -4,6 +4,7 @@ package at.petrak.hexcasting.common.casting.arithmetic.operator.vec;
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate; import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate;
import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate; import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate;
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator; import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.iota.DoubleIota; import at.petrak.hexcasting.api.casting.iota.DoubleIota;
import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.Iota;
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
@ -21,7 +22,7 @@ public class OperatorUnpack extends Operator {
public static OperatorUnpack INSTANCE = new OperatorUnpack(); public static OperatorUnpack INSTANCE = new OperatorUnpack();
@Override @Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) { public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) {
var it = iotas.iterator(); var it = iotas.iterator();
var vec = downcast(it.next(), VEC3).getVec3(); var vec = downcast(it.next(), VEC3).getVec3();
return List.of(new DoubleIota(vec.x), new DoubleIota(vec.y), new DoubleIota(vec.z)); return List.of(new DoubleIota(vec.x), new DoubleIota(vec.y), new DoubleIota(vec.z));

View file

@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaPredicate;
import at.petrak.hexcasting.api.casting.arithmetic.IterPair; import at.petrak.hexcasting.api.casting.arithmetic.IterPair;
import at.petrak.hexcasting.api.casting.arithmetic.TripleIterable; import at.petrak.hexcasting.api.casting.arithmetic.TripleIterable;
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator; import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.mishaps.Mishap; import at.petrak.hexcasting.api.casting.mishaps.Mishap;
import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero; import at.petrak.hexcasting.api.casting.mishaps.MishapDivideByZero;
import at.petrak.hexcasting.common.casting.arithmetic.DoubleArithmetic; import at.petrak.hexcasting.common.casting.arithmetic.DoubleArithmetic;
@ -32,7 +33,7 @@ public class OperatorVec3Delegating extends Operator {
} }
@Override @Override
public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas) throws Mishap { public @NotNull Iterable<Iota> apply(@NotNull Iterable<Iota> iotas, @NotNull CastingEnvironment env) throws Mishap {
var it = iotas.iterator(); var it = iotas.iterator();
var left = it.next(); var left = it.next();
var right = it.next(); var right = it.next();
@ -43,9 +44,9 @@ public class OperatorVec3Delegating extends Operator {
var lh = left instanceof Vec3Iota l ? l.getVec3() : triplicate(downcast(left, DOUBLE).getDouble()); var lh = left instanceof Vec3Iota l ? l.getVec3() : triplicate(downcast(left, DOUBLE).getDouble());
var rh = right instanceof Vec3Iota r ? r.getVec3() : triplicate(downcast(right, DOUBLE).getDouble()); var rh = right instanceof Vec3Iota r ? r.getVec3() : triplicate(downcast(right, DOUBLE).getDouble());
return new TripleIterable<>( return new TripleIterable<>(
fb.apply(new IterPair<>(new DoubleIota(lh.x()), new DoubleIota(rh.x()))), fb.apply(new IterPair<>(new DoubleIota(lh.x()), new DoubleIota(rh.x())), env),
fb.apply(new IterPair<>(new DoubleIota(lh.y()), new DoubleIota(rh.y()))), fb.apply(new IterPair<>(new DoubleIota(lh.y()), new DoubleIota(rh.y())), env),
fb.apply(new IterPair<>(new DoubleIota(lh.z()), new DoubleIota(rh.z()))), fb.apply(new IterPair<>(new DoubleIota(lh.z()), new DoubleIota(rh.z())), env),
(x, y, z) -> new Vec3Iota(new Vec3(downcast(x, DOUBLE).getDouble(), downcast(y, DOUBLE).getDouble(), downcast(z, DOUBLE).getDouble())) (x, y, z) -> new Vec3Iota(new Vec3(downcast(x, DOUBLE).getDouble(), downcast(y, DOUBLE).getDouble(), downcast(z, DOUBLE).getDouble()))
); );
} catch (MishapDivideByZero e) { } catch (MishapDivideByZero e) {

View file

@ -105,29 +105,22 @@ public class ListPerWorldPatternsCommand {
var stack = new ItemStack(HexItems.SCROLL_LARGE); var stack = new ItemStack(HexItems.SCROLL_LARGE);
stack.setTag(tag); stack.setTag(tag);
<<<<<<< HEAD:Common/src/main/java/at/petrak/hexcasting/common/command/ListPerWorldPatternsCommand.java
for (var player : targets) { for (var player : targets) {
var stackEntity = player.drop(stack, false); var stackEntity = player.drop(stack, false);
if (stackEntity != null) { if (stackEntity != null) {
stackEntity.setNoPickUpDelay(); stackEntity.setNoPickUpDelay();
stackEntity.setOwner(player.getUUID()); stackEntity.setThrower(player.getUUID());
} }
=======
for (var player : targets) {
var stackEntity = player.drop(stack, false);
if (stackEntity != null) {
stackEntity.setNoPickUpDelay();
stackEntity.setThrower(player.getUUID());
>>>>>>> talia-1.20/1.20.1:Common/src/main/java/at/petrak/hexcasting/common/command/ListPatternsCommand.java
}
count++; count++;
}
} }
} }
int finalCount = count;
source.sendSuccess(() -> source.sendSuccess(() ->
Component.translatable("command.hexcasting.pats.all", Component.translatable("command.hexcasting.pats.all",
count, finalCount,
targets.size() == 1 ? targets.iterator().next().getDisplayName() : targets.size()), targets.size() == 1 ? targets.iterator().next().getDisplayName() : targets.size()),
true); true);
return count; return count;

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.common.items;
import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.common.lib.HexSounds; import at.petrak.hexcasting.common.lib.HexSounds;
import at.petrak.hexcasting.common.msgs.MsgClearSpiralPatternsS2C;
import at.petrak.hexcasting.common.msgs.MsgOpenSpellGuiS2C; import at.petrak.hexcasting.common.msgs.MsgOpenSpellGuiS2C;
import at.petrak.hexcasting.xplat.IXplatAbstractions; import at.petrak.hexcasting.xplat.IXplatAbstractions;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -29,6 +30,9 @@ public class ItemStaff extends Item {
player.playSound(HexSounds.STAFF_RESET, 1f, 1f); player.playSound(HexSounds.STAFF_RESET, 1f, 1f);
} else if (player instanceof ServerPlayer serverPlayer) { } else if (player instanceof ServerPlayer serverPlayer) {
IXplatAbstractions.INSTANCE.clearCastingData(serverPlayer); IXplatAbstractions.INSTANCE.clearCastingData(serverPlayer);
var packet = new MsgClearSpiralPatternsS2C(player.getUUID());
IXplatAbstractions.INSTANCE.sendPacketToPlayer(serverPlayer, packet);
IXplatAbstractions.INSTANCE.sendPacketTracking(serverPlayer, packet);
} }
} }

View file

@ -5,9 +5,12 @@ import at.petrak.hexcasting.api.casting.eval.env.PackagedItemCastEnv;
import at.petrak.hexcasting.api.casting.eval.vm.CastingVM; import at.petrak.hexcasting.api.casting.eval.vm.CastingVM;
import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.Iota;
import at.petrak.hexcasting.api.casting.iota.IotaType; import at.petrak.hexcasting.api.casting.iota.IotaType;
import at.petrak.hexcasting.api.casting.iota.PatternIota;
import at.petrak.hexcasting.api.item.HexHolderItem; import at.petrak.hexcasting.api.item.HexHolderItem;
import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.pigment.FrozenPigment;
import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.api.utils.NBTHelper;
import at.petrak.hexcasting.common.msgs.MsgNewSpiralPatternsS2C;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import net.minecraft.nbt.CompoundTag; 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;
@ -128,6 +131,14 @@ public abstract class ItemPackagedHex extends ItemMediaHolder implements HexHold
var harness = CastingVM.empty(ctx); var harness = CastingVM.empty(ctx);
var clientView = harness.queueExecuteAndWrapIotas(instrs, sPlayer.serverLevel()); var clientView = harness.queueExecuteAndWrapIotas(instrs, sPlayer.serverLevel());
var patterns = instrs.stream()
.filter(i -> i instanceof PatternIota)
.map(i -> ((PatternIota) i).getPattern())
.toList();
var packet = new MsgNewSpiralPatternsS2C(sPlayer.getUUID(), patterns, 140);
IXplatAbstractions.INSTANCE.sendPacketToPlayer(sPlayer, packet);
IXplatAbstractions.INSTANCE.sendPacketTracking(sPlayer, packet);
boolean broken = breakAfterDepletion() && getMedia(stack) == 0; boolean broken = breakAfterDepletion() && getMedia(stack) == 0;
Stat<?> stat; Stat<?> stat;

View file

@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.casting.ActionRegistryEntry;
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic; import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic;
import at.petrak.hexcasting.api.casting.castables.SpecialHandler; import at.petrak.hexcasting.api.casting.castables.SpecialHandler;
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound; import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
import at.petrak.hexcasting.api.casting.eval.vm.ContinuationFrame;
import at.petrak.hexcasting.api.casting.iota.IotaType; import at.petrak.hexcasting.api.casting.iota.IotaType;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
@ -15,5 +16,6 @@ public class HexRegistries {
public static final ResourceKey<Registry<SpecialHandler.Factory<?>>> SPECIAL_HANDLER = ResourceKey.createRegistryKey(modLoc("special_handler")); public static final ResourceKey<Registry<SpecialHandler.Factory<?>>> SPECIAL_HANDLER = ResourceKey.createRegistryKey(modLoc("special_handler"));
public static final ResourceKey<Registry<IotaType<?>>> IOTA_TYPE = ResourceKey.createRegistryKey(modLoc("iota_type")); public static final ResourceKey<Registry<IotaType<?>>> IOTA_TYPE = ResourceKey.createRegistryKey(modLoc("iota_type"));
public static final ResourceKey<Registry<Arithmetic>> ARITHMETIC = ResourceKey.createRegistryKey(modLoc("arithmetic")); public static final ResourceKey<Registry<Arithmetic>> ARITHMETIC = ResourceKey.createRegistryKey(modLoc("arithmetic"));
public static final ResourceKey<Registry<ContinuationFrame.Type<?>>> CONTINUATION_TYPE = ResourceKey.createRegistryKey(modLoc("continuation_type"));
public static final ResourceKey<Registry<EvalSound>> EVAL_SOUND = ResourceKey.createRegistryKey(modLoc("eval_sound")); public static final ResourceKey<Registry<EvalSound>> EVAL_SOUND = ResourceKey.createRegistryKey(modLoc("eval_sound"));
} }

View file

@ -532,7 +532,7 @@ public class HexActions {
new OperationAction(HexPattern.fromAngles("edqdewaqa", HexDir.SOUTH_WEST))); new OperationAction(HexPattern.fromAngles("edqdewaqa", HexDir.SOUTH_WEST)));
public static final ActionRegistryEntry SLICE = make("slice", public static final ActionRegistryEntry SLICE = make("slice",
new OperationAction(HexPattern.fromAngles("qaeaqwded", HexDir.NORTH_WEST))); new OperationAction(HexPattern.fromAngles("qaeaqwded", HexDir.NORTH_WEST)));
public static final ActionRegistryEntry MODIFY_IN_PLACE = make("modify_in_place", public static final ActionRegistryEntry REPLACE = make("replace",
new OperationAction(HexPattern.fromAngles("wqaeaqw", HexDir.NORTH_WEST))); new OperationAction(HexPattern.fromAngles("wqaeaqw", HexDir.NORTH_WEST)));
public static final ActionRegistryEntry CONSTRUCT = make("construct", public static final ActionRegistryEntry CONSTRUCT = make("construct",
new OperationAction(HexPattern.fromAngles("ddewedd", HexDir.SOUTH_EAST))); new OperationAction(HexPattern.fromAngles("ddewedd", HexDir.SOUTH_EAST)));

View file

@ -0,0 +1,49 @@
package at.petrak.hexcasting.common.lib.hex;
import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.api.casting.eval.vm.ContinuationFrame;
import at.petrak.hexcasting.api.casting.eval.vm.FrameEvaluate;
import at.petrak.hexcasting.api.casting.eval.vm.FrameFinishEval;
import at.petrak.hexcasting.api.casting.eval.vm.FrameForEach;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import static at.petrak.hexcasting.api.HexAPI.modLoc;
/**
* Stores the registry for continuation frame types, some utility methods, and all the types Hexcasting itself defines.
*/
@ParametersAreNonnullByDefault
public class HexContinuationTypes {
public static final Registry<ContinuationFrame.Type<?>> REGISTRY = IXplatAbstractions.INSTANCE.getContinuationTypeRegistry();
public static final String
KEY_TYPE = HexAPI.MOD_ID + ":type",
KEY_DATA = HexAPI.MOD_ID + ":data";
public static void registerContinuations(BiConsumer<ContinuationFrame.Type<?>, ResourceLocation> r) {
for (var e : CONTINUATIONS.entrySet()) {
r.accept(e.getValue(), e.getKey());
}
}
private static final Map<ResourceLocation, ContinuationFrame.Type<?>> CONTINUATIONS = new LinkedHashMap<>();
public static final ContinuationFrame.Type<FrameEvaluate> EVALUATE = continuation("evaluate", FrameEvaluate.TYPE);
public static final ContinuationFrame.Type<FrameForEach> FOREACH = continuation("foreach", FrameForEach.TYPE);
public static final ContinuationFrame.Type<FrameFinishEval> END = continuation("end", FrameFinishEval.TYPE);
private static <U extends ContinuationFrame, T extends ContinuationFrame.Type<U>> T continuation(String name, T continuation) {
var old = CONTINUATIONS.put(modLoc(name), continuation);
if (old != null) {
throw new IllegalArgumentException("Typo? Duplicate id " + name);
}
return continuation;
}
}

View file

@ -0,0 +1,46 @@
package at.petrak.hexcasting.common.msgs;
import at.petrak.hexcasting.xplat.IClientXplatAbstractions;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import java.util.UUID;
import static at.petrak.hexcasting.api.HexAPI.modLoc;
public record MsgClearSpiralPatternsS2C(UUID playerUUID) implements IMessage {
public static final ResourceLocation ID = modLoc("clr_spi_pats_sc");
@Override
public ResourceLocation getFabricId() {
return ID;
}
public static MsgClearSpiralPatternsS2C deserialize(ByteBuf buffer) {
var buf = new FriendlyByteBuf(buffer);
var player = buf.readUUID();
return new MsgClearSpiralPatternsS2C(player);
}
@Override
public void serialize(FriendlyByteBuf buf) {
buf.writeUUID(playerUUID);
}
public static void handle(MsgClearSpiralPatternsS2C self) {
Minecraft.getInstance().execute(new Runnable() {
@Override
public void run() {
var mc = Minecraft.getInstance();
assert mc.level != null;
var player = mc.level.getPlayerByUUID(self.playerUUID);
var stack = IClientXplatAbstractions.INSTANCE.getClientCastingStack(player);
stack.slowClear();
}
});
}
}

View file

@ -50,15 +50,18 @@ public record MsgNewSpellPatternS2C(ExecutionClientView info, int index) impleme
} }
public static void handle(MsgNewSpellPatternS2C self) { public static void handle(MsgNewSpellPatternS2C self) {
Minecraft.getInstance().execute(() -> { Minecraft.getInstance().execute(new Runnable() {
var mc = Minecraft.getInstance(); @Override
if (self.info().isStackClear()) { public void run() {
// don't pay attention to the screen, so it also stops when we die var mc = Minecraft.getInstance();
mc.getSoundManager().stop(HexSounds.CASTING_AMBIANCE.getLocation(), null); if (self.info().isStackClear()) {
} // don't pay attention to the screen, so it also stops when we die
var screen = Minecraft.getInstance().screen; mc.getSoundManager().stop(HexSounds.CASTING_AMBIANCE.getLocation(), null);
if (screen instanceof GuiSpellcasting spellGui) { }
spellGui.recvServerUpdate(self.info(), self.index()); var screen = Minecraft.getInstance().screen;
if (screen instanceof GuiSpellcasting spellGui) {
spellGui.recvServerUpdate(self.info(), self.index());
}
} }
}); });
} }

View file

@ -0,0 +1,56 @@
package at.petrak.hexcasting.common.msgs;
import at.petrak.hexcasting.api.casting.math.HexPattern;
import at.petrak.hexcasting.xplat.IClientXplatAbstractions;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static at.petrak.hexcasting.api.HexAPI.modLoc;
public record MsgNewSpiralPatternsS2C(UUID playerUUID, List<HexPattern> patterns, int lifetime) implements IMessage {
public static final ResourceLocation ID = modLoc("spi_pats_sc");
@Override
public ResourceLocation getFabricId() {
return ID;
}
public static MsgNewSpiralPatternsS2C deserialize(ByteBuf buffer) {
var buf = new FriendlyByteBuf(buffer);
var player = buf.readUUID();
var patterns = buf.readCollection(ArrayList::new, buff -> HexPattern.fromNBT(buf.readNbt()));
var lifetime = buf.readInt();
return new MsgNewSpiralPatternsS2C(player, patterns, lifetime);
}
@Override
public void serialize(FriendlyByteBuf buf) {
buf.writeUUID(playerUUID);
buf.writeCollection(patterns, (buff, pattern) -> buff.writeNbt(pattern.serializeToNBT()));
buf.writeInt(lifetime);
}
public static void handle(MsgNewSpiralPatternsS2C self) {
Minecraft.getInstance().execute(new Runnable() {
@Override
public void run() {
var mc = Minecraft.getInstance();
assert mc.level != null;
var player = mc.level.getPlayerByUUID(self.playerUUID);
var stack = IClientXplatAbstractions.INSTANCE.getClientCastingStack(player);
for (var pattern : self.patterns)
stack.addPattern(pattern, self.lifetime);
}
});
}
}

View file

@ -56,11 +56,14 @@ public record MsgOpenSpellGuiS2C(InteractionHand hand, List<ResolvedPattern> pat
} }
public static void handle(MsgOpenSpellGuiS2C msg) { public static void handle(MsgOpenSpellGuiS2C msg) {
Minecraft.getInstance().execute(() -> { Minecraft.getInstance().execute(new Runnable() {
var mc = Minecraft.getInstance(); @Override
mc.setScreen( public void run() {
new GuiSpellcasting(msg.hand(), msg.patterns(), msg.stack, msg.ravenmind, var mc = Minecraft.getInstance();
msg.parenCount)); mc.setScreen(
new GuiSpellcasting(msg.hand(), msg.patterns(), msg.stack, msg.ravenmind,
msg.parenCount));
}
}); });
} }
} }

View file

@ -26,7 +26,7 @@ public record BrainsweepRecipe(
ResourceLocation id, ResourceLocation id,
StateIngredient blockIn, StateIngredient blockIn,
BrainsweepeeIngredient entityIn, BrainsweepeeIngredient entityIn,
int mediaCost, long mediaCost,
BlockState result BlockState result
) implements Recipe<Container> { ) implements Recipe<Container> {
public boolean matches(BlockState blockIn, Entity victim, ServerLevel level) { public boolean matches(BlockState blockIn, Entity victim, ServerLevel level) {
@ -97,7 +97,7 @@ public record BrainsweepRecipe(
public void toNetwork(FriendlyByteBuf buf, BrainsweepRecipe recipe) { public void toNetwork(FriendlyByteBuf buf, BrainsweepRecipe recipe) {
recipe.blockIn.write(buf); recipe.blockIn.write(buf);
recipe.entityIn.wrapWrite(buf); recipe.entityIn.wrapWrite(buf);
buf.writeVarInt(recipe.mediaCost); buf.writeVarLong(recipe.mediaCost);
buf.writeVarInt(Block.getId(recipe.result)); buf.writeVarInt(Block.getId(recipe.result));
} }
@ -105,7 +105,7 @@ public record BrainsweepRecipe(
public @NotNull BrainsweepRecipe fromNetwork(ResourceLocation recipeID, FriendlyByteBuf buf) { public @NotNull BrainsweepRecipe fromNetwork(ResourceLocation recipeID, FriendlyByteBuf buf) {
var blockIn = StateIngredientHelper.read(buf); var blockIn = StateIngredientHelper.read(buf);
var brainsweepeeIn = BrainsweepeeIngredient.read(buf); var brainsweepeeIn = BrainsweepeeIngredient.read(buf);
var cost = buf.readVarInt(); var cost = buf.readVarLong();
var result = Block.stateById(buf.readVarInt()); var result = Block.stateById(buf.readVarInt());
return new BrainsweepRecipe(recipeID, blockIn, brainsweepeeIn, cost, result); return new BrainsweepRecipe(recipeID, blockIn, brainsweepeeIn, cost, result);
} }

View file

@ -58,13 +58,13 @@ public class HexAdvancements extends PaucalAdvancementSubProvider {
.parent(root) .parent(root)
.addCriterion("waste_amt", new SpendMediaTrigger.Instance(ContextAwarePredicate.ANY, .addCriterion("waste_amt", new SpendMediaTrigger.Instance(ContextAwarePredicate.ANY,
MinMaxBounds.Ints.ANY, MinMaxBounds.Ints.ANY,
MinMaxBounds.Ints.atLeast(89 * MediaConstants.DUST_UNIT / 10))) MinMaxBounds.Ints.atLeast((int) (89 * MediaConstants.DUST_UNIT / 10))))
.save(consumer, prefix("aaa_wasteful_cast")); .save(consumer, prefix("aaa_wasteful_cast"));
Advancement.Builder.advancement() Advancement.Builder.advancement()
.display(simpleDisplay(HexItems.CHARGED_AMETHYST, "big_cast", FrameType.TASK)) .display(simpleDisplay(HexItems.CHARGED_AMETHYST, "big_cast", FrameType.TASK))
.parent(root) .parent(root)
.addCriterion("cast_amt", new SpendMediaTrigger.Instance(ContextAwarePredicate.ANY, .addCriterion("cast_amt", new SpendMediaTrigger.Instance(ContextAwarePredicate.ANY,
MinMaxBounds.Ints.atLeast(64 * MediaConstants.CRYSTAL_UNIT), MinMaxBounds.Ints.atLeast((int) (64 * MediaConstants.CRYSTAL_UNIT)),
MinMaxBounds.Ints.ANY)) MinMaxBounds.Ints.ANY))
.save(consumer, prefix("aab_big_cast")); .save(consumer, prefix("aab_big_cast"));

View file

@ -45,7 +45,7 @@ public class HexLootTables extends PaucalLootTableSubProvider {
Map<ResourceLocation, LootTable.Builder> lootTables) { Map<ResourceLocation, LootTable.Builder> lootTables) {
dropSelf(blockTables, HexBlocks.IMPETUS_EMPTY, dropSelf(blockTables, HexBlocks.IMPETUS_EMPTY,
HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_REDSTONE, HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_REDSTONE,
HexBlocks.DIRECTRIX_REDSTONE, HexBlocks.EMPTY_DIRECTRIX, HexBlocks.EMPTY_DIRECTRIX, HexBlocks.DIRECTRIX_REDSTONE, HexBlocks.DIRECTRIX_BOOLEAN,
HexBlocks.AKASHIC_RECORD, HexBlocks.AKASHIC_BOOKSHELF, HexBlocks.AKASHIC_LIGATURE, HexBlocks.AKASHIC_RECORD, HexBlocks.AKASHIC_BOOKSHELF, HexBlocks.AKASHIC_LIGATURE,
HexBlocks.SLATE_BLOCK, HexBlocks.SLATE_TILES, HexBlocks.SLATE_BRICKS, HexBlocks.SLATE_BRICKS_SMALL, HexBlocks.SLATE_BLOCK, HexBlocks.SLATE_TILES, HexBlocks.SLATE_BRICKS, HexBlocks.SLATE_BRICKS_SMALL,
HexBlocks.SLATE_PILLAR, HexBlocks.AMETHYST_DUST_BLOCK, HexBlocks.AMETHYST_TILES, HexBlocks.AMETHYST_BRICKS, HexBlocks.SLATE_PILLAR, HexBlocks.AMETHYST_DUST_BLOCK, HexBlocks.AMETHYST_TILES, HexBlocks.AMETHYST_BRICKS,

View file

@ -236,19 +236,19 @@ public class HexplatRecipes extends PaucalRecipeProvider {
.unlockedBy("has_item", hasItem(Items.AMETHYST_SHARD)).save(recipes); .unlockedBy("has_item", hasItem(Items.AMETHYST_SHARD)).save(recipes);
ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, HexItems.AMETHYST_DUST, ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, HexItems.AMETHYST_DUST,
(MediaConstants.QUENCHED_SHARD_UNIT / MediaConstants.DUST_UNIT) + 1) (int) (MediaConstants.QUENCHED_SHARD_UNIT / MediaConstants.DUST_UNIT) + 1)
.requires(HexItems.QUENCHED_SHARD) .requires(HexItems.QUENCHED_SHARD)
.requires(HexItems.AMETHYST_DUST) .requires(HexItems.AMETHYST_DUST)
.unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD)) .unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD))
.save(recipes, modLoc("decompose_quenched_shard/dust")); .save(recipes, modLoc("decompose_quenched_shard/dust"));
ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, Items.AMETHYST_SHARD, ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, Items.AMETHYST_SHARD,
(MediaConstants.QUENCHED_SHARD_UNIT / MediaConstants.SHARD_UNIT) + 1) (int) (MediaConstants.QUENCHED_SHARD_UNIT / MediaConstants.SHARD_UNIT) + 1)
.requires(HexItems.QUENCHED_SHARD) .requires(HexItems.QUENCHED_SHARD)
.requires(Items.AMETHYST_SHARD) .requires(Items.AMETHYST_SHARD)
.unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD)) .unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD))
.save(recipes, modLoc("decompose_quenched_shard/shard")); .save(recipes, modLoc("decompose_quenched_shard/shard"));
ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, HexItems.CHARGED_AMETHYST, ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, HexItems.CHARGED_AMETHYST,
(MediaConstants.QUENCHED_SHARD_UNIT / MediaConstants.CRYSTAL_UNIT) + 1) (int) (MediaConstants.QUENCHED_SHARD_UNIT / MediaConstants.CRYSTAL_UNIT) + 1)
.requires(HexItems.QUENCHED_SHARD) .requires(HexItems.QUENCHED_SHARD)
.requires(HexItems.CHARGED_AMETHYST) .requires(HexItems.CHARGED_AMETHYST)
.unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD)) .unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD))
@ -304,19 +304,11 @@ public class HexplatRecipes extends PaucalRecipeProvider {
.unlockedBy("has_item", hasItem(HexTags.Items.EDIFIED_LOGS)).save(recipes); .unlockedBy("has_item", hasItem(HexTags.Items.EDIFIED_LOGS)).save(recipes);
for (var log : EDIFIED_LOGS) { for (var log : EDIFIED_LOGS) {
<<<<<<< HEAD
ShapedRecipeBuilder.shaped(log, 3)
.define('W', log)
.pattern("WW")
.pattern("WW")
.unlockedBy("has_item", hasItem(log)).save(recipes);
=======
ShapedRecipeBuilder.shaped(RecipeCategory.BUILDING_BLOCKS, log, 3) ShapedRecipeBuilder.shaped(RecipeCategory.BUILDING_BLOCKS, log, 3)
.define('W', log) .define('W', log)
.pattern("WW") .pattern("WW")
.pattern("WW") .pattern("WW")
.unlockedBy("has_item", hasItem(log)).save(recipes); .unlockedBy("has_item", hasItem(log)).save(recipes);
>>>>>>> talia-1.20/1.20.1
} }
ShapedRecipeBuilder.shaped(RecipeCategory.BUILDING_BLOCKS, HexBlocks.STRIPPED_EDIFIED_WOOD, 3) ShapedRecipeBuilder.shaped(RecipeCategory.BUILDING_BLOCKS, HexBlocks.STRIPPED_EDIFIED_WOOD, 3)
@ -483,23 +475,13 @@ public class HexplatRecipes extends PaucalRecipeProvider {
// FD compat // FD compat
for (var log : EDIFIED_LOGS) { for (var log : EDIFIED_LOGS) {
this.conditions.apply(new FarmersDelightCuttingRecipeBuilder() this.conditions.apply(new FarmersDelightCuttingRecipeBuilder()
<<<<<<< HEAD
.withInput(log) .withInput(log)
.withTool(ingredients.axeStrip()) .withTool(ingredients.axeStrip())
.withOutput(HexBlocks.STRIPPED_EDIFIED_LOG) .withOutput(HexBlocks.STRIPPED_EDIFIED_LOG)
.withOutput("farmersdelight:tree_bark") .withOutput("farmersdelight:tree_bark")
.withSound(SoundEvents.AXE_STRIP)) .withSound(SoundEvents.AXE_STRIP))
.whenModLoaded("farmersdelight") .whenModLoaded("farmersdelight")
.save(recipes, modLoc("compat/farmersdelight/cutting/" + Registry.BLOCK.getKey(log).getPath())); .save(recipes, modLoc("compat/farmersdelight/cutting/" + BuiltInRegistries.BLOCK.getKey(log).getPath()));
=======
.withInput(log)
.withTool(ingredients.axeStrip())
.withOutput(HexBlocks.STRIPPED_EDIFIED_LOG)
.withOutput("farmersdelight:tree_bark")
.withSound(SoundEvents.AXE_STRIP))
.whenModLoaded("farmersdelight")
.save(recipes, modLoc("compat/farmersdelight/cutting/" + BuiltInRegistries.BLOCK.getKey(log).getPath()));
>>>>>>> talia-1.20/1.20.1
} }
this.conditions.apply(new FarmersDelightCuttingRecipeBuilder() this.conditions.apply(new FarmersDelightCuttingRecipeBuilder()

View file

@ -23,13 +23,13 @@ import java.util.function.Consumer;
public class BrainsweepRecipeBuilder implements RecipeBuilder { public class BrainsweepRecipeBuilder implements RecipeBuilder {
private final StateIngredient blockIn; private final StateIngredient blockIn;
private final BrainsweepeeIngredient entityIn; private final BrainsweepeeIngredient entityIn;
private final int mediaCost; private final long mediaCost;
private final BlockState result; private final BlockState result;
private final Advancement.Builder advancement; private final Advancement.Builder advancement;
public BrainsweepRecipeBuilder(StateIngredient blockIn, BrainsweepeeIngredient entityIn, BlockState result, public BrainsweepRecipeBuilder(StateIngredient blockIn, BrainsweepeeIngredient entityIn, BlockState result,
int mediaCost) { long mediaCost) {
this.blockIn = blockIn; this.blockIn = blockIn;
this.entityIn = entityIn; this.entityIn = entityIn;
this.result = result; this.result = result;
@ -71,7 +71,7 @@ public class BrainsweepRecipeBuilder implements RecipeBuilder {
} }
public record Result(ResourceLocation id, StateIngredient blockIn, BrainsweepeeIngredient villagerIn, public record Result(ResourceLocation id, StateIngredient blockIn, BrainsweepeeIngredient villagerIn,
int mediaCost, BlockState result, Advancement.Builder advancement, long mediaCost, BlockState result, Advancement.Builder advancement,
ResourceLocation advancementId) implements FinishedRecipe { ResourceLocation advancementId) implements FinishedRecipe {
@Override @Override
public void serializeRecipeData(JsonObject json) { public void serializeRecipeData(JsonObject json) {

View file

@ -3,13 +3,9 @@ package at.petrak.hexcasting.datagen.tag;
import at.petrak.hexcasting.api.casting.ActionRegistryEntry; import at.petrak.hexcasting.api.casting.ActionRegistryEntry;
import at.petrak.hexcasting.api.mod.HexTags; import at.petrak.hexcasting.api.mod.HexTags;
import at.petrak.hexcasting.xplat.IXplatAbstractions; import at.petrak.hexcasting.xplat.IXplatAbstractions;
<<<<<<< HEAD
import at.petrak.hexcasting.xplat.Platform; import at.petrak.hexcasting.xplat.Platform;
import net.minecraft.data.DataGenerator;
=======
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.data.PackOutput; import net.minecraft.data.PackOutput;
>>>>>>> talia-1.20/1.20.1
import net.minecraft.data.tags.TagsProvider; import net.minecraft.data.tags.TagsProvider;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;

View file

@ -26,7 +26,7 @@ public class HexBlockTagProvider extends PaucalBlockTagProvider {
add(tag(HexTags.Blocks.IMPETI), add(tag(HexTags.Blocks.IMPETI),
HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_REDSTONE); HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_REDSTONE);
add(tag(HexTags.Blocks.DIRECTRICES), add(tag(HexTags.Blocks.DIRECTRICES),
HexBlocks.DIRECTRIX_REDSTONE); HexBlocks.DIRECTRIX_REDSTONE, HexBlocks.DIRECTRIX_BOOLEAN);
tag(HexTags.Blocks.MINDFLAYED_CIRCLE_COMPONENTS) tag(HexTags.Blocks.MINDFLAYED_CIRCLE_COMPONENTS)
.addTag(HexTags.Blocks.IMPETI) .addTag(HexTags.Blocks.IMPETI)
.addTag(HexTags.Blocks.DIRECTRICES); .addTag(HexTags.Blocks.DIRECTRICES);
@ -34,7 +34,7 @@ public class HexBlockTagProvider extends PaucalBlockTagProvider {
add(tag(BlockTags.MINEABLE_WITH_PICKAXE), add(tag(BlockTags.MINEABLE_WITH_PICKAXE),
HexBlocks.SLATE_BLOCK, HexBlocks.SLATE_TILES, HexBlocks.SLATE_BRICKS, HexBlocks.SLATE_BLOCK, HexBlocks.SLATE_TILES, HexBlocks.SLATE_BRICKS,
HexBlocks.SLATE_BRICKS_SMALL, HexBlocks.SLATE_PILLAR, HexBlocks.SLATE, HexBlocks.SLATE_BRICKS_SMALL, HexBlocks.SLATE_PILLAR, HexBlocks.SLATE,
HexBlocks.EMPTY_DIRECTRIX, HexBlocks.DIRECTRIX_REDSTONE, HexBlocks.EMPTY_DIRECTRIX, HexBlocks.DIRECTRIX_REDSTONE, HexBlocks.DIRECTRIX_BOOLEAN,
HexBlocks.IMPETUS_EMPTY, HexBlocks.IMPETUS_EMPTY,
HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_REDSTONE, HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_REDSTONE,
HexBlocks.AMETHYST_TILES, HexBlocks.AMETHYST_BRICKS, HexBlocks.AMETHYST_BRICKS_SMALL, HexBlocks.AMETHYST_TILES, HexBlocks.AMETHYST_BRICKS, HexBlocks.AMETHYST_BRICKS_SMALL,

View file

@ -13,7 +13,7 @@ import net.minecraft.world.item.Items;
import java.util.List; import java.util.List;
public class PhialRecipeStackBuilder { public class PhialRecipeStackBuilder {
private static ItemStack makeBattery(int unit, int size) { private static ItemStack makeBattery(long unit, int size) {
return ItemMediaBattery.withMedia(new ItemStack(HexItems.BATTERY), unit * size, unit * size); return ItemMediaBattery.withMedia(new ItemStack(HexItems.BATTERY), unit * size, unit * size);
} }
@ -21,11 +21,11 @@ public class PhialRecipeStackBuilder {
List<ItemStack> inputItems = Lists.newArrayList(); List<ItemStack> inputItems = Lists.newArrayList();
List<ItemStack> outputItems = Lists.newArrayList(); List<ItemStack> outputItems = Lists.newArrayList();
int dust = HexConfig.common().dustMediaAmount(); long dust = HexConfig.common().dustMediaAmount();
int shard = HexConfig.common().shardMediaAmount(); long shard = HexConfig.common().shardMediaAmount();
int charged = HexConfig.common().chargedCrystalMediaAmount(); long charged = HexConfig.common().chargedCrystalMediaAmount();
int quenchedShard = MediaConstants.QUENCHED_SHARD_UNIT; long quenchedShard = MediaConstants.QUENCHED_SHARD_UNIT;
int quenchedBlock = MediaConstants.QUENCHED_BLOCK_UNIT; long quenchedBlock = MediaConstants.QUENCHED_BLOCK_UNIT;
if (dust > 0) { if (dust > 0) {

View file

@ -1,31 +1,20 @@
package at.petrak.hexcasting.mixin.client; package at.petrak.hexcasting.mixin.client;
import at.petrak.hexcasting.client.model.AltioraLayer; import at.petrak.hexcasting.api.client.ClientRenderHelper;
import net.minecraft.client.model.PlayerModel; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
// Mixin is the approach Ears uses
// granted, Ears isn't exactly the paragon of "how to make your average minecraft mod" but still
// IDK another way to do it
@Mixin(PlayerRenderer.class) @Mixin(PlayerRenderer.class)
public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractClientPlayer, public abstract class MixinPlayerRenderer {
PlayerModel<AbstractClientPlayer>> { @Inject(method = "render(Lnet/minecraft/client/player/AbstractClientPlayer;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V",
public MixinPlayerRenderer(EntityRendererProvider.Context $$0, PlayerModel<AbstractClientPlayer> $$1, float $$2) { at = @At("HEAD"))
super($$0, $$1, $$2); public void hex$onRender(AbstractClientPlayer player, float $$1, float pticks, PoseStack ps, MultiBufferSource bufferSource, int $$5, CallbackInfo ci) {
} ClientRenderHelper.renderCastingStack(ps, player, pticks);
@Inject(
method = "<init>",
at = @At("TAIL")
)
private void hex$init(EntityRendererProvider.Context erp, boolean slimModel, CallbackInfo ci) {
this.addLayer(new AltioraLayer<>(this, erp.getModelSet()));
} }
} }

View file

@ -1,6 +1,7 @@
package at.petrak.hexcasting.xplat; package at.petrak.hexcasting.xplat;
import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.api.client.ClientCastingStack;
import at.petrak.hexcasting.common.msgs.IMessage; import at.petrak.hexcasting.common.msgs.IMessage;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.EntityRendererProvider;
@ -9,6 +10,7 @@ import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
@ -27,6 +29,8 @@ public interface IClientXplatAbstractions {
void registerItemProperty(Item item, ResourceLocation id, ItemPropertyFunction func); void registerItemProperty(Item item, ResourceLocation id, ItemPropertyFunction func);
ClientCastingStack getClientCastingStack(Player player);
// On Forge, these are already exposed; on Farbc we do a mixin // On Forge, these are already exposed; on Farbc we do a mixin
void setFilterSave(AbstractTexture texture, boolean filter, boolean mipmap); void setFilterSave(AbstractTexture texture, boolean filter, boolean mipmap);

View file

@ -12,6 +12,7 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPattern;
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound; import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage; import at.petrak.hexcasting.api.casting.eval.vm.CastingImage;
import at.petrak.hexcasting.api.casting.eval.vm.CastingVM; import at.petrak.hexcasting.api.casting.eval.vm.CastingVM;
import at.petrak.hexcasting.api.casting.eval.vm.ContinuationFrame;
import at.petrak.hexcasting.api.casting.iota.IotaType; import at.petrak.hexcasting.api.casting.iota.IotaType;
import at.petrak.hexcasting.api.pigment.ColorProvider; import at.petrak.hexcasting.api.pigment.ColorProvider;
import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.pigment.FrozenPigment;
@ -68,6 +69,8 @@ public interface IXplatAbstractions {
void sendPacketNear(Vec3 pos, double radius, ServerLevel dimension, IMessage packet); void sendPacketNear(Vec3 pos, double radius, ServerLevel dimension, IMessage packet);
void sendPacketTracking(Entity entity, IMessage packet);
// https://github.com/VazkiiMods/Botania/blob/13b7bcd9cbb6b1a418b0afe455662d29b46f1a7f/Xplat/src/main/java/vazkii/botania/xplat/IXplatAbstractions.java#L157 // https://github.com/VazkiiMods/Botania/blob/13b7bcd9cbb6b1a418b0afe455662d29b46f1a7f/Xplat/src/main/java/vazkii/botania/xplat/IXplatAbstractions.java#L157
Packet<ClientGamePacketListener> toVanillaClientboundPacket(IMessage message); Packet<ClientGamePacketListener> toVanillaClientboundPacket(IMessage message);
@ -173,6 +176,7 @@ public interface IXplatAbstractions {
Registry<IotaType<?>> getIotaTypeRegistry(); Registry<IotaType<?>> getIotaTypeRegistry();
Registry<Arithmetic> getArithmeticRegistry(); Registry<Arithmetic> getArithmeticRegistry();
Registry<ContinuationFrame.Type<?>> getContinuationTypeRegistry();
Registry<EvalSound> getEvalSoundRegistry(); Registry<EvalSound> getEvalSoundRegistry();

View file

@ -424,7 +424,7 @@
"index_of": "Locator's Distillation", "index_of": "Locator's Distillation",
"remove_from": "Excisor's Distillation", "remove_from": "Excisor's Distillation",
"slice": "Selection Exaltation", "slice": "Selection Exaltation",
"modify_in_place": "Surgeon's Exaltation", "replace": "Surgeon's Exaltation",
"construct": "Speaker's Distillation", "construct": "Speaker's Distillation",
"deconstruct": "Speaker's Decomposition", "deconstruct": "Speaker's Decomposition",
@ -1245,8 +1245,8 @@
"numbers.example.7": "This pattern pushes 7: 5 + 1 + 1.", "numbers.example.7": "This pattern pushes 7: 5 + 1 + 1.",
"numbers.example.-32.header": "Example 3", "numbers.example.-32.header": "Example 3",
"numbers.example.-32": "This pattern pushes -32: negate 1 + 5 + 10 * 2.", "numbers.example.-32": "This pattern pushes -32: negate 1 + 5 + 10 * 2.",
"numbers.example.45.header": "Example 4", "numbers.example.4.5.header": "Example 4",
"numbers.example.45": "This pattern pushes 45: 5 / 2 + 1 + 1.", "numbers.example.4.5": "This pattern pushes 4.5: 5 / 2 + 1 + 1.",
"numbers.3": "In certain cases it might be easier to just use an $(l:items/abacus)$(item)Abacus/$. But, it's worth knowing the \"proper\" way to do things.", "numbers.3": "In certain cases it might be easier to just use an $(l:items/abacus)$(item)Abacus/$. But, it's worth knowing the \"proper\" way to do things.",
@ -1370,7 +1370,7 @@
"lists.reverse": "Reverse the list at the top of the stack.", "lists.reverse": "Reverse the list at the top of the stack.",
"lists.index_of": "Remove the iota at the top of the stack, then replace the list at the top with the first index of that iota within the list (starting from 0). Replaces the list with -1 if the iota doesn't exist in the list.", "lists.index_of": "Remove the iota at the top of the stack, then replace the list at the top with the first index of that iota within the list (starting from 0). Replaces the list with -1 if the iota doesn't exist in the list.",
"lists.remove_from": "Remove the number at the top of the stack, then remove the nth element of the list at the top of the stack (where n is the number you removed).", "lists.remove_from": "Remove the number at the top of the stack, then remove the nth element of the list at the top of the stack (where n is the number you removed).",
"lists.modify_in_place": "Remove the top iota of the stack and the number at the top, then set the nth element of the list at the top of the stack to that iota (where n is the number you removed). Does nothing if the number is out of bounds.", "lists.replace": "Remove the top iota of the stack and the number at the top, then set the nth element of the list at the top of the stack to that iota (where n is the number you removed). Does nothing if the number is out of bounds.",
"lists.last_n_list": "Remove $(italic)num/$ elements from the stack, then add them to a list at the top of the stack.", "lists.last_n_list": "Remove $(italic)num/$ elements from the stack, then add them to a list at the top of the stack.",
"lists.splat": "Remove the list at the top of the stack, then push its contents to the stack.", "lists.splat": "Remove the list at the top of the stack, then push its contents to the stack.",
"lists.construct": "Remove the top iota, then add it as the first element to the list at the top of the stack.", "lists.construct": "Remove the top iota, then add it as the first element to the list at the top of the stack.",

View file

@ -376,7 +376,7 @@
"hexcasting.action.hexcasting:index_of": "定位器之馏化", "hexcasting.action.hexcasting:index_of": "定位器之馏化",
"hexcasting.action.hexcasting:list_remove": "切除器之馏化", "hexcasting.action.hexcasting:list_remove": "切除器之馏化",
"hexcasting.action.hexcasting:slice": "选择之提整", "hexcasting.action.hexcasting:slice": "选择之提整",
"hexcasting.action.hexcasting:modify_in_place": "外科医师之提整", "hexcasting.action.hexcasting:replace": "外科医师之提整",
"hexcasting.action.hexcasting:construct": "演讲者之馏化", "hexcasting.action.hexcasting:construct": "演讲者之馏化",
"hexcasting.action.hexcasting:deconstruct": "演讲者之分解", "hexcasting.action.hexcasting:deconstruct": "演讲者之分解",
@ -1048,7 +1048,7 @@
"hexcasting.page.lists.reverse_list": "倒置栈顶列表。", "hexcasting.page.lists.reverse_list": "倒置栈顶列表。",
"hexcasting.page.lists.index_of": "移除栈顶元素,并将栈顶列表变为该元素在其中第一次出现的位置(从 0 开始)。若没有出现过则返回 -1。", "hexcasting.page.lists.index_of": "移除栈顶元素,并将栈顶列表变为该元素在其中第一次出现的位置(从 0 开始)。若没有出现过则返回 -1。",
"hexcasting.page.lists.list_remove": "移除栈顶的数,而后移除栈顶列表中下标为该数(就是被移除的那个数)的元素。", "hexcasting.page.lists.list_remove": "移除栈顶的数,而后移除栈顶列表中下标为该数(就是被移除的那个数)的元素。",
"hexcasting.page.lists.modify_in_place": "移除栈顶元素和栈顶的数,而后将栈顶列表中下标为该数(就是被移除的那个数)变为该元素。若该数越界则不进行操作。", "hexcasting.page.lists.replace": "移除栈顶元素和栈顶的数,而后将栈顶列表中下标为该数(就是被移除的那个数)变为该元素。若该数越界则不进行操作。",
"hexcasting.page.lists.last_n_list": "移除$(italic)所给数/$个元素,并将这些元素加入列表并将该列表压入栈顶。", "hexcasting.page.lists.last_n_list": "移除$(italic)所给数/$个元素,并将这些元素加入列表并将该列表压入栈顶。",
"hexcasting.page.lists.splat": "移除栈顶列表,而后将其中元素全部压入栈顶。", "hexcasting.page.lists.splat": "移除栈顶列表,而后将其中元素全部压入栈顶。",
"hexcasting.page.lists.construct": "移除栈顶元素,将其加到栈顶列表的开头。", "hexcasting.page.lists.construct": "移除栈顶元素,将其加到栈顶列表的开头。",

View file

@ -67,7 +67,7 @@
"type": "hexcasting:pattern", "type": "hexcasting:pattern",
"header": "hexcasting.action.hexcasting:list_size", "header": "hexcasting.action.hexcasting:list_size",
"op_id": "hexcasting:abs", "op_id": "hexcasting:abs",
"anchor": "hexcasting:abs", "anchor": "hexcasting:list_size",
"input": "list", "input": "list",
"output": "num", "output": "num",
"text": "hexcasting.page.lists.list_size" "text": "hexcasting.page.lists.list_size"
@ -98,11 +98,11 @@
}, },
{ {
"type": "hexcasting:pattern", "type": "hexcasting:pattern",
"op_id": "hexcasting:modify_in_place", "op_id": "hexcasting:replace",
"anchor": "hexcasting:modify_in_place", "anchor": "hexcasting:replace",
"input": "list, num, any", "input": "list, num, any",
"output": "list", "output": "list",
"text": "hexcasting.page.lists.modify_in_place" "text": "hexcasting.page.lists.replace"
}, },
{ {
"type": "hexcasting:pattern", "type": "hexcasting:pattern",

View file

@ -16,6 +16,7 @@
}, },
{ {
"type": "hexcasting:pattern", "type": "hexcasting:pattern",
"header": "hexcasting.action.book.hexcasting:bool_to_number",
"op_id": "hexcasting:abs", "op_id": "hexcasting:abs",
"anchor": "hexcasting:abs", "anchor": "hexcasting:abs",
"input": "bool", "input": "bool",

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Some files were not shown because too many files have changed in this diff Show more