1
0
mirror of https://github.com/chylex/Hardcore-Ender-Expansion-2.git synced 2025-03-16 11:15:42 +01:00

Refactor BlockPuzzleLogic to use the new flood-fill extension

This commit is contained in:
chylex 2019-10-16 16:01:52 +02:00
parent b92e64b743
commit f0ce92a9f4
2 changed files with 12 additions and 35 deletions
src/main/java/chylex/hee/game

View File

@ -11,7 +11,9 @@ import chylex.hee.system.migration.forge.Sided
import chylex.hee.system.util.allInCenteredBox
import chylex.hee.system.util.color.IntColor.Companion.RGB
import chylex.hee.system.util.facades.Facing4
import chylex.hee.system.util.floodFill
import chylex.hee.system.util.get
import chylex.hee.system.util.getBlock
import chylex.hee.system.util.getState
import chylex.hee.system.util.setState
import chylex.hee.system.util.with
@ -28,7 +30,6 @@ import net.minecraft.util.IStringSerializable
import net.minecraft.util.math.BlockPos
import net.minecraft.world.IBlockAccess
import net.minecraft.world.World
import java.util.Stack
sealed class BlockPuzzleLogic(builder: BlockBuilder) : BlockSimple(builder){
companion object{
@ -37,31 +38,8 @@ sealed class BlockPuzzleLogic(builder: BlockBuilder) : BlockSimple(builder){
const val UPDATE_RATE = 7
const val MAX_SIZE = 20
fun findAllBlocks(world: World, pos: BlockPos): List<Pair<BlockPos, IBlockState>>{
val found = mutableListOf<Pair<BlockPos, IBlockState>>()
val stack = Stack<BlockPos>().apply { push(pos) }
val visited = mutableSetOf(pos)
while(stack.isNotEmpty()){
val current = stack.pop()
val state = current.getState(world)
if (state.block is BlockPuzzleLogic && state[STATE] != DISABLED){
found.add(current to state)
for(facing in Facing4){
val offset = current.offset(facing)
if (!visited.contains(offset)){
stack.push(offset)
visited.add(offset)
}
}
}
}
return found
fun findAllBlocks(world: World, pos: BlockPos): List<BlockPos>{
return pos.floodFill(Facing4){ it.getState(world).let { state -> state.block is BlockPuzzleLogic && state[STATE] != DISABLED } }
}
private fun makePair(pos: BlockPos, facing: EnumFacing): Pair<BlockPos, EnumFacing>{
@ -172,7 +150,7 @@ sealed class BlockPuzzleLogic(builder: BlockBuilder) : BlockSimple(builder){
class Teleport(builder: BlockBuilder) : BlockPuzzleLogic(builder){
override fun getNextChains(world: World, pos: BlockPos, facing: EnumFacing): List<Pair<BlockPos, EnumFacing>>{
return findAllBlocks(world, pos).filter { it.first != pos && it.second.block is Teleport }.map { makePair(it.first, facing) }
return findAllBlocks(world, pos).filter { it != pos && it.getBlock(world) is Teleport }.map { makePair(it, facing) }
}
}

View File

@ -19,7 +19,6 @@ import chylex.hee.system.util.setPos
import chylex.hee.system.util.setState
import chylex.hee.system.util.totalTime
import chylex.hee.system.util.with
import net.minecraft.block.state.IBlockState
import net.minecraft.entity.item.EntityItem
import net.minecraft.item.ItemStack
import net.minecraft.util.EnumFacing
@ -99,13 +98,13 @@ class EntityTechnicalPuzzle(world: World) : EntityTechnicalBase(world){
}
}
private fun isBlockingSolution(allBlocks: List<Pair<BlockPos, IBlockState>>, other: EntityTechnicalPuzzle): Boolean{
private fun isBlockingSolution(allBlocks: List<BlockPos>, other: EntityTechnicalPuzzle): Boolean{
if (other.isDead){
return false
}
val entityPos = Pos(other)
return allBlocks.any { (pos, _) -> pos == entityPos }
return allBlocks.any { it == entityPos }
}
fun startChain(pos: BlockPos, facing: EnumFacing): Boolean{
@ -128,15 +127,15 @@ class EntityTechnicalPuzzle(world: World) : EntityTechnicalBase(world){
val allBlocks = BlockPuzzleLogic.findAllBlocks(world, startPos)
val entityArea = BlockPuzzleLogic.MAX_SIZE.toDouble().let { AxisAlignedBB(startPos).grow(it, 0.0, it) }
if (world.selectEntities.inBox<EntityTechnicalPuzzle>(entityArea).any { isBlockingSolution(allBlocks, it) }){
if (allBlocks.isEmpty() || world.selectEntities.inBox<EntityTechnicalPuzzle>(entityArea).any { isBlockingSolution(allBlocks, it) }){
return
}
if (allBlocks.isNotEmpty() && allBlocks.all { it.second[BlockPuzzleLogic.STATE] == BlockPuzzleLogic.State.ACTIVE }){
allBlocks.forEach { it.first.setState(world, it.second.with(BlockPuzzleLogic.STATE, BlockPuzzleLogic.State.DISABLED)) }
if (allBlocks.all { it.getState(world)[BlockPuzzleLogic.STATE] == BlockPuzzleLogic.State.ACTIVE }){
allBlocks.forEach { it.setState(world, it.getState(world).with(BlockPuzzleLogic.STATE, BlockPuzzleLogic.State.DISABLED)) }
val min = allBlocks.fold(allBlocks[0].first){ acc, (pos, _) -> acc.min(pos) }
val max = allBlocks.fold(allBlocks[0].first){ acc, (pos, _) -> acc.max(pos) }
val min = allBlocks.reduce(BlockPos::min)
val max = allBlocks.reduce(BlockPos::max)
// TODO will need to be adjusted for different shapes
// TODO fx