-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace the lamps' mob-killing logic with mob-blocking logic.
- Loading branch information
Showing
8 changed files
with
245 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
src/main/java/mods/eln/eventhandlers/MonsterEventHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package mods.eln.eventhandlers | ||
|
||
import mods.eln.entity.ReplicatorEntity | ||
import mods.eln.misc.Coordonate | ||
import mods.eln.misc.OctoTree | ||
import net.minecraft.entity.boss.EntityWither | ||
import net.minecraftforge.event.entity.EntityJoinWorldEvent | ||
import kotlin.math.roundToInt | ||
|
||
/** | ||
* This is not an efficient way to do anything. | ||
* | ||
* The octree is a good start. It's fine in terms of CPU use, more or less, but that memory use scares me and is | ||
* also entirely pointless. I'll have to find (or invent) a better algorithm. Though, the octree implementation | ||
* supports clusterization so... maybe that's at least partially fine? | ||
* | ||
* It's also far too easy to imagine this counter getting desynced from reality. | ||
* Although it seems to be working so far. | ||
*/ | ||
|
||
object MonsterEventHandler { | ||
private val trees: MutableMap<Int, OctoTree<Int>> = HashMap() | ||
|
||
fun onSpawn(event: EntityJoinWorldEvent) { | ||
val entity = event.entity | ||
if (entity is ReplicatorEntity || entity is EntityWither) { | ||
return | ||
} | ||
val x = entity.posX.roundToInt() + 32768 | ||
val y = entity.posY.roundToInt() + 32768 | ||
val z = entity.posZ.roundToInt() + 32768 | ||
if (trees[entity.dimension]?.get(x, y, z) ?: 0 > 0) { | ||
event.isCanceled = true | ||
} | ||
} | ||
|
||
private fun doCube(center: Coordonate, range: Int, f: (Int) -> Int) { | ||
if (range <= 0) return | ||
val xOffset = center.x + 32768 | ||
val yOffset = center.y + 32768 | ||
val zOffset = center.z + 32768 | ||
val tree = trees.getOrPut(center.dimention) { OctoTree(16) } | ||
for (x in (xOffset - range)..(xOffset + range)) { | ||
for (y in (yOffset - range)..(yOffset + range)) { | ||
for (z in (zOffset - range)..(zOffset + range)) { | ||
tree.set(x, y, z, f(tree.get(x, y, z) ?: 0)) | ||
} | ||
} | ||
} | ||
} | ||
|
||
fun registerMonsterBlock(coord: Coordonate, range: Int) { | ||
println("Registering block at $coord - $range") | ||
doCube(coord, range) { it + 1 } | ||
} | ||
|
||
fun unregisterMonsterBlock(coord: Coordonate, range: Int) { | ||
println("Unregistering block at $coord - $range") | ||
doCube(coord, range) { Math.max(0, it - 1) } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
package mods.eln.misc | ||
|
||
// Licensed under Apache 2.0 | ||
// Copyright JetBrains, 2017 | ||
|
||
class OctoTree<T>(val depth: Int) { | ||
|
||
private var root: Node<T>? = null | ||
private var actual = false | ||
|
||
//-------------------------------------------------------------------------// | ||
|
||
fun get(x: Int, y: Int, z: Int): T? { | ||
var dep = depth | ||
var iter = root | ||
while (true) { | ||
if (iter == null) return null | ||
else if (iter is Node.Leaf) return iter.value | ||
|
||
iter = (iter as Node.Branch<T>).nodes[number(x, y, z, --dep)] | ||
} | ||
} | ||
|
||
//-------------------------------------------------------------------------// | ||
|
||
fun set(x: Int, y: Int, z: Int, value: T) { | ||
if (root == null) root = Node.Branch() | ||
if (root!!.set(x, y, z, value, depth - 1)) { | ||
root = Node.Leaf(value) | ||
} | ||
actual = false | ||
} | ||
|
||
//-------------------------------------------------------------------------// | ||
|
||
override fun toString(): String = root.toString() | ||
|
||
//-------------------------------------------------------------------------// | ||
|
||
sealed class Node<T> { | ||
|
||
abstract fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean | ||
|
||
//---------------------------------------------------------------------// | ||
|
||
class Leaf<T>(var value: T) : Node<T>() { | ||
|
||
override fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean { | ||
throw UnsupportedOperationException("set on Leaf element") | ||
} | ||
|
||
override fun toString(): String = "L{$value}" | ||
} | ||
|
||
//---------------------------------------------------------------------// | ||
|
||
class Branch<T>() : Node<T>() { | ||
|
||
constructor(value: T, exclude: Int) : this() { | ||
|
||
var i = 0 | ||
while (i < 8) { | ||
if (i != exclude) { | ||
nodes[i] = Leaf(value) | ||
} | ||
i++ | ||
} | ||
} | ||
|
||
private fun canClusterize(value: T): Boolean { | ||
var i = 0 | ||
while (i < 8) { | ||
val w = nodes[i] | ||
if (w == null || w !is Leaf || value != w.value) { | ||
return false | ||
} | ||
i++ | ||
} | ||
return true | ||
} | ||
|
||
override fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean { | ||
val branchIndex = number(x, y, z, depth) | ||
val node = nodes[branchIndex] | ||
when (node) { | ||
null -> { | ||
if (depth == 0) { | ||
nodes[branchIndex] = Leaf(value) | ||
return canClusterize(value) | ||
} else { | ||
nodes[branchIndex] = Branch() | ||
} | ||
} | ||
is Leaf<T> -> { | ||
if (node.value == value) { | ||
return false | ||
} else if (depth == 0) { | ||
node.value = value | ||
return canClusterize(value) | ||
} | ||
nodes[branchIndex] = Branch(node.value, number(x, y, z, depth - 1)) | ||
} | ||
} | ||
|
||
if (nodes[branchIndex]!!.set(x, y, z, value, depth - 1)) { | ||
nodes[branchIndex] = Leaf(value) | ||
return canClusterize(value) | ||
} | ||
return false | ||
} | ||
|
||
val nodes = arrayOfNulls<Node<T>>(8) | ||
override fun toString(): String = nodes.joinToString(prefix = "[", postfix = "]") | ||
} | ||
} | ||
//-------------------------------------------------------------------------// | ||
|
||
companion object { | ||
fun number(x: Int, y: Int, z: Int, depth: Int): Int { | ||
val mask = 1 shl depth | ||
if (x and mask != 0) { | ||
if (y and mask != 0) { | ||
if (z and mask != 0) | ||
return 7 | ||
return 6 | ||
} | ||
if (z and mask != 0) | ||
return 5 | ||
return 4 | ||
} | ||
if (y and mask != 0) { | ||
if (z and mask != 0) | ||
return 3 | ||
return 2 | ||
} | ||
if (z and mask != 0) | ||
return 1 | ||
return 0 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.