Skip to content

Commit

Permalink
implement directional nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
Gutin1 committed Sep 23, 2024
1 parent 7371232 commit 88345d6
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.horizonsend.ion.server.features.transport.node.type.power

import net.horizonsend.ion.server.features.transport.node.NodeType
import net.horizonsend.ion.server.features.transport.node.TransportNode
import net.horizonsend.ion.server.features.transport.node.manager.PowerNodeManager
import net.horizonsend.ion.server.features.transport.node.type.general.LinearNode
import net.horizonsend.ion.server.miscellaneous.utils.axis
Expand All @@ -11,12 +12,14 @@ import net.horizonsend.ion.server.miscellaneous.utils.coordinates.getZ
import net.horizonsend.ion.server.miscellaneous.utils.getBlockDataSafe
import org.bukkit.block.data.Directional

class EndRodNode(network: PowerNodeManager) : LinearNode<PowerNodeManager, EndRodNode, EndRodNode>(network) {
class EndRodNode(network: PowerNodeManager) : LinearNode<PowerNodeManager, EndRodNode, EndRodNode>(network), PowerPathfindingNode {
override val type: NodeType = NodeType.END_ROD_NODE

override fun addBack(position: BlockKey) {
val data = getBlockDataSafe(manager.world, getX(position), getY(position), getZ(position)) as? Directional ?: return

manager.nodeFactory.addLinearNode<EndRodNode>(position, data.facing.axis, type, handleRelationships = false)
}

override fun getNextNodes(previous: TransportNode): ArrayDeque<TransportNode> = cachedTransferable
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,13 @@ import net.horizonsend.ion.server.features.transport.node.TransportNode
import net.horizonsend.ion.server.features.transport.node.manager.PowerNodeManager
import net.horizonsend.ion.server.features.transport.node.type.SingleNode
import net.horizonsend.ion.server.miscellaneous.registrations.persistence.NamespacedKeys
import net.horizonsend.ion.server.miscellaneous.utils.coordinates.BlockKey
import org.bukkit.block.BlockFace
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType

class InvertedDirectionalNode(override val manager: PowerNodeManager) : SingleNode() {
class InvertedDirectionalNode(override val manager: PowerNodeManager) : SingleNode(), PowerPathfindingNode {
override val type: NodeType = NodeType.POWER_INVERSE_DIRECTIONAL_NODE

constructor(network: PowerNodeManager, position: BlockKey) : this(network) {
this.position = position
}

override fun isTransferableTo(node: TransportNode): Boolean {
if (node is EndRodNode) return false
return node !is PowerExtractorNode && node !is SolarPanelNode
Expand All @@ -32,4 +28,18 @@ class InvertedDirectionalNode(override val manager: PowerNodeManager) : SingleNo
override fun getPathfindingResistance(previousNode: TransportNode?, nextNode: TransportNode?): Int {
return 1
}

override fun getNextNodes(previous: TransportNode): ArrayDeque<TransportNode> {
// Since this is a single node, and the previous node must be transferable to this, it can't be a sponge.
// So there will likely only be a single relation to this
val direction = previous.getRelationshipWith(this).values
if (direction.isEmpty()) return cachedTransferable // just in case
val face = direction.first().offset

getForwardTransferable(face)?.let { return ArrayDeque(listOf(it)) }

return cachedTransferable
}

fun getForwardTransferable(incoming: BlockFace): TransportNode? = relationships.values.firstOrNull { it.offset == incoming.oppositeFace && it.canTransfer }?.other
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import net.horizonsend.ion.server.features.transport.node.TransportNode
import net.horizonsend.ion.server.features.transport.node.manager.PowerNodeManager
import net.horizonsend.ion.server.features.transport.node.type.SingleNode
import net.horizonsend.ion.server.miscellaneous.registrations.persistence.NamespacedKeys
import net.horizonsend.ion.server.miscellaneous.utils.ADJACENT_BLOCK_FACES
import net.horizonsend.ion.server.miscellaneous.utils.coordinates.BlockKey
import org.bukkit.Material
import org.bukkit.block.BlockFace
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
import kotlin.properties.Delegates

class PowerDirectionalNode(override val manager: PowerNodeManager) : SingleNode() {
class PowerDirectionalNode(override val manager: PowerNodeManager) : SingleNode(), PowerPathfindingNode {
override val type: NodeType = NodeType.POWER_DIRECTIONAL_NODE
private var variant: Material by Delegates.notNull()

Expand Down Expand Up @@ -43,4 +45,23 @@ class PowerDirectionalNode(override val manager: PowerNodeManager) : SingleNode(
override fun getPathfindingResistance(previousNode: TransportNode?, nextNode: TransportNode?): Int {
return 1
}

override fun getNextNodes(previous: TransportNode): ArrayDeque<TransportNode> {
// Since this is a single node, and the previous node must be transferable to this, it can't be a sponge.
// So there will likely only be a single relation to this
val direction = previous.getRelationshipWith(this).values
if (direction.isEmpty()) return cachedTransferable
val face = direction.first().offset

getForwardTransferable(face)?.let { return ArrayDeque(listOf(it)) }

return cachedTransferable
}

fun getForwardTransferable(incoming: BlockFace): TransportNode? = relationships.values.firstOrNull { it.offset == incoming.oppositeFace && it.canTransfer }?.other

override fun toString(): String {
val face = ADJACENT_BLOCK_FACES.random()
return "directional: $face is ${getForwardTransferable(face)}, $cachedTransferable"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
import kotlin.math.roundToInt

class PowerExtractorNode(override val manager: PowerNodeManager) : SingleNode() {
class PowerExtractorNode(override val manager: PowerNodeManager) : SingleNode(), PowerPathfindingNode {
override val type: NodeType = NodeType.POWER_EXTRACTOR_NODE

constructor(network: PowerNodeManager, position: BlockKey) : this(network) {
Expand Down Expand Up @@ -101,5 +101,7 @@ class PowerExtractorNode(override val manager: PowerNodeManager) : SingleNode()
override fun toString(): String {
return "Extractor. found, can trasnsfer: ${getTransferPower()}"
}

override fun getNextNodes(previous: TransportNode): ArrayDeque<TransportNode> = cachedTransferable
}

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import org.bukkit.block.BlockFace.NORTH
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType

class PowerFlowMeter(override val manager: PowerNodeManager) : SingleNode() {
class PowerFlowMeter(override val manager: PowerNodeManager) : SingleNode(), PowerPathfindingNode {
override val type: NodeType = NodeType.POWER_FLOW_METER
constructor(network: PowerNodeManager, position: BlockKey, direction: BlockFace) : this(network) {
this.position = position
Expand Down Expand Up @@ -108,7 +108,7 @@ class PowerFlowMeter(override val manager: PowerNodeManager) : SingleNode() {
}

override fun onPlace(position: BlockKey) {
setupDisplayEntity()
runCatching { setupDisplayEntity() }

super.onPlace(position)
}
Expand All @@ -134,4 +134,6 @@ class PowerFlowMeter(override val manager: PowerNodeManager) : SingleNode() {
override fun getPathfindingResistance(previousNode: TransportNode?, nextNode: TransportNode?): Int {
return 1
}

override fun getNextNodes(previous: TransportNode): ArrayDeque<TransportNode> = cachedTransferable
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import net.horizonsend.ion.server.features.transport.node.manager.PowerNodeManag
import net.horizonsend.ion.server.features.transport.node.type.SingleNode
import net.horizonsend.ion.server.miscellaneous.registrations.persistence.NamespacedKeys.NODE_COVERED_POSITIONS
import net.horizonsend.ion.server.miscellaneous.utils.ADJACENT_BLOCK_FACES
import net.horizonsend.ion.server.miscellaneous.utils.coordinates.BlockKey
import net.horizonsend.ion.server.miscellaneous.utils.coordinates.getRelative
import net.horizonsend.ion.server.miscellaneous.utils.coordinates.getX
import net.horizonsend.ion.server.miscellaneous.utils.coordinates.getY
Expand All @@ -19,15 +18,8 @@ import org.bukkit.block.data.type.WallSign
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType

class PowerInputNode(override val manager: PowerNodeManager) : SingleNode() {
class PowerInputNode(override val manager: PowerNodeManager) : SingleNode(), PowerPathfindingNode {
override val type: NodeType = NodeType.POWER_INPUT_NODE
constructor(network: PowerNodeManager, position: BlockKey) : this(network) {
this.position = position
}

override fun isTransferableTo(node: TransportNode): Boolean {
return false
}

override fun storeData(persistentDataContainer: PersistentDataContainer) {
persistentDataContainer.set(NODE_COVERED_POSITIONS, PersistentDataType.LONG, position)
Expand Down Expand Up @@ -92,5 +84,13 @@ class PowerInputNode(override val manager: PowerNodeManager) : SingleNode() {
return 0
}

override fun getNextNodes(previous: TransportNode): ArrayDeque<TransportNode> {
return ArrayDeque(0) // Can't transfer to anything
}

override fun isTransferableTo(node: TransportNode): Boolean {
return false
}

override fun toString(): String = "POWER INPUT NODE. Bound to ${getPoweredEntities().joinToString { it.toString() }}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package net.horizonsend.ion.server.features.transport.node.type.power

import net.horizonsend.ion.server.features.transport.node.TransportNode

interface PowerPathfindingNode {
/**
* For use in pathfinding. When entering from previous node, get the list of available next nodes. Mostly used by the flood fill.
**/
fun getNextNodes(previous: TransportNode): ArrayDeque<TransportNode>
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ import java.util.function.Consumer
/**
* Represents a solar panel, or multiple
**/
class SolarPanelNode(
override val manager: PowerNodeManager
) : MultiNode<SolarPanelNode, SolarPanelNode>() {
class SolarPanelNode(override val manager: PowerNodeManager) : MultiNode<SolarPanelNode, SolarPanelNode>(), PowerPathfindingNode {
override val type: NodeType = NodeType.SOLAR_PANEL_NODE
/** The positions of extractors in this solar panel */
private val extractorPositions = ConcurrentHashMap.newKeySet<BlockKey>()
Expand Down Expand Up @@ -264,6 +262,8 @@ class SolarPanelNode(
}
}

override fun getNextNodes(previous: TransportNode): ArrayDeque<TransportNode> = cachedTransferable

override fun toString(): String = "(SOLAR PANEL NODE:" +
" Transferable to: ${getTransferableNodes().joinToString { it.javaClass.simpleName }} nodes, " +
"distance = $exitDistance," +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package net.horizonsend.ion.server.features.transport.node.type.power

import net.horizonsend.ion.server.features.transport.node.NodeType
import net.horizonsend.ion.server.features.transport.node.NodeType.SPONGE_NODE
import net.horizonsend.ion.server.features.transport.node.TransportNode
import net.horizonsend.ion.server.features.transport.node.manager.PowerNodeManager
import net.horizonsend.ion.server.features.transport.node.type.general.JunctionNode
import net.horizonsend.ion.server.miscellaneous.utils.coordinates.BlockKey
Expand All @@ -12,16 +13,14 @@ import net.horizonsend.ion.server.miscellaneous.utils.coordinates.toVec3i
*
* Since there is no use in keeping the individual steps, all touching sponges are consolidated into a single node with multiple inputs / outputs, weighted evenly
**/
class SpongeNode(network: PowerNodeManager) : JunctionNode<PowerNodeManager, SpongeNode, SpongeNode>(network) {
class SpongeNode(network: PowerNodeManager) : JunctionNode<PowerNodeManager, SpongeNode, SpongeNode>(network), PowerPathfindingNode {
override val type: NodeType = SPONGE_NODE

constructor(network: PowerNodeManager, origin: BlockKey) : this(network) {
positions.add(origin)
}

override fun addBack(position: BlockKey) {
manager.nodeFactory.addJunctionNode<SpongeNode>(position, type, handleRelationships = false)
}

override fun getNextNodes(previous: TransportNode): ArrayDeque<TransportNode> = cachedTransferable

override fun toString(): String = "(SPONGE NODE: ${positions.size} positions, Transferable to: ${getTransferableNodes().joinToString { it.javaClass.simpleName }} nodes) location = ${toVec3i(positions.random())}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package net.horizonsend.ion.server.features.transport.node.util

import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import net.horizonsend.ion.server.features.transport.node.TransportNode
import net.horizonsend.ion.server.features.transport.node.type.power.PowerPathfindingNode
import kotlin.math.roundToInt

inline fun <reified T: TransportNode> getNetworkDestinations(origin: TransportNode, check: (T) -> Boolean): ObjectOpenHashSet<T> {
Expand Down Expand Up @@ -40,9 +41,7 @@ fun getIdealPath(from: TransportNode, to: TransportNode): Array<TransportNode>?
iterations++
val current = queue.minBy { it.f }

if (current.node == to) {
return current.buildPath()
}
if (current.node == to) return current.buildPath()

queue.remove(current)
visited.add(current)
Expand All @@ -68,7 +67,11 @@ fun getIdealPath(from: TransportNode, to: TransportNode): Array<TransportNode>?

// Wraps neighbor nodes in a data class to store G and F values for pathfinding. Should probably find a better solution
private fun getNeighbors(parent: PathfindingNodeWrapper): Array<PathfindingNodeWrapper> {
val transferable = parent.node.cachedTransferable
val parentParent = parent.parent
val transferable = if (parentParent != null && parent.node is PowerPathfindingNode) {
parent.node.getNextNodes(parentParent.node)
} else parent.node.cachedTransferable

return Array(transferable.size) {
val neighbor = transferable[it]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,10 @@ object DataFixers: IonServerComponent() {
chunk.dataVersion = chunkDataFixer.dataVersion
}

return
SignFixerEntrance.iterateChunk(chunk)
}

fun handleMultiblockEntityLoad() {
//TODO
}

fun handleMultiblockSignLoad(sign: Sign) {
val dataVersion = sign.persistentDataContainer.getOrDefault(DATA_VERSION, INTEGER, 0)

Expand Down

0 comments on commit 88345d6

Please sign in to comment.