From 58bccebe31dc8fe56f2d09bac0aaf2f398afaf87 Mon Sep 17 00:00:00 2001
From: 0ffz <dan.voznyy@gmail.com>
Date: Fri, 14 Jan 2022 15:02:06 -0500
Subject: [PATCH] Fix missing methods with newer fastutil version + other
 bugfixes

---
 .../main/kotlin/geary.kotlin-conventions.gradle.kts |  2 +-
 .../com/mineinabyss/geary/ecs/api/GearyType.kt      |  4 ++--
 .../geary/ecs/api/entities/GearyEntity.kt           | 13 +++++++++++++
 .../geary/ecs/api/systems/TickingSystem.kt          |  4 ++--
 .../com/mineinabyss/geary/ecs/engine/GearyEngine.kt |  2 +-
 .../com/mineinabyss/geary/minecraft/GearyPlugin.kt  |  2 ++
 .../mineinabyss/geary/minecraft/dsl/GearyAddon.kt   |  3 ---
 .../geary/minecraft/engine/SpigotEngine.kt          | 13 ++++++++++++-
 8 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/geary-conventions/src/main/kotlin/geary.kotlin-conventions.gradle.kts b/geary-conventions/src/main/kotlin/geary.kotlin-conventions.gradle.kts
index f07b6d818..64c4180ef 100644
--- a/geary-conventions/src/main/kotlin/geary.kotlin-conventions.gradle.kts
+++ b/geary-conventions/src/main/kotlin/geary.kotlin-conventions.gradle.kts
@@ -15,7 +15,7 @@ repositories {
 object GearyDeps {
     val bimap = "com.uchuhimo:kotlinx-bimap:1.2"
     val bitvector = "net.onedaybeard.bitvector:bitvector-jvm:0.1.4"
-    val fastutil = "it.unimi.dsi:fastutil:8.5.4"
+    val fastutil = "it.unimi.dsi:fastutil:8.2.2" //Version on minecraft server
     val reflections = "org.reflections:reflections:0.9.12"
     val plugman = "com.rylinaux:PlugMan:2.2.5"
 }
diff --git a/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/GearyType.kt b/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/GearyType.kt
index ae669185e..6c1f2c4b2 100644
--- a/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/GearyType.kt
+++ b/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/GearyType.kt
@@ -30,7 +30,7 @@ public value class GearyType private constructor(
     public fun last(): GearyComponentId = inner.lastLong().toULong()
 
     public inline fun forEach(run: (GearyComponentId) -> Unit) {
-        val iterator = inner.longIterator()
+        val iterator = inner.iterator()
         while (iterator.hasNext()) {
             run(iterator.nextLong().toULong())
         }
@@ -42,7 +42,7 @@ public value class GearyType private constructor(
     }
 
     public inline fun forEachIndexed(run: (Int, GearyComponentId) -> Unit) {
-        val iterator = inner.longIterator()
+        val iterator = inner.iterator()
         var i = 0
         forEach { run(i++, iterator.nextLong().toULong()) }
     }
diff --git a/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/entities/GearyEntity.kt b/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/entities/GearyEntity.kt
index 5467d262f..827257359 100644
--- a/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/entities/GearyEntity.kt
+++ b/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/entities/GearyEntity.kt
@@ -108,6 +108,19 @@ public value class GearyEntity(public val id: GearyEntityId) {
     public fun removeRelation(relation: Relation): Boolean =
         remove(Relation.of(relation.key, relation.value).id)
 
+    /** Removes all relations with a value of type [V] on the entity. */
+    public inline fun <reified V : GearyComponent> removeRelationsByValue(): Set<GearyComponent> =
+        removeRelationsByValue(componentId<V>())
+
+    /** Removes all relations with a value with id [componentId] on the entity. */
+    public fun removeRelationsByValue(componentId: GearyComponentId): Set<GearyComponent> {
+        val comps = Engine.getRelationsFor(this, RelationValueId(componentId))
+        comps.forEach { (_, relation) ->
+            removeRelation(relation)
+        }
+        return comps.mapTo(mutableSetOf()) { it.first }
+    }
+
     /**
      * Adds a [component] to this entity's type, setting no data.
      *
diff --git a/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/systems/TickingSystem.kt b/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/systems/TickingSystem.kt
index ac6dda830..176484b5e 100644
--- a/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/systems/TickingSystem.kt
+++ b/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/api/systems/TickingSystem.kt
@@ -3,8 +3,8 @@ package com.mineinabyss.geary.ecs.api.systems
 import com.mineinabyss.geary.ecs.accessors.TargetScope
 import com.mineinabyss.geary.ecs.engine.ArchetypeIterator
 import com.mineinabyss.geary.ecs.query.Query
+import com.mineinabyss.idofront.time.ticks
 import kotlin.time.Duration
-import kotlin.time.Duration.Companion.milliseconds
 
 /**
  * #### [Guide: Ticking systems](https://wiki.mineinabyss.com/geary/guide/ticking-systems)
@@ -16,7 +16,7 @@ import kotlin.time.Duration.Companion.milliseconds
  * @see [ArchetypeIterator]
  */
 public abstract class TickingSystem(
-    public val interval: Duration = 20.milliseconds,
+    public val interval: Duration = 1.ticks,
     init: (TickingSystem.() -> Unit)? = null
 ) : Query(), GearySystem {
     protected var iteration: Int = 0
diff --git a/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/engine/GearyEngine.kt b/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/engine/GearyEngine.kt
index a2ade972f..c3ff6a53a 100644
--- a/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/engine/GearyEngine.kt
+++ b/geary-core/src/main/kotlin/com/mineinabyss/geary/ecs/engine/GearyEngine.kt
@@ -235,7 +235,7 @@ public open class GearyEngine : TickingEngine() {
 
     override fun tick(currentTick: Long) {
         registeredSystems
-            .filter { currentTick % it.interval.inWholeTicks == 0L }
+            .filter { currentTick % it.interval.inWholeTicks.coerceAtLeast(1) == 0L }
             .forEach {
                 try {
                     it.runSystem()
diff --git a/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/GearyPlugin.kt b/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/GearyPlugin.kt
index 2dd465cbd..8fac0b525 100644
--- a/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/GearyPlugin.kt
+++ b/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/GearyPlugin.kt
@@ -25,6 +25,8 @@ import java.util.*
 import kotlin.io.path.div
 import kotlin.reflect.KClass
 
+public val gearyPlugin: GearyPlugin = Bukkit.getPluginManager().getPlugin("Geary") as GearyPlugin
+
 public class GearyPlugin : JavaPlugin() {
     override fun onLoad() {
         IdofrontPlatforms.load(this, "mineinabyss")
diff --git a/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/dsl/GearyAddon.kt b/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/dsl/GearyAddon.kt
index 6f18a6329..ca59e9d6d 100644
--- a/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/dsl/GearyAddon.kt
+++ b/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/dsl/GearyAddon.kt
@@ -10,7 +10,6 @@ import com.mineinabyss.geary.ecs.serialization.Formats
 import com.mineinabyss.geary.minecraft.access.BukkitEntityAssociations
 import com.mineinabyss.geary.prefabs.PrefabKey
 import com.mineinabyss.geary.prefabs.PrefabManager
-import com.mineinabyss.idofront.plugin.registerEvents
 import kotlinx.serialization.InternalSerializationApi
 import kotlinx.serialization.KSerializer
 import kotlinx.serialization.Serializable
@@ -20,7 +19,6 @@ import kotlinx.serialization.modules.SerializersModuleBuilder
 import kotlinx.serialization.modules.polymorphic
 import kotlinx.serialization.serializerOrNull
 import org.bukkit.entity.Entity
-import org.bukkit.event.Listener
 import org.bukkit.plugin.Plugin
 import java.io.File
 import kotlin.reflect.KClass
@@ -145,7 +143,6 @@ public class GearyAddon(
 
     /** Registers a list of [systems]. */
     public fun systems(vararg systems: GearySystem) {
-        plugin.registerEvents(*systems.filterIsInstance<Listener>().toTypedArray())
         systems.forEach { system(it) }
     }
 
diff --git a/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/engine/SpigotEngine.kt b/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/engine/SpigotEngine.kt
index bfd8a3086..41f18cd5e 100644
--- a/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/engine/SpigotEngine.kt
+++ b/platforms/geary-platform-papermc/src/main/kotlin/com/mineinabyss/geary/minecraft/engine/SpigotEngine.kt
@@ -2,14 +2,18 @@ package com.mineinabyss.geary.minecraft.engine
 
 import co.aikar.timings.Timings
 import com.mineinabyss.geary.ecs.api.entities.GearyEntity
+import com.mineinabyss.geary.ecs.api.systems.GearySystem
 import com.mineinabyss.geary.ecs.api.systems.TickingSystem
 import com.mineinabyss.geary.ecs.engine.GearyEngine
 import com.mineinabyss.geary.minecraft.GearyPlugin
 import com.mineinabyss.geary.minecraft.events.GearyEntityRemoveEvent
+import com.mineinabyss.geary.minecraft.gearyPlugin
 import com.mineinabyss.idofront.events.call
+import com.mineinabyss.idofront.plugin.registerEvents
 import com.okkero.skedule.schedule
 import org.bukkit.Bukkit
 import org.bukkit.NamespacedKey
+import org.bukkit.event.Listener
 import java.util.*
 
 public class SpigotEngine : GearyEngine() {
@@ -28,6 +32,13 @@ public class SpigotEngine : GearyEngine() {
         }.getOrThrow()
     }
 
+    override fun addSystem(system: GearySystem) {
+        super.addSystem(system)
+
+        if (system is Listener)
+            gearyPlugin.registerEvents(system)
+    }
+
     override fun scheduleSystemTicking() {
         //tick all systems every interval ticks
         GearyPlugin.instance.schedule {
@@ -41,7 +52,7 @@ public class SpigotEngine : GearyEngine() {
 
     override fun removeEntity(entity: GearyEntity) {
         if (entity.has<UUID>())
-            //TODO this should be unnecessary now
+        //TODO this should be unnecessary now
             GearyEntityRemoveEvent(entity).call()
         super.removeEntity(entity)
     }