kind of fix sounds but not really again

This commit is contained in:
petrak@ 2023-04-24 21:45:36 -05:00
parent 7f73db1786
commit c6612c547a
27 changed files with 126 additions and 106 deletions

View file

@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
/** /**
* A SimpleOperator that always costs the same amount of media. * A SimpleOperator that always costs the same amount of media.
@ -36,7 +37,7 @@ interface ConstMediaAction : Action {
val sideEffects = mutableListOf<OperatorSideEffect>(OperatorSideEffect.ConsumeMedia(this.mediaCost)) val sideEffects = mutableListOf<OperatorSideEffect>(OperatorSideEffect.ConsumeMedia(this.mediaCost))
val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount) val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount)
return OperationResult(image2, sideEffects, continuation) return OperationResult(image2, sideEffects, continuation, HexEvalSounds.NORMAL_EXECUTE)
} }
data class CostMediaActionResult(val resultStack: List<Iota>, val opCount: Long = 1) data class CostMediaActionResult(val resultStack: List<Iota>, val opCount: Long = 1)

View file

@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
interface SpellAction : Action { interface SpellAction : Action {
@ -59,7 +60,8 @@ interface SpellAction : Action {
val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount, userData = userDataMut) val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount, userData = userDataMut)
return OperationResult(image2, sideEffects, continuation) val sound = if (this.hasCastingSound(env)) HexEvalSounds.SPELL else HexEvalSounds.MUTE
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: Int, val particles: List<ParticleSpray>, val opCount: Long = 1)

View file

@ -31,6 +31,8 @@ import java.util.*;
*/ */
public class CircleExecutionState { public class CircleExecutionState {
public static final String public static final String
TAG_IMPETUS_POS = "impetus_pos",
TAG_IMPETUS_DIR = "impetus_dir",
TAG_KNOWN_POSITIONS = "known_positions", TAG_KNOWN_POSITIONS = "known_positions",
TAG_REACHED_POSITIONS = "reached_positions", TAG_REACHED_POSITIONS = "reached_positions",
TAG_CURRENT_POS = "current_pos", TAG_CURRENT_POS = "current_pos",
@ -39,6 +41,8 @@ public class CircleExecutionState {
TAG_CASTER = "caster", TAG_CASTER = "caster",
TAG_COLORIZER = "colorizer"; TAG_COLORIZER = "colorizer";
public final BlockPos impetusPos;
public final Direction impetusDir;
// Does contain the starting impetus // Does contain the starting impetus
public final Set<BlockPos> knownPositions; public final Set<BlockPos> knownPositions;
public final List<BlockPos> reachedPositions; public final List<BlockPos> reachedPositions;
@ -51,9 +55,11 @@ public class CircleExecutionState {
public final AABB bounds; public final AABB bounds;
protected CircleExecutionState(Set<BlockPos> knownPositions, List<BlockPos> reachedPositions, protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, Set<BlockPos> knownPositions,
BlockPos currentPos, Direction enteredFrom, List<BlockPos> reachedPositions, BlockPos currentPos, Direction enteredFrom,
CastingImage currentImage, @Nullable UUID caster, FrozenColorizer colorizer) { CastingImage currentImage, @Nullable UUID caster, FrozenColorizer colorizer) {
this.impetusPos = impetusPos;
this.impetusDir = impetusDir;
this.knownPositions = knownPositions; this.knownPositions = knownPositions;
this.reachedPositions = reachedPositions; this.reachedPositions = reachedPositions;
this.currentPos = currentPos; this.currentPos = currentPos;
@ -65,8 +71,21 @@ public class CircleExecutionState {
this.bounds = BlockEntityAbstractImpetus.getBounds(new ArrayList<>(this.knownPositions)); this.bounds = BlockEntityAbstractImpetus.getBounds(new ArrayList<>(this.knownPositions));
} }
public @Nullable ServerPlayer getCaster(ServerLevel world) {
if (this.caster == null) {
return null;
}
var entity = world.getEntity(this.caster);
if (entity instanceof ServerPlayer serverPlayer) {
return serverPlayer;
}
// there's a problem if this branch is reached
return null;
}
// Return null if the circle does not close. // Return null if the circle does not close.
public static @Nullable CircleExecutionState createNew(BlockEntityAbstractImpetus impetus, @Nullable ServerPlayer caster) { public static @Nullable CircleExecutionState createNew(BlockEntityAbstractImpetus impetus,
@Nullable ServerPlayer caster) {
var level = (ServerLevel) impetus.getLevel(); var level = (ServerLevel) impetus.getLevel();
if (level == null) if (level == null)
@ -112,24 +131,32 @@ public class CircleExecutionState {
reachedPositions.add(impetus.getBlockPos()); reachedPositions.add(impetus.getBlockPos());
var start = seenGoodPositions.get(0); var start = seenGoodPositions.get(0);
FrozenColorizer colorizer;
UUID casterUUID;
if (caster == null) { if (caster == null) {
var colorizer = new FrozenColorizer(new ItemStack(HexItems.DYE_COLORIZERS.get(DyeColor.PURPLE)), Util.NIL_UUID); colorizer = new FrozenColorizer(new ItemStack(HexItems.DYE_COLORIZERS.get(DyeColor.PURPLE)),
return new CircleExecutionState(knownPositions, reachedPositions, start, impetus.getStartDirection(), new CastingImage(), null, colorizer); Util.NIL_UUID);
casterUUID = null;
} else { } else {
var colorizer = HexAPI.instance().getColorizer(caster); colorizer = HexAPI.instance().getColorizer(caster);
return new CircleExecutionState(knownPositions, reachedPositions, start, impetus.getStartDirection(), new CastingImage(), caster.getUUID(), colorizer); casterUUID = caster.getUUID();
} }
return new CircleExecutionState(impetus.getBlockPos(), impetus.getStartDirection(), knownPositions,
reachedPositions, start, impetus.getStartDirection(), new CastingImage(), casterUUID, colorizer);
} }
public CompoundTag save() { public CompoundTag save() {
var out = new CompoundTag(); var out = new CompoundTag();
out.put(TAG_IMPETUS_POS, NbtUtils.writeBlockPos(this.impetusPos));
out.putByte(TAG_IMPETUS_DIR, (byte) this.impetusDir.ordinal());
var knownTag = new ListTag(); var knownTag = new ListTag();
for (var bp : this.knownPositions) { for (var bp : this.knownPositions) {
knownTag.add(NbtUtils.writeBlockPos(bp)); knownTag.add(NbtUtils.writeBlockPos(bp));
} }
out.put(TAG_KNOWN_POSITIONS, knownTag); out.put(TAG_KNOWN_POSITIONS, knownTag);
var reachedTag = new ListTag(); var reachedTag = new ListTag();
for (var bp : this.reachedPositions) { for (var bp : this.reachedPositions) {
reachedTag.add(NbtUtils.writeBlockPos(bp)); reachedTag.add(NbtUtils.writeBlockPos(bp));
@ -149,6 +176,9 @@ public class CircleExecutionState {
} }
public static CircleExecutionState load(CompoundTag nbt, ServerLevel world) { public static CircleExecutionState load(CompoundTag nbt, ServerLevel world) {
var startPos = NbtUtils.readBlockPos(nbt.getCompound(TAG_IMPETUS_POS));
var startDir = Direction.values()[nbt.getByte(TAG_IMPETUS_DIR)];
var knownPositions = new HashSet<BlockPos>(); var knownPositions = new HashSet<BlockPos>();
var knownTag = nbt.getList(TAG_KNOWN_POSITIONS, Tag.TAG_COMPOUND); var knownTag = nbt.getList(TAG_KNOWN_POSITIONS, Tag.TAG_COMPOUND);
for (var tag : knownTag) { for (var tag : knownTag) {
@ -170,7 +200,8 @@ public class CircleExecutionState {
FrozenColorizer colorizer = FrozenColorizer.fromNBT(nbt.getCompound(TAG_COLORIZER)); FrozenColorizer colorizer = FrozenColorizer.fromNBT(nbt.getCompound(TAG_COLORIZER));
return new CircleExecutionState(knownPositions, reachedPositions, currentPos, enteredFrom, image, caster, colorizer); return new CircleExecutionState(startPos, startDir, knownPositions, reachedPositions, currentPos,
enteredFrom, image, caster, colorizer);
} }
/** /**
@ -188,15 +219,16 @@ public class CircleExecutionState {
if (this.caster != null && world.getEntity(this.caster) instanceof ServerPlayer player) if (this.caster != null && world.getEntity(this.caster) instanceof ServerPlayer player)
caster = player; caster = player;
var env = new CircleCastEnv(world, impetus.getBlockPos(), impetus.getStartDirection(), caster, this.bounds); var env = new CircleCastEnv(world, this);
var executorBlockState = world.getBlockState(this.currentPos); var executorBlockState = world.getBlockState(this.currentPos);
if (!(executorBlockState.getBlock() instanceof ICircleComponent executor)) { if (!(executorBlockState.getBlock() instanceof ICircleComponent executor)) {
// TODO: notification of the error? // TODO: notification of the error?
ICircleComponent.sfx(this.currentPos, executorBlockState, world, Objects.requireNonNull(env.getImpetus()), false); ICircleComponent.sfx(this.currentPos, executorBlockState, world, Objects.requireNonNull(env.getImpetus())
, false);
return false; return false;
} }
executorBlockState = executor.startEnergized(this.currentPos, executorBlockState, world); executorBlockState = executor.startEnergized(this.currentPos, executorBlockState, world);
this.reachedPositions.add(this.currentPos); this.reachedPositions.add(this.currentPos);
@ -219,7 +251,8 @@ public class CircleExecutionState {
Component.translatable("hexcasting.circles.many_exits", Component.translatable("hexcasting.circles.many_exits",
Component.literal(this.currentPos.toShortString()).withStyle(ChatFormatting.RED)), Component.literal(this.currentPos.toShortString()).withStyle(ChatFormatting.RED)),
new ItemStack(Items.COMPASS)); new ItemStack(Items.COMPASS));
ICircleComponent.sfx(this.currentPos, executorBlockState, world, Objects.requireNonNull(env.getImpetus()), false); ICircleComponent.sfx(this.currentPos, executorBlockState, world,
Objects.requireNonNull(env.getImpetus()), false);
halt = true; halt = true;
break; break;
} else { } else {
@ -234,11 +267,13 @@ public class CircleExecutionState {
Component.translatable("hexcasting.circles.no_exits", Component.translatable("hexcasting.circles.no_exits",
Component.literal(this.currentPos.toShortString()).withStyle(ChatFormatting.RED)), Component.literal(this.currentPos.toShortString()).withStyle(ChatFormatting.RED)),
new ItemStack(Items.OAK_SIGN)); new ItemStack(Items.OAK_SIGN));
ICircleComponent.sfx(this.currentPos, executorBlockState, world, Objects.requireNonNull(env.getImpetus()), false); ICircleComponent.sfx(this.currentPos, executorBlockState, world,
Objects.requireNonNull(env.getImpetus()), false);
halt = true; halt = true;
} else { } else {
// A single valid exit position has been found. // A single valid exit position has been found.
ICircleComponent.sfx(this.currentPos, executorBlockState, world, Objects.requireNonNull(env.getImpetus()), true); ICircleComponent.sfx(this.currentPos, executorBlockState, world,
Objects.requireNonNull(env.getImpetus()), true);
currentPos = found.getFirst(); currentPos = found.getFirst();
enteredFrom = found.getSecond(); enteredFrom = found.getSecond();
currentImage = cont.update; currentImage = cont.update;
@ -247,20 +282,20 @@ public class CircleExecutionState {
return !halt; return !halt;
} }
/** /**
* How many ticks should pass between activations, given the number of blocks encountered so far. * How many ticks should pass between activations, given the number of blocks encountered so far.
*/ */
protected int getTickSpeed() { protected int getTickSpeed() {
return Math.max(2, 10 - (this.reachedPositions.size() - 1) / 3); return Math.max(2, 10 - (this.reachedPositions.size() - 1) / 3);
} }
public void endExecution(BlockEntityAbstractImpetus impetus) { public void endExecution(BlockEntityAbstractImpetus impetus) {
var world = (ServerLevel) impetus.getLevel(); var world = (ServerLevel) impetus.getLevel();
if (world == null) if (world == null)
return; // TODO: error here? return; // TODO: error here?
for (var pos : this.reachedPositions) { for (var pos : this.reachedPositions) {
var there = world.getBlockState(pos); var there = world.getBlockState(pos);
if (there.getBlock() instanceof ICircleComponent cc) { if (there.getBlock() instanceof ICircleComponent cc) {

View file

@ -2,7 +2,6 @@ package at.petrak.hexcasting.api.casting.eval;
import at.petrak.hexcasting.api.casting.ParticleSpray; import at.petrak.hexcasting.api.casting.ParticleSpray;
import at.petrak.hexcasting.api.casting.PatternShapeMatch; import at.petrak.hexcasting.api.casting.PatternShapeMatch;
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
import at.petrak.hexcasting.api.casting.mishaps.Mishap; import at.petrak.hexcasting.api.casting.mishaps.Mishap;
import at.petrak.hexcasting.api.casting.mishaps.MishapBadLocation; import at.petrak.hexcasting.api.casting.mishaps.MishapBadLocation;
import at.petrak.hexcasting.api.casting.mishaps.MishapDisallowedSpell; import at.petrak.hexcasting.api.casting.mishaps.MishapDisallowedSpell;
@ -54,11 +53,6 @@ public abstract class CastingEnvironment {
*/ */
public abstract MishapEnvironment getMishapEnvironment(); public abstract MishapEnvironment getMishapEnvironment();
/**
* Get the sound that this I/O module makes upon receiving a pattern
*/
public abstract EvalSound getSoundType();
/** /**
* If something about this ARE itself is invalid, mishap. * If something about this ARE itself is invalid, mishap.
* <p> * <p>

View file

@ -1,5 +1,6 @@
package at.petrak.hexcasting.api.casting.eval package at.petrak.hexcasting.api.casting.eval
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound
import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
@ -11,4 +12,5 @@ data class OperationResult(
val newImage: CastingImage, val newImage: CastingImage,
val sideEffects: List<OperatorSideEffect>, val sideEffects: List<OperatorSideEffect>,
val newContinuation: SpellContinuation, val newContinuation: SpellContinuation,
val sound: EvalSound,
) )

View file

@ -3,22 +3,20 @@ package at.petrak.hexcasting.api.casting.eval.env;
import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.api.casting.ParticleSpray; import at.petrak.hexcasting.api.casting.ParticleSpray;
import at.petrak.hexcasting.api.casting.circles.BlockEntityAbstractImpetus; 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.CastResult;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.eval.MishapEnvironment; import at.petrak.hexcasting.api.casting.eval.MishapEnvironment;
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
import at.petrak.hexcasting.api.misc.FrozenColorizer; import at.petrak.hexcasting.api.misc.FrozenColorizer;
import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.common.lib.HexItems;
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds;
import net.minecraft.Util; import net.minecraft.Util;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -28,60 +26,48 @@ import java.util.List;
import static at.petrak.hexcasting.api.casting.eval.env.PlayerBasedCastEnv.SENTINEL_RADIUS; import static at.petrak.hexcasting.api.casting.eval.env.PlayerBasedCastEnv.SENTINEL_RADIUS;
public class CircleCastEnv extends CastingEnvironment { public class CircleCastEnv extends CastingEnvironment {
protected EvalSound sound = HexEvalSounds.NOTHING; protected final CircleExecutionState execState;
protected final BlockPos impetusLoc; public CircleCastEnv(ServerLevel world, CircleExecutionState execState) {
protected final Direction startDir;
protected final @Nullable ServerPlayer caster;
protected final AABB bounds;
public CircleCastEnv(ServerLevel world, BlockPos impetusLoc, Direction startDir, @Nullable ServerPlayer caster, AABB bounds) {
super(world); super(world);
this.impetusLoc = impetusLoc; this.execState = execState;
this.startDir = startDir;
this.caster = caster;
this.bounds = bounds;
} }
@Override @Override
public @Nullable ServerPlayer getCaster() { public @Nullable ServerPlayer getCaster() {
return this.caster; return this.execState.getCaster(this.world);
} }
public @Nullable BlockEntityAbstractImpetus getImpetus() { public @Nullable BlockEntityAbstractImpetus getImpetus() {
var entity = this.world.getBlockEntity(impetusLoc); var entity = this.world.getBlockEntity(execState.impetusPos);
if (entity instanceof BlockEntityAbstractImpetus) if (entity instanceof BlockEntityAbstractImpetus)
return (BlockEntityAbstractImpetus) entity; return (BlockEntityAbstractImpetus) entity;
return null; return null;
} }
public BlockPos getImpetusLoc() { public CircleExecutionState circleState() {
return impetusLoc; return execState;
}
public Direction getStartDir() {
return startDir;
} }
@Override @Override
public MishapEnvironment getMishapEnvironment() { public MishapEnvironment getMishapEnvironment() {
return new CircleMishapEnv(this.world, this.impetusLoc, this.startDir, this.caster, this.bounds); return new CircleMishapEnv(this.world, this.execState);
}
@Override
public EvalSound getSoundType() {
return sound;
} }
@Override @Override
public void postExecution(CastResult result) { public void postExecution(CastResult result) {
this.sound = this.sound.greaterOf(result.getSound()); // we always want to play this sound one at a time
var sound = result.getSound().sound();
if (sound != null) {
var soundPos = this.execState.currentPos;
this.world.playSound(null, soundPos, sound, SoundSource.PLAYERS, 1f, 1f);
}
} }
@Override @Override
public Vec3 mishapSprayPos() { public Vec3 mishapSprayPos() {
return Vec3.atCenterOf(impetusLoc); return Vec3.atCenterOf(this.execState.currentPos);
} }
@Override @Override
@ -103,18 +89,19 @@ public class CircleCastEnv extends CastingEnvironment {
@Override @Override
public boolean isVecInRange(Vec3 vec) { public boolean isVecInRange(Vec3 vec) {
if (this.caster != null) { var caster = this.execState.getCaster(this.world);
var sentinel = HexAPI.instance().getSentinel(this.caster); if (caster != null) {
var sentinel = HexAPI.instance().getSentinel(caster);
if (sentinel != null if (sentinel != null
&& sentinel.extendsRange() && sentinel.extendsRange()
&& this.caster.getLevel().dimension() == sentinel.dimension() && caster.getLevel().dimension() == sentinel.dimension()
&& vec.distanceToSqr(sentinel.position()) <= SENTINEL_RADIUS * SENTINEL_RADIUS && vec.distanceToSqr(sentinel.position()) <= SENTINEL_RADIUS * SENTINEL_RADIUS
) { ) {
return true; return true;
} }
} }
return this.bounds.contains(vec); return this.execState.bounds.contains(vec);
} }
@Override @Override

View file

@ -1,26 +1,16 @@
package at.petrak.hexcasting.api.casting.eval.env; package at.petrak.hexcasting.api.casting.eval.env;
import at.petrak.hexcasting.api.casting.circles.CircleExecutionState;
import at.petrak.hexcasting.api.casting.eval.MishapEnvironment; import at.petrak.hexcasting.api.casting.eval.MishapEnvironment;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
public class CircleMishapEnv extends MishapEnvironment { public class CircleMishapEnv extends MishapEnvironment {
protected final BlockPos impetusLoc; protected final CircleExecutionState execState;
protected final Direction startDir;
protected final @Nullable ServerPlayer caster;
protected final AABB bounds;
protected CircleMishapEnv(ServerLevel world, BlockPos impetusLoc, Direction startDir, @Nullable ServerPlayer caster, AABB bounds) { protected CircleMishapEnv(ServerLevel world, CircleExecutionState execState) {
super(world, null); super(world, null);
this.impetusLoc = impetusLoc; this.execState = execState;
this.startDir = startDir;
this.caster = caster;
this.bounds = bounds;
} }
@Override @Override

View file

@ -16,13 +16,10 @@ public class PackagedItemCastEnv extends PlayerBasedCastEnv {
super(caster, castingHand); super(caster, castingHand);
} }
public EvalSound getFinalSound() {
return sound;
}
@Override @Override
public void postExecution(CastResult result) { public void postExecution(CastResult result) {
super.postExecution(result); super.postExecution(result);
// TODO: how do we know when to actually play this sound?
this.sound = this.sound.greaterOf(result.getSound()); this.sound = this.sound.greaterOf(result.getSound());
} }

View file

@ -7,7 +7,6 @@ import at.petrak.hexcasting.api.casting.ParticleSpray;
import at.petrak.hexcasting.api.casting.eval.CastResult; import at.petrak.hexcasting.api.casting.eval.CastResult;
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.eval.MishapEnvironment; import at.petrak.hexcasting.api.casting.eval.MishapEnvironment;
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect; import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect;
import at.petrak.hexcasting.api.casting.mishaps.Mishap; import at.petrak.hexcasting.api.casting.mishaps.Mishap;
import at.petrak.hexcasting.api.misc.FrozenColorizer; import at.petrak.hexcasting.api.misc.FrozenColorizer;
@ -16,7 +15,6 @@ import at.petrak.hexcasting.api.mod.HexConfig;
import at.petrak.hexcasting.api.mod.HexStatistics; import at.petrak.hexcasting.api.mod.HexStatistics;
import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.api.utils.HexUtils;
import at.petrak.hexcasting.api.utils.MediaHelper; import at.petrak.hexcasting.api.utils.MediaHelper;
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
@ -50,11 +48,6 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
return this.caster; return this.caster;
} }
@Override
public EvalSound getSoundType() {
return HexEvalSounds.NORMAL_EXECUTE;
}
@Override @Override
public void postExecution(CastResult result) { public void postExecution(CastResult result) {
for (var sideEffect : result.getSideEffects()) { for (var sideEffect : result.getSideEffects()) {

View file

@ -33,10 +33,11 @@ public class StaffCastEnv extends PlayerBasedCastEnv {
public void postExecution(CastResult result) { public void postExecution(CastResult result) {
super.postExecution(result); super.postExecution(result);
// we always want to play this sound one at a time
var sound = result.getSound().sound(); var sound = result.getSound().sound();
if (sound != null) { if (sound != null) {
var soundPos = this.caster.position(); var soundPos = this.caster.position();
this.caster.getLevel().playSound(null, soundPos.x, soundPos.y, soundPos.z, this.world.playSound(null, soundPos.x, soundPos.y, soundPos.z,
sound, SoundSource.PLAYERS, 1f, 1f); sound, SoundSource.PLAYERS, 1f, 1f);
} }
} }

View file

@ -12,7 +12,7 @@ import net.minecraft.world.entity.Entity
/** /**
* The state of a casting VM, containing the stack and all * The state of a casting VM, containing the stack and all
*/ */
data class CastingImage constructor( data class CastingImage private constructor(
val stack: List<Iota>, val stack: List<Iota>,
val parenCount: Int, val parenCount: Int,

View file

@ -113,7 +113,7 @@ public class PatternIota extends Iota {
result.getNewImage(), result.getNewImage(),
sideEffects, sideEffects,
ResolvedPatternType.EVALUATED, ResolvedPatternType.EVALUATED,
vm.getEnv().getSoundType() result.getSound()
); );
} catch (Mishap mishap) { } catch (Mishap mishap) {

View file

@ -7,6 +7,10 @@ import at.petrak.hexcasting.api.casting.eval.env.CircleCastEnv
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.mishaps.MishapNoSpellCircle import at.petrak.hexcasting.api.casting.mishaps.MishapNoSpellCircle
// TODO: we now have the interesting potential to add *other* spell circle getters, like the current position
// of the eval. Hmm hm hm.
// Reminded of "targeted position" in Psi -- we could have a "cast location" refl that gets the player pos
// or the current eval pos on a circle
object OpImpetusDir : ConstMediaAction { object OpImpetusDir : ConstMediaAction {
override val argc = 0 override val argc = 0
@ -14,6 +18,6 @@ object OpImpetusDir : ConstMediaAction {
if (ctx !is CircleCastEnv) if (ctx !is CircleCastEnv)
throw MishapNoSpellCircle() throw MishapNoSpellCircle()
return ctx.startDir.step().asActionResult return ctx.circleState().impetusDir.step().asActionResult
} }
} }

View file

@ -14,6 +14,6 @@ object OpImpetusPos : ConstMediaAction {
if (ctx !is CircleCastEnv) if (ctx !is CircleCastEnv)
throw MishapNoSpellCircle() throw MishapNoSpellCircle()
return ctx.impetusLoc.asActionResult return ctx.circleState().impetusPos.asActionResult
} }
} }

View file

@ -11,6 +11,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.evaluatable import at.petrak.hexcasting.api.casting.evaluatable
import at.petrak.hexcasting.api.casting.iota.PatternIota import at.petrak.hexcasting.api.casting.iota.PatternIota
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
object OpEval : Action { object OpEval : Action {
override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
@ -32,6 +33,6 @@ object OpEval : Action {
val frame = FrameEvaluate(instrsList, true) val frame = FrameEvaluate(instrsList, true)
val image2 = image.withUsedOp().copy(stack = stack) val image2 = image.withUsedOp().copy(stack = stack)
return OperationResult(image2, listOf(), newCont.pushFrame(frame)) return OperationResult(image2, listOf(), newCont.pushFrame(frame), HexEvalSounds.HERMES)
} }
} }

View file

@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.FrameForEach
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.getList import at.petrak.hexcasting.api.casting.getList
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
object OpForEach : Action { object OpForEach : Action {
override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
@ -24,6 +25,6 @@ object OpForEach : Action {
val frame = FrameForEach(datums, instrs, null, mutableListOf()) val frame = FrameForEach(datums, instrs, null, mutableListOf())
val image2 = image.withUsedOp().copy(stack = stack) val image2 = image.withUsedOp().copy(stack = stack)
return OperationResult(image2, listOf(), continuation.pushFrame(frame)) return OperationResult(image2, listOf(), continuation.pushFrame(frame), HexEvalSounds.THOTH)
} }
} }

View file

@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.eval.OperationResult import at.petrak.hexcasting.api.casting.eval.OperationResult
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
object OpHalt : Action { object OpHalt : Action {
override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
@ -26,6 +27,6 @@ object OpHalt : Action {
} }
val image2 = image.withUsedOp().copy(stack = newStack) val image2 = image.withUsedOp().copy(stack = newStack)
return OperationResult(image2, listOf(), newCont) return OperationResult(image2, listOf(), newCont, HexEvalSounds.SPELL)
} }
} }

View file

@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.iota.DoubleIota import at.petrak.hexcasting.api.casting.iota.DoubleIota
import at.petrak.hexcasting.api.mod.HexConfig import at.petrak.hexcasting.api.mod.HexConfig
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
object OpThanos : Action { object OpThanos : Action {
override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
@ -15,6 +16,6 @@ object OpThanos : Action {
stack.add(DoubleIota(opsLeft.toDouble())) stack.add(DoubleIota(opsLeft.toDouble()))
val image2 = image.withUsedOp().copy(stack = stack) val image2 = image.withUsedOp().copy(stack = stack)
return OperationResult(image2, listOf(), continuation) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)
} }
} }

View file

@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.getPositiveIntUnderInclusive import at.petrak.hexcasting.api.casting.getPositiveIntUnderInclusive
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
object OpLastNToList : Action { object OpLastNToList : Action {
override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
@ -26,6 +27,6 @@ object OpLastNToList : Action {
stack.addAll(output.asActionResult) stack.addAll(output.asActionResult)
val image2 = image.withUsedOp().copy(stack = stack) val image2 = image.withUsedOp().copy(stack = stack)
return OperationResult(image2, listOf(), continuation) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)
} }
} }

View file

@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.iota.IotaType import at.petrak.hexcasting.api.casting.iota.IotaType
import at.petrak.hexcasting.api.casting.iota.NullIota import at.petrak.hexcasting.api.casting.iota.NullIota
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
object OpPeekLocal : Action { object OpPeekLocal : Action {
override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
@ -22,6 +23,6 @@ object OpPeekLocal : Action {
// does not mutate userdata // does not mutate userdata
val image2 = image.withUsedOp().copy(stack = stack) val image2 = image.withUsedOp().copy(stack = stack)
return OperationResult(image2, listOf(), continuation) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)
} }
} }

View file

@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.OperationResult
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
object OpPushLocal : Action { object OpPushLocal : Action {
override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
@ -19,6 +20,6 @@ object OpPushLocal : Action {
image.userData.put(HexAPI.RAVENMIND_USERDATA, newLocal.serialize()) image.userData.put(HexAPI.RAVENMIND_USERDATA, newLocal.serialize())
val image2 = image.withUsedOp().copy(stack = stack) val image2 = image.withUsedOp().copy(stack = stack)
return OperationResult(image2, listOf(), continuation) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)
} }
} }

View file

@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
// TODO should this dump the whole stack // TODO should this dump the whole stack
object OpPrint : Action { object OpPrint : Action {
@ -27,6 +28,7 @@ object OpPrint : Action {
OperatorSideEffect.AttemptSpell(Spell(datum), hasCastingSound = false, awardStat = false) OperatorSideEffect.AttemptSpell(Spell(datum), hasCastingSound = false, awardStat = false)
), ),
continuation, continuation,
HexEvalSounds.SPELL,
) )
} }

