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:
parent
b92e64b743
commit
f0ce92a9f4
src/main/java/chylex/hee/game
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user