Skip to content
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 @@ -4,13 +4,24 @@
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nullable;
import java.util.Map;

import static at.petrak.hexcasting.api.casting.circles.CircleExecutionState.CACHE;

// Convenience impl of ICircleComponent
public abstract class BlockCircleComponent extends Block implements ICircleComponent {
Expand All @@ -28,6 +39,27 @@ public BlockState startEnergized(BlockPos pos, BlockState bs, Level world) {
return newState;
}

@Override
public void destroy(@NotNull LevelAccessor world, @NotNull BlockPos blockPos, @NotNull BlockState blockState) {
// spaghet
for (Map.Entry<BlockPos, AABB> entry : CACHE.entrySet()) {
Vec3 location = blockPos.getCenter();
if (!entry.getValue().contains(location)) {continue;}
CACHE.remove(entry.getKey());
}
}

@Override
public void setPlacedBy(Level level, BlockPos blockPos, BlockState bs, @Nullable LivingEntity entity, ItemStack stack) {
for (Map.Entry<BlockPos, AABB> entry : CACHE.entrySet()) {
Vec3 location = blockPos.getCenter();
AABB aabb = entry.getValue();
if (!aabb.contains(location)) {continue;}
if (aabb.distanceToSqr(location) > 0.250009) {continue;}
CACHE.remove(entry.getKey());
}
}

@Override
public boolean isEnergized(BlockPos pos, BlockState bs, Level world) {
return bs.getValue(ENERGIZED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package at.petrak.hexcasting.api.casting

import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.*
import at.petrak.hexcasting.api.casting.math.HexPattern
import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidIota
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* See {@link BlockEntityAbstractImpetus}, this is what's stored in it
Expand All @@ -42,6 +43,9 @@ public class CircleExecutionState {
TAG_POSITIVE_POS = "positive_pos",
TAG_NEGATIVE_POS = "negative_pos";

// A cache for reusing previous searches. Invalidated when ICircleComponents are broken within the AABB.
public static final Map<BlockPos, AABB> CACHE = new ConcurrentHashMap<>();

public final BlockPos impetusPos;
public final Direction impetusDir;
// Does contain the starting impetus
Expand Down Expand Up @@ -107,6 +111,31 @@ protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, HashSe
var positiveBlock = impetusPos.mutable();
var negativeBlock = impetusPos.mutable();
var lastBlockPos = impetusPos.mutable();
var reachedPositions = new HashSet<BlockPos>();
reachedPositions.add(impetus.getBlockPos());

FrozenPigment colorizer = null;
UUID casterUUID;
if (caster == null) {
casterUUID = null;
} else {
colorizer = HexAPI.instance().getColorizer(caster);
casterUUID = caster.getUUID();
}

if (CACHE.containsKey(impetusPos)) {
final AABB bounds = CACHE.get(impetusPos);
BlockPos greater = new BlockPos((int) bounds.maxX, (int) bounds.maxY, (int) bounds.maxZ);
BlockPos lesser = new BlockPos((int) bounds.minX, (int) bounds.minY, (int) bounds.minZ);

return new Result.Ok<>(
new CircleExecutionState(
impetus.getBlockPos(), impetus.getStartDirection(), reachedPositions,
impetusPos.offset(impetus.getStartDirection().getNormal()), impetus.getStartDirection(),
new CastingImage(), casterUUID, colorizer, 0L, greater, lesser
)
);
}

while (!todo.isEmpty()) {
var pair = todo.pop();
Expand All @@ -133,6 +162,7 @@ protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, HashSe
negativeBlock.setZ(Math.min(herePos.getZ(), negativeBlock.getZ()));
// it's new
var outs = cmp.possibleExitDirections(herePos, hereBs, level);

for (var out : outs) {
todo.add(Pair.of(out, herePos.relative(out)));
}
Expand All @@ -152,17 +182,10 @@ protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, HashSe
return new Result.Err<>(lastBlockPos);
}

var reachedPositions = new HashSet<BlockPos>();
reachedPositions.add(impetus.getBlockPos());
AABB aabb = new AABB(positiveBlock.move(1,1,1), negativeBlock);

CACHE.put(impetusPos, aabb);

FrozenPigment colorizer = null;
UUID casterUUID;
if (caster == null) {
casterUUID = null;
} else {
colorizer = HexAPI.instance().getColorizer(caster);
casterUUID = caster.getUUID();
}
return new Result.Ok<>(
new CircleExecutionState(impetus.getBlockPos(), impetus.getStartDirection(),
reachedPositions, impetus.getBlockPos().offset(impetus.getStartDirection().getNormal()),
Expand Down