View file

@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.getPositiveInt import at.petrak.hexcasting.api.casting.getPositiveInt
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
import it.unimi.dsi.fastutil.ints.IntArrayList import it.unimi.dsi.fastutil.ints.IntArrayList
// "lehmer code" // "lehmer code"
@ -42,7 +43,7 @@ object OpAlwinfyHasAscendedToABeingOfPureMath : Action {
} }
val image2 = image.withUsedOp().copy(stack = stack) val image2 = image.withUsedOp().copy(stack = stack)
return OperationResult(image2, listOf(), continuation) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)
} }
private class FactorialIter : Iterator<Int> { private class FactorialIter : Iterator<Int> {

View file

@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.iota.DoubleIota import at.petrak.hexcasting.api.casting.iota.DoubleIota
import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidIota import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidIota
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -41,6 +42,6 @@ object OpFisherman : Action {
} }
val image2 = image.withUsedOp().copy(stack = stack) val image2 = image.withUsedOp().copy(stack = stack)
return OperationResult(image2, listOf(), continuation) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)
} }
} }

View file

@ -7,6 +7,7 @@ import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.getIntBetween import at.petrak.hexcasting.api.casting.getIntBetween
import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
object OpFishermanButItCopies : Action { object OpFishermanButItCopies : Action {
override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
@ -27,6 +28,6 @@ object OpFishermanButItCopies : Action {
} }
val image2 = image.withUsedOp().copy(stack = stack) val image2 = image.withUsedOp().copy(stack = stack)
return OperationResult(image2, listOf(), continuation) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)
} }
} }

