Skip to content

Optimized Spell Circles #908

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,42 +31,51 @@ public class CircleExecutionState {
public static final String
TAG_IMPETUS_POS = "impetus_pos",
TAG_IMPETUS_DIR = "impetus_dir",
TAG_KNOWN_POSITIONS = "known_positions",
TAG_REACHED_POSITIONS = "reached_positions",
TAG_CURRENT_POS = "current_pos",
TAG_ENTERED_FROM = "entered_from",
TAG_IMAGE = "image",
TAG_CASTER = "caster",
TAG_PIGMENT = "pigment";
TAG_PIGMENT = "pigment",
TAG_REACHED_NUMBER = "reached_slate",
TAG_POSITIVE_POS = "positive_pos",
TAG_NEGATIVE_POS = "negative_pos";

public final BlockPos impetusPos;
public final Direction impetusDir;
// Does contain the starting impetus
public final Set<BlockPos> knownPositions;
public final List<BlockPos> reachedPositions;
public final HashSet<BlockPos> reachedPositions;
public BlockPos currentPos;
public Direction enteredFrom;
public CastingImage currentImage;
public @Nullable UUID caster;
public @Nullable FrozenPigment casterPigment;
// This controls the speed of the current slate

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

variable names aren't too descriptive here, something better might be slateWait, and greaterCorner / lesserCorner

public long reachedSlate;

// Tracks the highest pos, and lowest pos of the AABB
public BlockPos positivePos;
public BlockPos negativePos;

public final AABB bounds;


protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, Set<BlockPos> knownPositions,
List<BlockPos> reachedPositions, BlockPos currentPos, Direction enteredFrom,
CastingImage currentImage, @Nullable UUID caster, @Nullable FrozenPigment casterPigment) {
protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, HashSet<BlockPos> reachedPositions,
BlockPos currentPos, Direction enteredFrom, CastingImage currentImage, @Nullable UUID caster,
@Nullable FrozenPigment casterPigment, Long reachedSlate, BlockPos positivePos, BlockPos negativePos) {
this.impetusPos = impetusPos;
this.impetusDir = impetusDir;
this.knownPositions = knownPositions;
this.reachedPositions = reachedPositions;
this.currentPos = currentPos;
this.enteredFrom = enteredFrom;
this.currentImage = currentImage;
this.caster = caster;
this.casterPigment = casterPigment;
this.reachedSlate = reachedSlate;

this.bounds = BlockEntityAbstractImpetus.getBounds(new ArrayList<>(this.knownPositions));
this.positivePos = positivePos;
this.negativePos = negativePos;
this.bounds = new AABB(positivePos,negativePos);
}

public @Nullable ServerPlayer getCaster(ServerLevel world) {
Expand Down Expand Up @@ -94,7 +103,10 @@ protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, Set<Bl
var todo = new Stack<Pair<Direction, BlockPos>>();
todo.add(Pair.of(impetus.getStartDirection(), impetus.getBlockPos().relative(impetus.getStartDirection())));
var seenGoodPosSet = new HashSet<BlockPos>();
var seenGoodPositions = new ArrayList<BlockPos>();
var positiveBlock = new BlockPos.MutableBlockPos();
var negativeBlock = new BlockPos.MutableBlockPos();
var impetusPos = impetus.getBlockPos();
var lastBlockPos = new BlockPos.MutableBlockPos(impetusPos.getX(),impetusPos.getY(),impetusPos.getZ());

while (!todo.isEmpty()) {
var pair = todo.pop();
Expand All @@ -110,29 +122,34 @@ protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, Set<Bl
}

if (seenGoodPosSet.add(herePos)) {
lastBlockPos.set(herePos);
// Checks to see if it should update the most positive/negative block pos

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using Math.max() here would be more readable, i.e.
positiveBlock.setX(Math.max( herePos.getX(), positiveBlock.getX() ));

if (herePos.getX() > positiveBlock.getX()) positiveBlock.setX(herePos.getX());
if (herePos.getX() < negativeBlock.getX()) negativeBlock.setX(herePos.getX());

if (herePos.getY() > positiveBlock.getY()) positiveBlock.setY(herePos.getY());
if (herePos.getY() < negativeBlock.getY()) negativeBlock.setY(herePos.getY());

if (herePos.getZ() > positiveBlock.getZ()) positiveBlock.setZ(herePos.getZ());
if (herePos.getZ() < negativeBlock.getZ()) negativeBlock.setZ(herePos.getZ());
// it's new
seenGoodPositions.add(herePos);
var outs = cmp.possibleExitDirections(herePos, hereBs, level);
for (var out : outs) {
todo.add(Pair.of(out, herePos.relative(out)));
}
}
}

