|
@ -2,8 +2,8 @@ Hello, intrepid Github reader!
|
|||
|
||||
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)
|
||||
- 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)
|
||||
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
package at.petrak.hexcasting.api.casting
|
||||
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
|
||||
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
|
||||
|
||||
interface RenderedSpell {
|
||||
fun cast(env: CastingEnvironment)
|
||||
|
||||
fun cast(env: CastingEnvironment, image: CastingImage): CastingImage? {
|
||||
cast(env)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.operator.Operator;
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||
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 iotas The current stack.
|
||||
* @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.
|
||||
* @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);
|
||||
if (candidates == null)
|
||||
throw new InvalidOperatorException("the pattern " + pattern + " is not an operator."); //
|
||||
|
@ -84,7 +86,7 @@ public class ArithmeticEngine {
|
|||
}
|
||||
Collections.reverse(args);
|
||||
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) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.api.casting.arithmetic.operator;
|
||||
|
||||
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.IotaType;
|
||||
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.
|
||||
* @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).
|
||||
* @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.
|
||||
|
|
|
@ -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.eval.CastingEnvironment;
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
@ -20,7 +21,7 @@ public class OperatorBinary extends Operator {
|
|||
}
|
||||
|
||||
@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();
|
||||
return List.of(inner.apply(it.next(), it.next()));
|
||||
}
|
||||
|
|
|
@ -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.eval.CastingEnvironment;
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
@ -20,7 +21,7 @@ public class OperatorUnary extends Operator {
|
|||
}
|
||||
|
||||
@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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.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
|
||||
* 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);
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
|
@ -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 {
|
||||
@Override
|
||||
public boolean test(Iota iota) {
|
||||
|
|
|
@ -14,7 +14,7 @@ import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
|
|||
*/
|
||||
interface ConstMediaAction : Action {
|
||||
val argc: Int
|
||||
val mediaCost: Int
|
||||
val mediaCost: Long
|
||||
get() = 0
|
||||
|
||||
fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota>
|
||||
|
|
|
@ -24,7 +24,7 @@ data class OperationAction(val pattern: HexPattern) : Action {
|
|||
stack.addAll(stackList)
|
||||
val startingLength = stackList.size
|
||||
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) })
|
||||
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)
|
||||
|
|
|
@ -64,5 +64,5 @@ interface SpellAction : Action {
|
|||
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)
|
||||
}
|
||||
|
|
|
@ -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.vm.CastingImage
|
||||
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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
data class CastResult(
|
||||
val continuation: SpellContinuation,
|
||||
val newData: CastingImage?,
|
||||
val sideEffects: List<OperatorSideEffect>,
|
||||
val resolutionType: ResolvedPatternType,
|
||||
val sound: EvalSound,
|
||||
val cast: Iota,
|
||||
val continuation: SpellContinuation,
|
||||
val newData: CastingImage?,
|
||||
val sideEffects: List<OperatorSideEffect>,
|
||||
val resolutionType: ResolvedPatternType,
|
||||
val sound: EvalSound,
|
||||
)
|
||||
|
|
|
@ -62,6 +62,15 @@ public abstract class CastingEnvironment {
|
|||
public void precheckAction(PatternShapeMatch match) throws Mishap {
|
||||
// TODO: this doesn't let you select special handlers.
|
||||
// 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;
|
||||
if (match instanceof PatternShapeMatch.Normal normal) {
|
||||
key = normal.key.location();
|
||||
|
@ -72,9 +81,7 @@ public abstract class CastingEnvironment {
|
|||
} else {
|
||||
key = null;
|
||||
}
|
||||
if (!HexConfig.server().isActionAllowed(key)) {
|
||||
throw new MishapDisallowedSpell();
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,15 +2,20 @@ package at.petrak.hexcasting.api.casting.eval.env;
|
|||
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
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.CircleExecutionState;
|
||||
import at.petrak.hexcasting.api.casting.eval.CastResult;
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
|
||||
import at.petrak.hexcasting.api.casting.eval.MishapEnvironment;
|
||||
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 net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
|
@ -55,6 +60,17 @@ public class CircleCastEnv extends CastingEnvironment {
|
|||
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
|
||||
public void postExecution(CastResult result) {
|
||||
// we always want to play this sound one at a time
|
||||
|
|
|
@ -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.sideeffects.EvalSound;
|
||||
import at.petrak.hexcasting.api.casting.iota.PatternIota;
|
||||
import at.petrak.hexcasting.api.pigment.FrozenPigment;
|
||||
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds;
|
||||
import at.petrak.hexcasting.common.msgs.MsgNewSpiralPatternsS2C;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PackagedItemCastEnv extends PlayerBasedCastEnv {
|
||||
|
||||
protected EvalSound sound = HexEvalSounds.NOTHING;
|
||||
|
@ -19,6 +23,15 @@ public class PackagedItemCastEnv extends PlayerBasedCastEnv {
|
|||
@Override
|
||||
public void postExecution(CastResult 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?
|
||||
this.sound = this.sound.greaterOf(result.getSound());
|
||||
}
|
||||
|
@ -56,7 +69,10 @@ public class PackagedItemCastEnv extends PlayerBasedCastEnv {
|
|||
public FrozenPigment getPigment() {
|
||||
var casterStack = this.caster.getItemInHand(this.castingHand);
|
||||
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() {
|
||||
|
|
|
@ -47,7 +47,7 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ServerPlayer getCaster() {
|
||||
public ServerPlayer getCaster() {
|
||||
return this.caster;
|
||||
}
|
||||
|
||||
|
@ -189,6 +189,8 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
|
|||
protected long extractMediaFromInventory(long costLeft, boolean allowOvercast) {
|
||||
List<ADMediaHolder> sources = MediaHelper.scanPlayerForMediaStuff(this.caster);
|
||||
|
||||
var startCost = costLeft;
|
||||
|
||||
for (var source : sources) {
|
||||
var found = MediaHelper.extractMedia(source, (int) costLeft, true, false);
|
||||
costLeft -= found;
|
||||
|
@ -212,6 +214,8 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
|
|||
costLeft -= actuallyTaken;
|
||||
}
|
||||
|
||||
this.caster.awardStat(HexStatistics.MEDIA_USED, (int) (startCost - costLeft));
|
||||
|
||||
return costLeft;
|
||||
}
|
||||
|
||||
|
@ -227,8 +231,8 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void produceParticles(ParticleSpray particles, FrozenPigment colorizer) {
|
||||
particles.sprayParticles(this.world, colorizer);
|
||||
public void produceParticles(ParticleSpray particles, FrozenPigment pigment) {
|
||||
particles.sprayParticles(this.world, pigment);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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.mod.HexStatistics;
|
||||
import at.petrak.hexcasting.api.pigment.FrozenPigment;
|
||||
import at.petrak.hexcasting.common.msgs.MsgNewSpellPatternC2S;
|
||||
import at.petrak.hexcasting.common.msgs.MsgNewSpellPatternS2C;
|
||||
import at.petrak.hexcasting.common.msgs.*;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
@ -35,6 +34,14 @@ public class StaffCastEnv extends PlayerBasedCastEnv {
|
|||
public void postExecution(CastResult 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
|
||||
var sound = result.getSound().sound();
|
||||
if (sound != null) {
|
||||
|
@ -111,6 +118,15 @@ public class StaffCastEnv extends PlayerBasedCastEnv {
|
|||
IXplatAbstractions.INSTANCE.sendPacketToPlayer(sender,
|
||||
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()) {
|
||||
// Somehow we lost spraying particles on each new pattern, so do it here
|
||||
// this also nicely prevents particle spam on trinkets
|
||||
|
|
|
@ -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.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.mishaps.Mishap
|
||||
import at.petrak.hexcasting.api.mod.HexStatistics
|
||||
|
@ -36,7 +37,7 @@ sealed class OperatorSideEffect {
|
|||
) :
|
||||
OperatorSideEffect() {
|
||||
override fun performEffect(harness: CastingVM): Boolean {
|
||||
this.spell.cast(harness.env)
|
||||
this.spell.cast(harness.env, harness.image)?.let { harness.image = it }
|
||||
if (awardStat)
|
||||
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 {
|
||||
val leftoverMedia = harness.env.extractMedia(this.amount.toLong())
|
||||
val leftoverMedia = harness.env.extractMedia(this.amount)
|
||||
return leftoverMedia > 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,11 +80,12 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
|
|||
// ALSO TODO need to add reader macro-style things
|
||||
try {
|
||||
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) {
|
||||
// This is ridiculous and needs to be fixed
|
||||
return CastResult(
|
||||
iota,
|
||||
continuation,
|
||||
null,
|
||||
listOf(
|
||||
|
@ -106,6 +107,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
|
|||
// This means something very bad has happened
|
||||
exception.printStackTrace()
|
||||
return CastResult(
|
||||
iota,
|
||||
continuation,
|
||||
null,
|
||||
listOf(
|
||||
|
|
|
@ -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.eval.CastResult
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.utils.getList
|
||||
import at.petrak.hexcasting.api.utils.hasList
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
|
||||
import at.petrak.hexcasting.common.lib.hex.HexContinuationTypes
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
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.
|
||||
*
|
||||
|
@ -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.
|
||||
*
|
||||
*/
|
||||
sealed interface ContinuationFrame {
|
||||
interface ContinuationFrame {
|
||||
/**
|
||||
* Step the evaluation forward once.
|
||||
* 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
|
||||
|
||||
val type: Type<*>
|
||||
|
||||
interface Type<U : ContinuationFrame> {
|
||||
fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): U?
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Takes a tag containing the ContinuationFrame.Type resourcelocation and the serialized continuation frame, and returns
|
||||
* the deserialized continuation frame.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun fromNBT(tag: CompoundTag, world: ServerLevel): ContinuationFrame {
|
||||
return when (tag.getString("type")) {
|
||||
"evaluate" -> FrameEvaluate(
|
||||
HexIotaTypes.LIST.deserialize(
|
||||
tag.getList("patterns", Tag.TAG_COMPOUND),
|
||||
world
|
||||
)!!.list,
|
||||
tag.getBoolean("isMetacasting")
|
||||
)
|
||||
val type = getTypeFromTag(tag) ?: return FrameEvaluate(SpellList.LList(0, listOf()), false)
|
||||
|
||||
"end" -> FrameFinishEval
|
||||
"foreach" -> 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()
|
||||
)
|
||||
return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { type.deserializeFromNBT(it, world) }
|
||||
?: FrameEvaluate(SpellList.LList(0, listOf()), false)
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.ResolvedPatternType
|
||||
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.getList
|
||||
import at.petrak.hexcasting.api.utils.serializeToNBT
|
||||
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
|
||||
|
||||
/**
|
||||
|
@ -39,15 +44,31 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont
|
|||
}
|
||||
} else {
|
||||
// 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 {
|
||||
"type" %= "evaluate"
|
||||
"patterns" %= list.serializeToNBT()
|
||||
"isMetacasting" %= isMetacasting
|
||||
}
|
||||
|
||||
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"))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.ResolvedPatternType
|
||||
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.common.lib.hex.HexEvalSounds
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
|
||||
/**
|
||||
|
@ -22,6 +24,7 @@ object FrameFinishEval : ContinuationFrame {
|
|||
harness: CastingVM
|
||||
): CastResult {
|
||||
return CastResult(
|
||||
NullIota(),
|
||||
continuation,
|
||||
null,
|
||||
listOf(),
|
||||
|
@ -30,9 +33,14 @@ object FrameFinishEval : ContinuationFrame {
|
|||
)
|
||||
}
|
||||
|
||||
override fun serializeToNBT() = NBTBuilder {
|
||||
"type" %= "end"
|
||||
}
|
||||
override fun serializeToNBT() = CompoundTag()
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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.ListIota
|
||||
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.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
|
||||
|
||||
/**
|
||||
|
@ -52,8 +57,6 @@ data class FrameForEach(
|
|||
|
||||
// If we still have data to process...
|
||||
val (stackTop, newImage, newCont) = if (data.nonEmpty) {
|
||||
// Increment the evaluation depth,
|
||||
|
||||
// push the next datum to the top of the stack,
|
||||
val cont2 = continuation
|
||||
// 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()
|
||||
tStack.add(stackTop)
|
||||
return CastResult(
|
||||
ListIota(code),
|
||||
newCont,
|
||||
newImage.copy(stack = tStack),
|
||||
listOf(),
|
||||
|
@ -77,7 +81,6 @@ data class FrameForEach(
|
|||
}
|
||||
|
||||
override fun serializeToNBT() = NBTBuilder {
|
||||
"type" %= "foreach"
|
||||
"data" %= data.serializeToNBT()
|
||||
"code" %= code.serializeToNBT()
|
||||
if (baseStack != null)
|
||||
|
@ -86,4 +89,27 @@ data class FrameForEach(
|
|||
}
|
||||
|
||||
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()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ sealed interface SpellContinuation {
|
|||
var self = this
|
||||
val frames = mutableListOf<CompoundTag>()
|
||||
while (self is NotDone) {
|
||||
frames.add(self.frame.serializeToNBT())
|
||||
frames.add(ContinuationFrame.toNBT(self.frame))
|
||||
self = self.next
|
||||
}
|
||||
return frames
|
||||
|
|
|
@ -48,7 +48,7 @@ public class ContinuationIota extends Iota {
|
|||
|
||||
@Override
|
||||
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
|
||||
|
|
|
@ -54,17 +54,17 @@ public abstract class Iota {
|
|||
*/
|
||||
public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) {
|
||||
return new CastResult(
|
||||
this,
|
||||
continuation,
|
||||
null,
|
||||
null, // Should never matter
|
||||
List.of(
|
||||
new OperatorSideEffect.DoMishap(
|
||||
new MishapUnescapedValue(this),
|
||||
new Mishap.Context(new HexPattern(HexDir.WEST, List.of()), null)
|
||||
)
|
||||
), // Should never matter
|
||||
),
|
||||
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
|
||||
* limits. It should return every "iota" that is a subelement of this iota.
|
||||
* For example, if you implemented a Map<Iota, Iota>, then it should be an iterable over the keys *and*
|
||||
* values of the map. If you implemented a typed List<Double> iota for some reason, you should instad override
|
||||
* values of the map. If you implemented a typed List<Double> iota for some reason, you should instead override
|
||||
* {@link Iota#size}.
|
||||
*/
|
||||
public @Nullable Iterable<Iota> subIotas() {
|
||||
|
|
|
@ -17,6 +17,7 @@ import net.minecraft.util.FormattedCharSequence;
|
|||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
// 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.
|
||||
if (iota instanceof ListIota listIota && isTooLargeToSerialize(listIota.getList())) {
|
||||
if (isTooLargeToSerialize(List.of(iota), 0)) {
|
||||
// Garbage will never be too large so we just recurse
|
||||
return serialize(new GarbageIota());
|
||||
}
|
||||
|
@ -76,12 +77,16 @@ public abstract class IotaType<T extends Iota> {
|
|||
}
|
||||
|
||||
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.)
|
||||
// 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.
|
||||
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()) {
|
||||
var iotaPair = listsToExamine.removeFirst();
|
||||
var sublist = iotaPair.getFirst();
|
||||
|
|
|
@ -115,21 +115,21 @@ public class PatternIota extends Iota {
|
|||
var sideEffects = result.getSideEffects();
|
||||
|
||||
return new CastResult(
|
||||
this,
|
||||
cont2,
|
||||
result.getNewImage(),
|
||||
sideEffects,
|
||||
ResolvedPatternType.EVALUATED,
|
||||
result.getSound()
|
||||
);
|
||||
result.getSound());
|
||||
|
||||
} catch (Mishap mishap) {
|
||||
return new CastResult(
|
||||
this,
|
||||
continuation,
|
||||
null,
|
||||
List.of(new OperatorSideEffect.DoMishap(mishap, new Mishap.Context(this.getPattern(), castedName))),
|
||||
mishap.resolutionType(vm.getEnv()),
|
||||
HexEvalSounds.MISHAP
|
||||
);
|
||||
HexEvalSounds.MISHAP);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,8 @@ class MishapAlreadyBrainswept(val mob: Mob) : Mishap() {
|
|||
override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment =
|
||||
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>) {
|
||||
mob.hurt(mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.caster), mob.health)
|
||||
>>>>>>> talia-1.20/1.20.1
|
||||
}
|
||||
|
||||
override fun particleSpray(ctx: CastingEnvironment) =
|
||||
|
|
|
@ -16,13 +16,8 @@ class MishapBadBlock(val pos: BlockPos, val expected: Component) : Mishap() {
|
|||
override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment =
|
||||
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>) {
|
||||
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) =
|
||||
|
|
|
@ -14,13 +14,8 @@ class MishapBadBrainsweep(val mob: Mob, val pos: BlockPos) : Mishap() {
|
|||
override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment =
|
||||
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>) {
|
||||
trulyHurt(mob, mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.caster), 1f)
|
||||
>>>>>>> talia-1.20/1.20.1
|
||||
}
|
||||
|
||||
override fun particleSpray(ctx: CastingEnvironment): ParticleSpray {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package at.petrak.hexcasting.api.misc;
|
||||
|
||||
public final class MediaConstants {
|
||||
public static final int DUST_UNIT = 10000;
|
||||
public static final int SHARD_UNIT = 5 * DUST_UNIT;
|
||||
public static final int CRYSTAL_UNIT = 10 * DUST_UNIT;
|
||||
public static final long DUST_UNIT = 10000;
|
||||
public static final long SHARD_UNIT = 5 * DUST_UNIT;
|
||||
public static final long CRYSTAL_UNIT = 10 * DUST_UNIT;
|
||||
|
||||
public static final int QUENCHED_SHARD_UNIT = 3 * CRYSTAL_UNIT;
|
||||
public static final int QUENCHED_BLOCK_UNIT = 4 * QUENCHED_SHARD_UNIT;
|
||||
public static final long QUENCHED_SHARD_UNIT = 3 * CRYSTAL_UNIT;
|
||||
public static final long QUENCHED_BLOCK_UNIT = 4 * QUENCHED_SHARD_UNIT;
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ import java.util.List;
|
|||
public class HexConfig {
|
||||
public interface CommonConfigAccess {
|
||||
|
||||
int dustMediaAmount();
|
||||
long dustMediaAmount();
|
||||
|
||||
int shardMediaAmount();
|
||||
long shardMediaAmount();
|
||||
|
||||
int chargedCrystalMediaAmount();
|
||||
long chargedCrystalMediaAmount();
|
||||
|
||||
double mediaToHealthRate();
|
||||
|
||||
|
@ -27,9 +27,9 @@ public class HexConfig {
|
|||
|
||||
int artifactCooldown();
|
||||
|
||||
int DEFAULT_DUST_MEDIA_AMOUNT = MediaConstants.DUST_UNIT;
|
||||
int DEFAULT_SHARD_MEDIA_AMOUNT = MediaConstants.SHARD_UNIT;
|
||||
int DEFAULT_CHARGED_MEDIA_AMOUNT = MediaConstants.CRYSTAL_UNIT;
|
||||
long DEFAULT_DUST_MEDIA_AMOUNT = MediaConstants.DUST_UNIT;
|
||||
long DEFAULT_SHARD_MEDIA_AMOUNT = MediaConstants.SHARD_UNIT;
|
||||
long DEFAULT_CHARGED_MEDIA_AMOUNT = MediaConstants.CRYSTAL_UNIT;
|
||||
double DEFAULT_MEDIA_TO_HEALTH_RATE = 2 * MediaConstants.CRYSTAL_UNIT / 20.0;
|
||||
|
||||
int DEFAULT_CYPHER_COOLDOWN = 8;
|
||||
|
|
|
@ -11,9 +11,9 @@ import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
|||
|
||||
public class HexStatistics {
|
||||
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",
|
||||
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 SPELLS_CAST = makeCustomStat("spells_cast", StatFormatter.DEFAULT);
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ import net.minecraft.world.item.ItemStack;
|
|||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -85,8 +84,8 @@ public class HexAdditionalRenderers {
|
|||
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
RenderSystem.lineWidth(5f);
|
||||
|
||||
var colorizer = IXplatAbstractions.INSTANCE.getPigment(owner);
|
||||
var colProvider = colorizer.getColorProvider();
|
||||
var pigment = IXplatAbstractions.INSTANCE.getPigment(owner);
|
||||
var colProvider = pigment.getColorProvider();
|
||||
BiConsumer<float[], float[]> v = (l, r) -> {
|
||||
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]));
|
||||
|
|
|
@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.casting.math.HexPattern
|
|||
import at.petrak.hexcasting.api.mod.HexConfig
|
||||
import at.petrak.hexcasting.api.utils.*
|
||||
import at.petrak.hexcasting.client.ClientTickCounter
|
||||
import at.petrak.hexcasting.client.gui.GuiSpellcasting
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
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())
|
||||
.toFloat()
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ public class BlockBooleanDirectrix extends BlockCircleComponent {
|
|||
public static final DirectionProperty FACING = BlockStateProperties.FACING;
|
||||
public static final EnumProperty<State> STATE = EnumProperty.create("state", State.class);
|
||||
|
||||
public BlockBooleanDirectrix(Properties p_49795_) {
|
||||
super(p_49795_);
|
||||
public BlockBooleanDirectrix(Properties properties) {
|
||||
super(properties);
|
||||
this.registerDefaultState(this.stateDefinition.any()
|
||||
.setValue(ENERGIZED, false)
|
||||
.setValue(STATE, State.NEITHER)
|
||||
|
@ -57,9 +57,11 @@ public class BlockBooleanDirectrix extends BlockCircleComponent {
|
|||
return new ControlFlow.Stop();
|
||||
}
|
||||
|
||||
world.setBlockAndUpdate(pos, bs.setValue(STATE, biota.getBool() ? State.TRUE : State.FALSE));
|
||||
|
||||
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(),
|
||||
imageIn.getEscapeNext(), imageIn.getOpsConsumed(), imageIn.getUserData());
|
||||
|
||||
|
@ -87,6 +89,13 @@ public class BlockBooleanDirectrix extends BlockCircleComponent {
|
|||
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
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
super.createBlockStateDefinition(builder);
|
||||
|
|
|
@ -12,7 +12,7 @@ import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicRecord
|
|||
|
||||
object OpAkashicRead : ConstMediaAction {
|
||||
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> {
|
||||
val pos = args.getBlockPos(0, argc)
|
||||
|
|
|
@ -14,7 +14,7 @@ import net.minecraft.world.phys.Vec3
|
|||
|
||||
object OpBlockAxisRaycast : ConstMediaAction {
|
||||
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> {
|
||||
val origin = args.getVec3(0, argc)
|
||||
val look = args.getVec3(1, argc)
|
||||
|
|
|
@ -14,7 +14,7 @@ import net.minecraft.world.phys.Vec3
|
|||
|
||||
object OpBlockRaycast : ConstMediaAction {
|
||||
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> {
|
||||
val origin = args.getVec3(0, argc)
|
||||
val look = args.getVec3(1, argc)
|
||||
|
|
|
@ -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.NullIota
|
||||
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.EntityHitResult
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import java.util.function.Predicate
|
||||
|
||||
object OpEntityRaycast : ConstMediaAction {
|
||||
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> {
|
||||
val origin = args.getVec3(0, argc)
|
||||
val look = args.getVec3(1, argc)
|
||||
|
@ -21,8 +25,9 @@ object OpEntityRaycast : ConstMediaAction {
|
|||
|
||||
env.assertVecInRange(origin)
|
||||
|
||||
val entityHitResult = ProjectileUtil.getEntityHitResult(
|
||||
val entityHitResult = getEntityHitResult(
|
||||
env.caster,
|
||||
env.world,
|
||||
origin,
|
||||
endp,
|
||||
AABB(origin, endp),
|
||||
|
@ -36,4 +41,44 @@ object OpEntityRaycast : ConstMediaAction {
|
|||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ object OpAddMotion : SpellAction {
|
|||
motion
|
||||
return SpellAction.Result(
|
||||
Spell(target, shrunkMotion),
|
||||
(motionForCost * MediaConstants.DUST_UNIT).toInt(),
|
||||
(motionForCost * MediaConstants.DUST_UNIT).toLong(),
|
||||
listOf(
|
||||
ParticleSpray(
|
||||
target.position().add(0.0, target.eyeHeight / 2.0, 0.0),
|
||||
|
|
|
@ -15,7 +15,7 @@ import at.petrak.hexcasting.api.mod.HexTags
|
|||
import at.petrak.hexcasting.common.casting.actions.spells.great.OpTeleport
|
||||
import net.minecraft.world.entity.Entity
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
object OpBlink : SpellAction {
|
||||
override val argc = 2
|
||||
|
@ -46,7 +46,7 @@ object OpBlink : SpellAction {
|
|||
|
||||
return SpellAction.Result(
|
||||
Spell(target, delta),
|
||||
(MediaConstants.SHARD_UNIT * delta.absoluteValue * 0.5).roundToInt(),
|
||||
(MediaConstants.SHARD_UNIT * delta.absoluteValue * 0.5).roundToLong(),
|
||||
listOf(
|
||||
ParticleSpray.cloud(targetMiddlePos, 2.0, 50),
|
||||
ParticleSpray.burst(targetMiddlePos.add(dvec), 2.0, 100)
|
||||
|
|
|
@ -17,7 +17,7 @@ import net.minecraft.world.level.block.state.BlockState
|
|||
import net.minecraft.world.level.material.Fluid
|
||||
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 fun execute(
|
||||
args: List<Iota>,
|
||||
|
|
|
@ -29,7 +29,7 @@ class OpExplode(val fire: Boolean) : SpellAction {
|
|||
val cost = MediaConstants.DUST_UNIT * (3 * clampedStrength + if (fire) 1.0 else 0.125)
|
||||
return SpellAction.Result(
|
||||
Spell(pos, strength, this.fire),
|
||||
cost.toInt(),
|
||||
cost.toLong(),
|
||||
listOf(ParticleSpray.burst(pos, strength, 50))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import net.minecraft.world.item.ItemStack
|
|||
import net.minecraft.world.phys.Vec3
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
class OpFlight(val type: Type) : SpellAction {
|
||||
override val argc = 2
|
||||
|
@ -38,7 +39,7 @@ class OpFlight(val type: Type) : SpellAction {
|
|||
Type.LimitRange -> theArg * MediaConstants.DUST_UNIT
|
||||
// A second of flight should cost 1 shard
|
||||
Type.LimitTime -> theArg * MediaConstants.SHARD_UNIT
|
||||
}.roundToInt()
|
||||
}.roundToLong()
|
||||
|
||||
// Convert to ticks
|
||||
return SpellAction.Result(
|
||||
|
|
|
@ -18,7 +18,7 @@ import net.minecraft.world.entity.item.ItemEntity
|
|||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
// 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 fun execute(
|
||||
args: List<Iota>,
|
||||
|
|
|
@ -10,7 +10,7 @@ import net.minecraft.world.entity.LivingEntity
|
|||
|
||||
class OpPotionEffect(
|
||||
val effect: MobEffect,
|
||||
val baseCost: Int,
|
||||
val baseCost: Long,
|
||||
val allowPotency: Boolean,
|
||||
val potencyCubic: Boolean,
|
||||
) : SpellAction {
|
||||
|
@ -36,7 +36,7 @@ class OpPotionEffect(
|
|||
}
|
||||
return SpellAction.Result(
|
||||
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))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ object OpTheOnlyReasonAnyoneDownloadedPsi : SpellAction {
|
|||
|
||||
return SpellAction.Result(
|
||||
Spell(target),
|
||||
(MediaConstants.DUST_UNIT * 1.125).toInt(),
|
||||
(MediaConstants.DUST_UNIT * 1.125).toLong(),
|
||||
listOf(ParticleSpray.burst(Vec3.atCenterOf(BlockPos(target)), 1.0))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ import at.petrak.hexcasting.xplat.IXplatAbstractions
|
|||
|
||||
object OpGetSentinelPos : ConstMediaAction {
|
||||
override val argc = 0
|
||||
override val mediaCost = MediaConstants.DUST_UNIT / 10
|
||||
override fun execute(args: List<Iota>, ctx: CastingEnvironment): List<Iota> {
|
||||
val sentinel = IXplatAbstractions.INSTANCE.getSentinel(ctx.caster) ?: return listOf(NullIota())
|
||||
if (sentinel.dimension != ctx.world.dimension())
|
||||
override val mediaCost: Long = MediaConstants.DUST_UNIT / 10
|
||||
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
|
||||
val sentinel = IXplatAbstractions.INSTANCE.getSentinel(env.caster) ?: return listOf(NullIota())
|
||||
if (sentinel.dimension != env.world.dimension())
|
||||
throw MishapLocationInWrongDimension(sentinel.dimension.location())
|
||||
return sentinel.position.asActionResult
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import at.petrak.hexcasting.xplat.IXplatAbstractions
|
|||
// TODO standardize "a negligible amount" of media to be 1/8 a dust
|
||||
object OpGetSentinelWayfind : ConstMediaAction {
|
||||
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> {
|
||||
val from = args.getVec3(0, argc)
|
||||
|
||||
|
|
|
@ -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.IotaPredicate
|
||||
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.mishaps.MishapDivideByZero
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.DOUBLE
|
||||
import kotlin.math.log
|
||||
|
||||
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 value = it.nextDouble(arity)
|
||||
val base = it.nextDouble(arity)
|
||||
|
|
|
@ -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.IotaPredicate
|
||||
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.common.casting.arithmetic.operator.nextList
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
|
||||
|
||||
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 list = it.nextList(arity).toMutableList()
|
||||
list.add(it.next().value)
|
||||
|
|
|
@ -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.IotaPredicate
|
||||
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.NullIota
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
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 list = downcast(it.next(), LIST).list.toMutableList()
|
||||
val index = downcast(it.next(), DOUBLE).double
|
||||
|
|
|
@ -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.IotaPredicate
|
||||
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.common.casting.arithmetic.operator.nextList
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
|
||||
|
||||
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 list = it.nextList(arity).toList()
|
||||
return list.indexOf(it.next().value).asActionResult
|
||||
|
|
|
@ -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.IotaPredicate
|
||||
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.common.casting.arithmetic.operator.nextInt
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextList
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
|
||||
|
||||
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 list = it.nextList(arity).toMutableList()
|
||||
val index = it.nextInt(arity)
|
||||
|
|
|
@ -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.IotaPredicate
|
||||
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.common.casting.arithmetic.operator.nextList
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextPositiveIntUnder
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*
|
||||
|
||||
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 list = it.nextList(arity)
|
||||
val index = it.nextPositiveIntUnder(list.size(), arity)
|
||||
|
|
|
@ -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.operator.Operator
|
||||
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.common.casting.arithmetic.operator.nextList
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.operator.nextPositiveIntUnderInclusive
|
||||
|
@ -12,7 +13,7 @@ import kotlin.math.max
|
|||
import kotlin.math.min
|
||||
|
||||
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 list = it.nextList(arity).toList()
|
||||
val index0 = it.nextPositiveIntUnderInclusive(list.size, arity)
|
||||
|
|
|
@ -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.predicates.IotaMultiPredicate
|
||||
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.ListIota
|
||||
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
|
||||
|
||||
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 list = it.nextList(arity)
|
||||
if (list.nonEmpty) {
|
||||
if (list.nonEmpty)
|
||||
return listOf(ListIota(list.cdr), list.car)
|
||||
}
|
||||
return listOf(ListIota(list), NullIota())
|
||||
}
|
||||
}
|
|
@ -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.predicates.IotaMultiPredicate
|
||||
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.ListIota
|
||||
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.*
|
||||
|
||||
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 list = it.nextList(arity).toMutableList()
|
||||
val last = list.removeLastOrNull() ?: NullIota()
|
||||
|
|
|
@ -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.IotaPredicate
|
||||
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.common.casting.arithmetic.operator.nextList
|
||||
import at.petrak.hexcasting.common.casting.actions.math.bit.OpToSet
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes.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 list = it.nextList(OpToSet.argc)
|
||||
val out = mutableListOf<Iota>()
|
||||
|
|
|
@ -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.IotaPredicate;
|
||||
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.Vec3Iota;
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||
|
@ -20,7 +21,7 @@ public class OperatorPack extends Operator {
|
|||
public static OperatorPack INSTANCE = new OperatorPack();
|
||||
|
||||
@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();
|
||||
return List.of(new Vec3Iota(new Vec3(
|
||||
downcast(it.next(), HexIotaTypes.DOUBLE).getDouble(),
|
||||
|
|
|
@ -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.IotaPredicate;
|
||||
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.Iota;
|
||||
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||
|
@ -21,7 +22,7 @@ public class OperatorUnpack extends Operator {
|
|||
public static OperatorUnpack INSTANCE = new OperatorUnpack();
|
||||
|
||||
@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 vec = downcast(it.next(), VEC3).getVec3();
|
||||
return List.of(new DoubleIota(vec.x), new DoubleIota(vec.y), new DoubleIota(vec.z));
|
||||
|
|
|
@ -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.TripleIterable;
|
||||
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.MishapDivideByZero;
|
||||
import at.petrak.hexcasting.common.casting.arithmetic.DoubleArithmetic;
|
||||
|
@ -32,7 +33,7 @@ public class OperatorVec3Delegating extends Operator {
|
|||
}
|
||||
|
||||
@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 left = 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 rh = right instanceof Vec3Iota r ? r.getVec3() : triplicate(downcast(right, DOUBLE).getDouble());
|
||||
return new TripleIterable<>(
|
||||
fb.apply(new IterPair<>(new DoubleIota(lh.x()), new DoubleIota(rh.x()))),
|
||||
fb.apply(new IterPair<>(new DoubleIota(lh.y()), new DoubleIota(rh.y()))),
|
||||
fb.apply(new IterPair<>(new DoubleIota(lh.z()), new DoubleIota(rh.z()))),
|
||||
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())), env),
|
||||
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()))
|
||||
);
|
||||
} catch (MishapDivideByZero e) {
|
||||
|
|
|
@ -105,29 +105,22 @@ public class ListPerWorldPatternsCommand {
|
|||
var stack = new ItemStack(HexItems.SCROLL_LARGE);
|
||||
stack.setTag(tag);
|
||||
|
||||
<<<<<<< HEAD:Common/src/main/java/at/petrak/hexcasting/common/command/ListPerWorldPatternsCommand.java
|
||||
for (var player : targets) {
|
||||
var stackEntity = player.drop(stack, false);
|
||||
if (stackEntity != null) {
|
||||
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(() ->
|
||||
Component.translatable("command.hexcasting.pats.all",
|
||||
count,
|
||||
finalCount,
|
||||
targets.size() == 1 ? targets.iterator().next().getDisplayName() : targets.size()),
|
||||
true);
|
||||
return count;
|
||||
|
|
|
@ -2,6 +2,7 @@ package at.petrak.hexcasting.common.items;
|
|||
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
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.xplat.IXplatAbstractions;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -29,6 +30,9 @@ public class ItemStaff extends Item {
|
|||
player.playSound(HexSounds.STAFF_RESET, 1f, 1f);
|
||||
} else if (player instanceof ServerPlayer serverPlayer) {
|
||||
IXplatAbstractions.INSTANCE.clearCastingData(serverPlayer);
|
||||
var packet = new MsgClearSpiralPatternsS2C(player.getUUID());
|
||||
IXplatAbstractions.INSTANCE.sendPacketToPlayer(serverPlayer, packet);
|
||||
IXplatAbstractions.INSTANCE.sendPacketTracking(serverPlayer, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.iota.Iota;
|
||||
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.pigment.FrozenPigment;
|
||||
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.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
@ -128,6 +131,14 @@ public abstract class ItemPackagedHex extends ItemMediaHolder implements HexHold
|
|||
var harness = CastingVM.empty(ctx);
|
||||
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;
|
||||
|
||||
Stat<?> stat;
|
||||
|
|
|
@ -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.castables.SpecialHandler;
|
||||
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 net.minecraft.core.Registry;
|
||||
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<IotaType<?>>> IOTA_TYPE = ResourceKey.createRegistryKey(modLoc("iota_type"));
|
||||
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"));
|
||||
}
|
||||
|
|
|
@ -532,7 +532,7 @@ public class HexActions {
|
|||
new OperationAction(HexPattern.fromAngles("edqdewaqa", HexDir.SOUTH_WEST)));
|
||||
public static final ActionRegistryEntry SLICE = make("slice",
|
||||
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)));
|
||||
public static final ActionRegistryEntry CONSTRUCT = make("construct",
|
||||
new OperationAction(HexPattern.fromAngles("ddewedd", HexDir.SOUTH_EAST)));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -50,15 +50,18 @@ public record MsgNewSpellPatternS2C(ExecutionClientView info, int index) impleme
|
|||
}
|
||||
|
||||
public static void handle(MsgNewSpellPatternS2C self) {
|
||||
Minecraft.getInstance().execute(() -> {
|
||||
var mc = Minecraft.getInstance();
|
||||
if (self.info().isStackClear()) {
|
||||
// don't pay attention to the screen, so it also stops when we die
|
||||
mc.getSoundManager().stop(HexSounds.CASTING_AMBIANCE.getLocation(), null);
|
||||
}
|
||||
var screen = Minecraft.getInstance().screen;
|
||||
if (screen instanceof GuiSpellcasting spellGui) {
|
||||
spellGui.recvServerUpdate(self.info(), self.index());
|
||||
Minecraft.getInstance().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
var mc = Minecraft.getInstance();
|
||||
if (self.info().isStackClear()) {
|
||||
// don't pay attention to the screen, so it also stops when we die
|
||||
mc.getSoundManager().stop(HexSounds.CASTING_AMBIANCE.getLocation(), null);
|
||||
}
|
||||
var screen = Minecraft.getInstance().screen;
|
||||
if (screen instanceof GuiSpellcasting spellGui) {
|
||||
spellGui.recvServerUpdate(self.info(), self.index());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -56,11 +56,14 @@ public record MsgOpenSpellGuiS2C(InteractionHand hand, List<ResolvedPattern> pat
|
|||
}
|
||||
|
||||
public static void handle(MsgOpenSpellGuiS2C msg) {
|
||||
Minecraft.getInstance().execute(() -> {
|
||||
var mc = Minecraft.getInstance();
|
||||
mc.setScreen(
|
||||
new GuiSpellcasting(msg.hand(), msg.patterns(), msg.stack, msg.ravenmind,
|
||||
msg.parenCount));
|
||||
Minecraft.getInstance().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
var mc = Minecraft.getInstance();
|
||||
mc.setScreen(
|
||||
new GuiSpellcasting(msg.hand(), msg.patterns(), msg.stack, msg.ravenmind,
|
||||
msg.parenCount));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public record BrainsweepRecipe(
|
|||
ResourceLocation id,
|
||||
StateIngredient blockIn,
|
||||
BrainsweepeeIngredient entityIn,
|
||||
int mediaCost,
|
||||
long mediaCost,
|
||||
BlockState result
|
||||
) implements Recipe<Container> {
|
||||
public boolean matches(BlockState blockIn, Entity victim, ServerLevel level) {
|
||||
|
@ -97,7 +97,7 @@ public record BrainsweepRecipe(
|
|||
public void toNetwork(FriendlyByteBuf buf, BrainsweepRecipe recipe) {
|
||||
recipe.blockIn.write(buf);
|
||||
recipe.entityIn.wrapWrite(buf);
|
||||
buf.writeVarInt(recipe.mediaCost);
|
||||
buf.writeVarLong(recipe.mediaCost);
|
||||
buf.writeVarInt(Block.getId(recipe.result));
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ public record BrainsweepRecipe(
|
|||
public @NotNull BrainsweepRecipe fromNetwork(ResourceLocation recipeID, FriendlyByteBuf buf) {
|
||||
var blockIn = StateIngredientHelper.read(buf);
|
||||
var brainsweepeeIn = BrainsweepeeIngredient.read(buf);
|
||||
var cost = buf.readVarInt();
|
||||
var cost = buf.readVarLong();
|
||||
var result = Block.stateById(buf.readVarInt());
|
||||
return new BrainsweepRecipe(recipeID, blockIn, brainsweepeeIn, cost, result);
|
||||
}
|
||||
|
|
|
@ -58,13 +58,13 @@ public class HexAdvancements extends PaucalAdvancementSubProvider {
|
|||
.parent(root)
|
||||
.addCriterion("waste_amt", new SpendMediaTrigger.Instance(ContextAwarePredicate.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"));
|
||||
Advancement.Builder.advancement()
|
||||
.display(simpleDisplay(HexItems.CHARGED_AMETHYST, "big_cast", FrameType.TASK))
|
||||
.parent(root)
|
||||
.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))
|
||||
.save(consumer, prefix("aab_big_cast"));
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ public class HexLootTables extends PaucalLootTableSubProvider {
|
|||
Map<ResourceLocation, LootTable.Builder> lootTables) {
|
||||
dropSelf(blockTables, HexBlocks.IMPETUS_EMPTY,
|
||||
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.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,
|
||||
|
|
|
@ -236,19 +236,19 @@ public class HexplatRecipes extends PaucalRecipeProvider {
|
|||
.unlockedBy("has_item", hasItem(Items.AMETHYST_SHARD)).save(recipes);
|
||||
|
||||
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.AMETHYST_DUST)
|
||||
.unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD))
|
||||
.save(recipes, modLoc("decompose_quenched_shard/dust"));
|
||||
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(Items.AMETHYST_SHARD)
|
||||
.unlockedBy("has_item", hasItem(HexItems.QUENCHED_SHARD))
|
||||
.save(recipes, modLoc("decompose_quenched_shard/shard"));
|
||||
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.CHARGED_AMETHYST)
|
||||
.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);
|
||||
|
||||
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)
|
||||
.define('W', log)
|
||||
.pattern("WW")
|
||||
.pattern("WW")
|
||||
.unlockedBy("has_item", hasItem(log)).save(recipes);
|
||||
>>>>>>> talia-1.20/1.20.1
|
||||
}
|
||||
|
||||
ShapedRecipeBuilder.shaped(RecipeCategory.BUILDING_BLOCKS, HexBlocks.STRIPPED_EDIFIED_WOOD, 3)
|
||||
|
@ -483,23 +475,13 @@ public class HexplatRecipes extends PaucalRecipeProvider {
|
|||
// FD compat
|
||||
for (var log : EDIFIED_LOGS) {
|
||||
this.conditions.apply(new FarmersDelightCuttingRecipeBuilder()
|
||||
<<<<<<< HEAD
|
||||
.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/" + Registry.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
|
||||
.save(recipes, modLoc("compat/farmersdelight/cutting/" + BuiltInRegistries.BLOCK.getKey(log).getPath()));
|
||||
}
|
||||
|
||||
this.conditions.apply(new FarmersDelightCuttingRecipeBuilder()
|
||||
|
|
|
@ -23,13 +23,13 @@ import java.util.function.Consumer;
|
|||
public class BrainsweepRecipeBuilder implements RecipeBuilder {
|
||||
private final StateIngredient blockIn;
|
||||
private final BrainsweepeeIngredient entityIn;
|
||||
private final int mediaCost;
|
||||
private final long mediaCost;
|
||||
private final BlockState result;
|
||||
|
||||
private final Advancement.Builder advancement;
|
||||
|
||||
public BrainsweepRecipeBuilder(StateIngredient blockIn, BrainsweepeeIngredient entityIn, BlockState result,
|
||||
int mediaCost) {
|
||||
long mediaCost) {
|
||||
this.blockIn = blockIn;
|
||||
this.entityIn = entityIn;
|
||||
this.result = result;
|
||||
|
@ -71,7 +71,7 @@ public class BrainsweepRecipeBuilder implements RecipeBuilder {
|
|||
}
|
||||
|
||||
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 {
|
||||
@Override
|
||||
public void serializeRecipeData(JsonObject json) {
|
||||
|
|
|
@ -3,13 +3,9 @@ package at.petrak.hexcasting.datagen.tag;
|
|||
import at.petrak.hexcasting.api.casting.ActionRegistryEntry;
|
||||
import at.petrak.hexcasting.api.mod.HexTags;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
<<<<<<< HEAD
|
||||
import at.petrak.hexcasting.xplat.Platform;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
=======
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.PackOutput;
|
||||
>>>>>>> talia-1.20/1.20.1
|
||||
import net.minecraft.data.tags.TagsProvider;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
|
|
@ -26,7 +26,7 @@ public class HexBlockTagProvider extends PaucalBlockTagProvider {
|
|||
add(tag(HexTags.Blocks.IMPETI),
|
||||
HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_RIGHTCLICK, HexBlocks.IMPETUS_REDSTONE);
|
||||
add(tag(HexTags.Blocks.DIRECTRICES),
|
||||
HexBlocks.DIRECTRIX_REDSTONE);
|
||||
HexBlocks.DIRECTRIX_REDSTONE, HexBlocks.DIRECTRIX_BOOLEAN);
|
||||
tag(HexTags.Blocks.MINDFLAYED_CIRCLE_COMPONENTS)
|
||||
.addTag(HexTags.Blocks.IMPETI)
|
||||
.addTag(HexTags.Blocks.DIRECTRICES);
|
||||
|
@ -34,7 +34,7 @@ public class HexBlockTagProvider extends PaucalBlockTagProvider {
|
|||
add(tag(BlockTags.MINEABLE_WITH_PICKAXE),
|
||||
HexBlocks.SLATE_BLOCK, HexBlocks.SLATE_TILES, HexBlocks.SLATE_BRICKS,
|
||||
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_RIGHTCLICK, HexBlocks.IMPETUS_LOOK, HexBlocks.IMPETUS_REDSTONE,
|
||||
HexBlocks.AMETHYST_TILES, HexBlocks.AMETHYST_BRICKS, HexBlocks.AMETHYST_BRICKS_SMALL,
|
||||
|
|
|
@ -13,7 +13,7 @@ import net.minecraft.world.item.Items;
|
|||
import java.util.List;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,11 @@ public class PhialRecipeStackBuilder {
|
|||
List<ItemStack> inputItems = Lists.newArrayList();
|
||||
List<ItemStack> outputItems = Lists.newArrayList();
|
||||
|
||||
int dust = HexConfig.common().dustMediaAmount();
|
||||
int shard = HexConfig.common().shardMediaAmount();
|
||||
int charged = HexConfig.common().chargedCrystalMediaAmount();
|
||||
int quenchedShard = MediaConstants.QUENCHED_SHARD_UNIT;
|
||||
int quenchedBlock = MediaConstants.QUENCHED_BLOCK_UNIT;
|
||||
long dust = HexConfig.common().dustMediaAmount();
|
||||
long shard = HexConfig.common().shardMediaAmount();
|
||||
long charged = HexConfig.common().chargedCrystalMediaAmount();
|
||||
long quenchedShard = MediaConstants.QUENCHED_SHARD_UNIT;
|
||||
long quenchedBlock = MediaConstants.QUENCHED_BLOCK_UNIT;
|
||||
|
||||
|
||||
if (dust > 0) {
|
||||
|
|
|
@ -1,31 +1,20 @@
|
|||
package at.petrak.hexcasting.mixin.client;
|
||||
|
||||
import at.petrak.hexcasting.client.model.AltioraLayer;
|
||||
import net.minecraft.client.model.PlayerModel;
|
||||
import at.petrak.hexcasting.api.client.ClientRenderHelper;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
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)
|
||||
public abstract class MixinPlayerRenderer extends LivingEntityRenderer<AbstractClientPlayer,
|
||||
PlayerModel<AbstractClientPlayer>> {
|
||||
public MixinPlayerRenderer(EntityRendererProvider.Context $$0, PlayerModel<AbstractClientPlayer> $$1, float $$2) {
|
||||
super($$0, $$1, $$2);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "<init>",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private void hex$init(EntityRendererProvider.Context erp, boolean slimModel, CallbackInfo ci) {
|
||||
this.addLayer(new AltioraLayer<>(this, erp.getModelSet()));
|
||||
public abstract class MixinPlayerRenderer {
|
||||
@Inject(method = "render(Lnet/minecraft/client/player/AbstractClientPlayer;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V",
|
||||
at = @At("HEAD"))
|
||||
public void hex$onRender(AbstractClientPlayer player, float $$1, float pticks, PoseStack ps, MultiBufferSource bufferSource, int $$5, CallbackInfo ci) {
|
||||
ClientRenderHelper.renderCastingStack(ps, player, pticks);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package at.petrak.hexcasting.xplat;
|
||||
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
import at.petrak.hexcasting.api.client.ClientCastingStack;
|
||||
import at.petrak.hexcasting.common.msgs.IMessage;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
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.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
@ -27,6 +29,8 @@ public interface IClientXplatAbstractions {
|
|||
|
||||
void registerItemProperty(Item item, ResourceLocation id, ItemPropertyFunction func);
|
||||
|
||||
ClientCastingStack getClientCastingStack(Player player);
|
||||
|
||||
// On Forge, these are already exposed; on Farbc we do a mixin
|
||||
void setFilterSave(AbstractTexture texture, boolean filter, boolean mipmap);
|
||||
|
||||
|
|
|
@ -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.vm.CastingImage;
|
||||
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.pigment.ColorProvider;
|
||||
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 sendPacketTracking(Entity entity, IMessage packet);
|
||||
|
||||
// https://github.com/VazkiiMods/Botania/blob/13b7bcd9cbb6b1a418b0afe455662d29b46f1a7f/Xplat/src/main/java/vazkii/botania/xplat/IXplatAbstractions.java#L157
|
||||
Packet<ClientGamePacketListener> toVanillaClientboundPacket(IMessage message);
|
||||
|
||||
|
@ -173,6 +176,7 @@ public interface IXplatAbstractions {
|
|||
Registry<IotaType<?>> getIotaTypeRegistry();
|
||||
|
||||
Registry<Arithmetic> getArithmeticRegistry();
|
||||
Registry<ContinuationFrame.Type<?>> getContinuationTypeRegistry();
|
||||
|
||||
Registry<EvalSound> getEvalSoundRegistry();
|
||||
|
||||
|
|
|
@ -424,7 +424,7 @@
|
|||
"index_of": "Locator's Distillation",
|
||||
"remove_from": "Excisor's Distillation",
|
||||
"slice": "Selection Exaltation",
|
||||
"modify_in_place": "Surgeon's Exaltation",
|
||||
"replace": "Surgeon's Exaltation",
|
||||
"construct": "Speaker's Distillation",
|
||||
"deconstruct": "Speaker's Decomposition",
|
||||
|
||||
|
@ -1245,8 +1245,8 @@
|
|||
"numbers.example.7": "This pattern pushes 7: 5 + 1 + 1.",
|
||||
"numbers.example.-32.header": "Example 3",
|
||||
"numbers.example.-32": "This pattern pushes -32: negate 1 + 5 + 10 * 2.",
|
||||
"numbers.example.45.header": "Example 4",
|
||||
"numbers.example.45": "This pattern pushes 45: 5 / 2 + 1 + 1.",
|
||||
"numbers.example.4.5.header": "Example 4",
|
||||
"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.",
|
||||
|
||||
|
||||
|
@ -1370,7 +1370,7 @@
|
|||
"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.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.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.",
|
||||
|
|
|
@ -376,7 +376,7 @@
|
|||
"hexcasting.action.hexcasting:index_of": "定位器之馏化",
|
||||
"hexcasting.action.hexcasting:list_remove": "切除器之馏化",
|
||||
"hexcasting.action.hexcasting:slice": "选择之提整",
|
||||
"hexcasting.action.hexcasting:modify_in_place": "外科医师之提整",
|
||||
"hexcasting.action.hexcasting:replace": "外科医师之提整",
|
||||
"hexcasting.action.hexcasting:construct": "演讲者之馏化",
|
||||
"hexcasting.action.hexcasting:deconstruct": "演讲者之分解",
|
||||
|
||||
|
@ -1048,7 +1048,7 @@
|
|||
"hexcasting.page.lists.reverse_list": "倒置栈顶列表。",
|
||||
"hexcasting.page.lists.index_of": "移除栈顶元素,并将栈顶列表变为该元素在其中第一次出现的位置(从 0 开始)。若没有出现过则返回 -1。",
|
||||
"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.splat": "移除栈顶列表,而后将其中元素全部压入栈顶。",
|
||||
"hexcasting.page.lists.construct": "移除栈顶元素,将其加到栈顶列表的开头。",
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
"type": "hexcasting:pattern",
|
||||
"header": "hexcasting.action.hexcasting:list_size",
|
||||
"op_id": "hexcasting:abs",
|
||||
"anchor": "hexcasting:abs",
|
||||
"anchor": "hexcasting:list_size",
|
||||
"input": "list",
|
||||
"output": "num",
|
||||
"text": "hexcasting.page.lists.list_size"
|
||||
|
@ -98,11 +98,11 @@
|
|||
},
|
||||
{
|
||||
"type": "hexcasting:pattern",
|
||||
"op_id": "hexcasting:modify_in_place",
|
||||
"anchor": "hexcasting:modify_in_place",
|
||||
"op_id": "hexcasting:replace",
|
||||
"anchor": "hexcasting:replace",
|
||||
"input": "list, num, any",
|
||||
"output": "list",
|
||||
"text": "hexcasting.page.lists.modify_in_place"
|
||||
"text": "hexcasting.page.lists.replace"
|
||||
},
|
||||
{
|
||||
"type": "hexcasting:pattern",
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
},
|
||||
{
|
||||
"type": "hexcasting:pattern",
|
||||
"header": "hexcasting.action.book.hexcasting:bool_to_number",
|
||||
"op_id": "hexcasting:abs",
|
||||
"anchor": "hexcasting:abs",
|
||||
"input": "bool",
|
||||
|
|
After Width: | Height: | Size: 420 B |
After Width: | Height: | Size: 453 B |
After Width: | Height: | Size: 373 B |
After Width: | Height: | Size: 409 B |
After Width: | Height: | Size: 448 B |
After Width: | Height: | Size: 372 B |
After Width: | Height: | Size: 392 B |
After Width: | Height: | Size: 341 B |
After Width: | Height: | Size: 415 B |