View file

@ -6,12 +6,13 @@ import at.petrak.hexcasting.api.casting.eval.OperationResult
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.CastingImage
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation
import at.petrak.hexcasting.api.casting.iota.DoubleIota import at.petrak.hexcasting.api.casting.iota.DoubleIota
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
object OpStackSize : Action { object OpStackSize : Action {
override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult {
val stack = image.stack.toMutableList() val stack = image.stack.toMutableList()
stack.add(DoubleIota(stack.size.toDouble())) stack.add(DoubleIota(stack.size.toDouble()))
val image2 = image.withUsedOp().copy(stack = stack) val image2 = image.withUsedOp().copy(stack = stack)
return OperationResult(image2, listOf(), continuation) return OperationResult(image2, listOf(), continuation, HexEvalSounds.NORMAL_EXECUTE)
} }
} }

View file

@ -10,6 +10,7 @@ import java.util.function.BiConsumer;
import static at.petrak.hexcasting.api.HexAPI.modLoc; import static at.petrak.hexcasting.api.HexAPI.modLoc;
// TODO: we REALLY need a cleanup of how sounds work. again.
public class HexEvalSounds { public class HexEvalSounds {
private static final Map<ResourceLocation, EvalSound> SOUNDS = new LinkedHashMap<>(); private static final Map<ResourceLocation, EvalSound> SOUNDS = new LinkedHashMap<>();