if (seenGoodPositions.isEmpty()) {
if (lastBlockPos == impetus.getBlockPos()) {
return new Result.Err<>(null);
} else if (!seenGoodPosSet.contains(impetus.getBlockPos())) {
// we can't enter from the side the directrix exits from, so this means we couldn't loop back.
// the last item we tried to examine will always be a terminal slate (b/c if it wasn't,
// then the *next* slate would be last qed)
return new Result.Err<>(seenGoodPositions.get(seenGoodPositions.size() - 1));
return new Result.Err<>(lastBlockPos);
}

var knownPositions = new HashSet<>(seenGoodPositions);
var reachedPositions = new ArrayList<BlockPos>();
reachedPositions.add(impetus.getBlockPos());
var start = seenGoodPositions.get(0);

seenGoodPosSet.add(impetus.getBlockPos());
FrozenPigment colorizer = null;
UUID casterUUID;
if (caster == null) {
Expand All @@ -142,8 +159,10 @@ protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, Set<Bl
casterUUID = caster.getUUID();
}
return new Result.Ok<>(
new CircleExecutionState(impetus.getBlockPos(), impetus.getStartDirection(), knownPositions,
reachedPositions, start, impetus.getStartDirection(), new CastingImage(), casterUUID, colorizer));
new CircleExecutionState(impetus.getBlockPos(), impetus.getStartDirection(),
seenGoodPosSet, impetus.getBlockPos().offset(impetus.getStartDirection().getNormal()),
impetus.getStartDirection(), new CastingImage(), casterUUID, colorizer, 0L,
positiveBlock.move(1,1,1), negativeBlock));
}

public CompoundTag save() {
Expand All @@ -152,12 +171,6 @@ public CompoundTag save() {
out.put(TAG_IMPETUS_POS, NbtUtils.writeBlockPos(this.impetusPos));
out.putByte(TAG_IMPETUS_DIR, (byte) this.impetusDir.ordinal());

var knownTag = new ListTag();
for (var bp : this.knownPositions) {
knownTag.add(NbtUtils.writeBlockPos(bp));
}
out.put(TAG_KNOWN_POSITIONS, knownTag);

var reachedTag = new ListTag();
for (var bp : this.reachedPositions) {
reachedTag.add(NbtUtils.writeBlockPos(bp));
Expand All @@ -174,19 +187,19 @@ public CompoundTag save() {
if (this.casterPigment != null)
out.put(TAG_PIGMENT, this.casterPigment.serializeToNBT());

out.putLong(TAG_REACHED_NUMBER, this.reachedSlate);

out.put(TAG_POSITIVE_POS,NbtUtils.writeBlockPos(this.positivePos));
out.put(TAG_NEGATIVE_POS,NbtUtils.writeBlockPos(this.negativePos));

return out;
}

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 knownTag = nbt.getList(TAG_KNOWN_POSITIONS, Tag.TAG_COMPOUND);
for (var tag : knownTag) {
knownPositions.add(NbtUtils.readBlockPos(HexUtils.downcast(tag, CompoundTag.TYPE)));
}
var reachedPositions = new ArrayList<BlockPos>();
var reachedPositions = new HashSet<BlockPos>();
var reachedTag = nbt.getList(TAG_REACHED_POSITIONS, Tag.TAG_COMPOUND);
for (var tag : reachedTag) {
reachedPositions.add(NbtUtils.readBlockPos(HexUtils.downcast(tag, CompoundTag.TYPE)));
Expand All @@ -196,6 +209,10 @@ public static CircleExecutionState load(CompoundTag nbt, ServerLevel world) {
var enteredFrom = Direction.values()[nbt.getByte(TAG_ENTERED_FROM)];
var image = CastingImage.loadFromNbt(nbt.getCompound(TAG_IMAGE), world);

var reachedSlate = nbt.getLong(TAG_REACHED_NUMBER);
var positivePos = NbtUtils.readBlockPos(nbt.getCompound(TAG_POSITIVE_POS));
var negativePos = NbtUtils.readBlockPos(nbt.getCompound(TAG_NEGATIVE_POS));

UUID caster = null;
if (nbt.hasUUID(TAG_CASTER))
caster = nbt.getUUID(TAG_CASTER);
Expand All @@ -204,8 +221,8 @@ public static CircleExecutionState load(CompoundTag nbt, ServerLevel world) {
if (nbt.contains(TAG_PIGMENT, Tag.TAG_COMPOUND))
pigment = FrozenPigment.fromNBT(nbt.getCompound(TAG_PIGMENT));

return new CircleExecutionState(startPos, startDir, knownPositions, reachedPositions, currentPos,
enteredFrom, image, caster, pigment);
return new CircleExecutionState(startPos, startDir, reachedPositions, currentPos,
enteredFrom, image, caster, pigment, reachedSlate, positivePos, negativePos);
}

/**
Expand All @@ -231,6 +248,7 @@ public boolean tick(BlockEntityAbstractImpetus impetus) {

executorBlockState = executor.startEnergized(this.currentPos, executorBlockState, world);
this.reachedPositions.add(this.currentPos);
this.reachedSlate +=1;

// Do the execution!
boolean halt = false;
Expand Down Expand Up @@ -289,7 +307,7 @@ public boolean tick(BlockEntityAbstractImpetus impetus) {
* How many ticks should pass between activations, given the number of blocks encountered so far.
*/
protected int getTickSpeed() {
return Math.max(2, 10 - (this.reachedPositions.size() - 1) / 3);
return Math.max(2, (int) (10 - (this.reachedSlate - 1) / 3));
}

public void endExecution(BlockEntityAbstractImpetus impetus) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ static void sfx(BlockPos pos, BlockState bs, Level world, BlockEntityAbstractImp
var state = impetus.getExecutionState();

// This is a good use of my time
var note = state.reachedPositions.size() - 1;
var semitone = impetus.semitoneFromScale(note);
var note = state.reachedSlate - 1;
var semitone = impetus.semitoneFromScale((int) note);
pitch = (float) Math.pow(2.0, (semitone - 8) / 12d);
}
world.playSound(null, vpos.x, vpos.y, vpos.z, sound, SoundSource.BLOCKS, 1f, pitch);
Expand Down