Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 44 additions & 4 deletions src/main/kotlin/org/cobalt/event/EventBus.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,50 @@ object EventBus {
handlers.addAll(toAdd)
dispatchCache.clear()
}
/**
* Alternative to the [SubscribeEvent] annotation for people that are either too lazy to subscribe their events to the EventBus
* or for people that just prefer lambdas to annotation based methods.
*
* @param priority the priority this handler runs at relative to other handlers for the same event type
* @param receiveCancelled whether this handler should still be invoked if the event has already been canceled
* @param once if true, this handler is automatically unregistered after it runs once
* @param handler the lambda invoked when an event of type [T] is posted
* @return a token that can be passed to [unregister] to remove this handler
**/
@JvmStatic
inline fun <reified T : Event> registerLambda(
priority: Event.Priority = Event.Priority.MEDIUM,
receiveCancelled: Boolean = false,
once: Boolean = false,
noinline handler: (T) -> Unit,
): Any = registerLambdaInternal(T::class.java, priority, receiveCancelled, once, handler)

@JvmStatic
@PublishedApi
internal fun <T : Event> registerLambdaInternal(
eventType: Class<T>,
priority: Event.Priority,
receiveCancelled: Boolean,
once: Boolean,
handler: (T) -> Unit,
): Any {
val token = Any()
val h = Handler(
listener = token,
eventType = eventType,
priority = priority,
receiveCancelled = receiveCancelled,
once = once,
methodName = "<lambda:${eventType.simpleName}>",
invoker = { event ->
@Suppress("UNCHECKED_CAST")
handler(event as T)
},
)
handlers.add(h)
dispatchCache.clear()
return token
}

private fun scanClassForHandlers(listenerClass: Class<*>): List<MethodMetadata> {
return listenerClass.declaredMethods.mapNotNull { method ->
Expand All @@ -54,10 +98,6 @@ object EventBus {
"EventBus: could not access ${listenerClass.name}#${method.name}"
}

require(Event::class.java.isAssignableFrom(params[0])) {
"EventBus: ${listenerClass.name}#${method.name} parameter ${params[0].name} is not an Event"
}

MethodMetadata(
method = method,
eventType = params[0].asSubclass(Event::class.java),
Expand Down
9 changes: 9 additions & 0 deletions src/main/kotlin/org/cobalt/event/annotation/SubscribeEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ package org.cobalt.event.annotation

import org.cobalt.event.Event

/**
* Marks a function to be called when the specified event is fired
* Must be registered with [org.cobalt.event.EventBus.register] in your class/object
* If you dislike like annotation style methods like this or prefer lambdas, use [org.cobalt.event.EventBus.registerLambda], there are docs on that too
*
* @property ignoreCancelled whether this function should still be called if the event has been canceled
* @property priority the priority this runs at
* @property once should this event be unregistered after it has been run once
*/
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class SubscribeEvent(
Expand Down
12 changes: 7 additions & 5 deletions src/main/kotlin/org/cobalt/pathfinder/calculate/PathNode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ data class PathNode(
val centerVec: Vec3 = Vec3(x + 0.5, y + 0.5, z + 0.5)

override fun equals(other: Any?): Boolean {
val otherNode = other as PathNode
if (this === other) return true
if (other !is PathNode) return false

return otherNode.x == x &&
otherNode.y == y &&
otherNode.z == z
return other.x == x &&
other.y == y &&
other.z == z
}

override fun hashCode(): Int {
return longHash(x, y, z).toInt()
val hash = longHash(x, y, z)
return (hash xor (hash ushr 32)).toInt() // IntelliJ is saying ushr isn't a thing, but it is wrong
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class ModeSetting(
val options: Array<String>,
) : Setting<Int>(name, description, defaultValue) {

init {
require(options.isNotEmpty()) { "ModeSetting: '$name' must have at least one option" }
}
override fun read(element: JsonElement) {
this.value = element.asInt
}
Expand Down Expand Up @@ -51,6 +54,8 @@ class ModeSetting(
}

override fun mouseClicked(button: Int): Boolean {
if (options.isEmpty()) return false

val display = options.getOrNull(value) ?: ""
val buttonWidth = Skia.textWidth(Skia.regularFont, display, FONT_SIZE) + 30f
val startX = xPos + width - buttonWidth - PADDING
Expand Down
16 changes: 9 additions & 7 deletions src/main/kotlin/org/cobalt/util/PlayerUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import org.cobalt.Cobalt.minecraft
import org.cobalt.util.rotation.Rotation

object PlayerUtils {

@JvmStatic
val player: LocalPlayer?
get() = minecraft.player
Expand Down Expand Up @@ -43,17 +42,20 @@ object PlayerUtils {
@JvmStatic
val rotation: Rotation
get() {
val player = minecraft.player!!
val player = minecraft.player ?: return Rotation(0f, 0f, true)
return Rotation(player.yRot, player.xRot, true)
}

@JvmStatic
val position: BlockPos
get() = BlockPos(
floor(player!!.x).toInt(),
player!!.blockPosition().y,
floor(player!!.z).toInt()
)
get() {
val player = player ?: return BlockPos(0, 0, 0)
return BlockPos(
floor(player.x).toInt(),
player.blockPosition().y,
floor(player.z).toInt()
)
}

@JvmStatic
val isSuffocating: Boolean
Expand Down
Loading