Refactor source layout

Introduce compat source sets and move all kotlin sources to the main directory

[no changelog]
This commit is contained in:
Linnea Gräf
2024-08-28 19:04:24 +02:00
parent a690630816
commit d2f240ff0c
251 changed files with 295 additions and 38 deletions

View File

@@ -0,0 +1,16 @@
package moe.nea.firmament.events
import moe.nea.firmament.util.unformattedString
import net.minecraft.text.Text
/**
* Filter whether the user should see a chat message altogether. May or may not be called for every chat packet sent by
* the server. When that quality is desired, consider [ProcessChatEvent] instead.
*/
data class AllowChatEvent(val text: Text) : FirmamentEvent.Cancellable() {
val unformattedString = text.unformattedString
companion object : FirmamentEventBus<AllowChatEvent>()
}

View File

@@ -0,0 +1,18 @@
package moe.nea.firmament.events
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.util.Hand
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.world.World
data class AttackBlockEvent(
val player: PlayerEntity,
val world: World,
val hand: Hand,
val blockPos: BlockPos,
val direction: Direction
) : FirmamentEvent.Cancellable() {
companion object : FirmamentEventBus<AttackBlockEvent>()
}

View File

@@ -0,0 +1,21 @@
package moe.nea.firmament.events
import java.util.function.Consumer
import net.minecraft.client.util.ModelIdentifier
class BakeExtraModelsEvent(
private val addItemModel: Consumer<ModelIdentifier>,
private val addAnyModel: Consumer<ModelIdentifier>,
) : FirmamentEvent() {
fun addNonItemModel(modelIdentifier: ModelIdentifier) {
this.addAnyModel.accept(modelIdentifier)
}
fun addItemModel(modelIdentifier: ModelIdentifier) {
this.addItemModel.accept(modelIdentifier)
}
companion object : FirmamentEventBus<BakeExtraModelsEvent>()
}

View File

@@ -0,0 +1,6 @@
package moe.nea.firmament.events
class ClientStartedEvent : FirmamentEvent() {
companion object : FirmamentEventBus<ClientStartedEvent>()
}

View File

@@ -0,0 +1,45 @@
package moe.nea.firmament.events
import com.mojang.brigadier.CommandDispatcher
import com.mojang.brigadier.tree.LiteralCommandNode
import net.minecraft.command.CommandRegistryAccess
import moe.nea.firmament.commands.CaseInsensitiveLiteralCommandNode
import moe.nea.firmament.commands.DefaultSource
import moe.nea.firmament.commands.literal
import moe.nea.firmament.commands.thenLiteral
data class CommandEvent(
val dispatcher: CommandDispatcher<DefaultSource>,
val ctx: CommandRegistryAccess,
val serverCommands: CommandDispatcher<*>?,
) : FirmamentEvent() {
companion object : FirmamentEventBus<CommandEvent>()
/**
* Register subcommands to `/firm`. For new top level commands use [CommandEvent]. Cannot be used to register
* subcommands to other commands.
*/
data class SubCommand(
val builder: CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>,
) : FirmamentEvent() {
companion object : FirmamentEventBus<SubCommand>()
fun subcommand(name: String, block: CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>.() -> Unit) {
builder.thenLiteral(name, block)
}
}
fun deleteCommand(name: String) {
dispatcher.root.children.removeIf { it.name.equals(name, ignoreCase = false) }
serverCommands?.root?.children?.removeIf { it.name.equals(name, ignoreCase = false) }
}
fun register(
name: String,
block: CaseInsensitiveLiteralCommandNode.Builder<DefaultSource>.() -> Unit
): LiteralCommandNode<DefaultSource> {
return dispatcher.register(literal(name, block))
}
}

View File

@@ -0,0 +1,43 @@
package moe.nea.firmament.events
import java.util.*
import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.BakedModelManager
import net.minecraft.client.util.ModelIdentifier
import net.minecraft.item.ItemStack
data class CustomItemModelEvent(
val itemStack: ItemStack,
var overrideModel: ModelIdentifier? = null,
) : FirmamentEvent() {
companion object : FirmamentEventBus<CustomItemModelEvent>() {
private val cache = IdentityHashMap<ItemStack?, Any>()
private val sentinelNull = Object()
fun clearCache() {
cache.clear()
}
@JvmStatic
fun getModelIdentifier(itemStack: ItemStack?): ModelIdentifier? {
if (itemStack == null) return null
return publish(CustomItemModelEvent(itemStack)).overrideModel
}
@JvmStatic
fun getModel(itemStack: ItemStack?, thing: BakedModelManager): BakedModel? {
if (itemStack == null) return null
val cachedValue = cache.getOrPut(itemStack) {
val modelId = getModelIdentifier(itemStack) ?: return@getOrPut sentinelNull
val bakedModel = thing.getModel(modelId)
if (bakedModel === thing.missingModel) return@getOrPut sentinelNull
bakedModel
}
if (cachedValue === sentinelNull)
return null
return cachedValue as BakedModel
}
}
}

View File

@@ -0,0 +1,10 @@
package moe.nea.firmament.events
import java.util.concurrent.Executor
import net.minecraft.resource.ResourceManager
data class EarlyResourceReloadEvent(val resourceManager: ResourceManager, val preparationExecutor: Executor) :
FirmamentEvent() {
companion object : FirmamentEventBus<EarlyResourceReloadEvent>()
}

View File

@@ -0,0 +1,11 @@
package moe.nea.firmament.events
import net.minecraft.entity.Entity
data class EntityDespawnEvent(
val entity: Entity?, val entityId: Int,
val reason: Entity.RemovalReason,
) : FirmamentEvent() {
companion object: FirmamentEventBus<EntityDespawnEvent>()
}

View File

@@ -0,0 +1,29 @@
package moe.nea.firmament.events
import net.minecraft.entity.Entity
import net.minecraft.util.Hand
data class EntityInteractionEvent(
val kind: InteractionKind,
val entity: Entity,
val hand: Hand,
) : FirmamentEvent() {
companion object : FirmamentEventBus<EntityInteractionEvent>()
enum class InteractionKind {
/**
* Is sent when left-clicking an entity
*/
ATTACK,
/**
* Is a fallback when [INTERACT_AT_LOCATION] fails
*/
INTERACT,
/**
* Is tried first on right click
*/
INTERACT_AT_LOCATION,
}
}

View File

@@ -0,0 +1,31 @@
package moe.nea.firmament.events
import net.minecraft.entity.Entity
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.data.DataTracker
import net.minecraft.network.packet.s2c.play.EntityAttributesS2CPacket
/**
* This event is fired when some entity properties are updated.
* It is not fired for common changes like position, but is for less common ones,
* like health, tracked data, names, equipment. It is always fired
* *after* the values have been applied to the entity.
*/
sealed class EntityUpdateEvent : FirmamentEvent() {
companion object : FirmamentEventBus<EntityUpdateEvent>()
abstract val entity: Entity
data class AttributeUpdate(
override val entity: LivingEntity,
val attributes: List<EntityAttributesS2CPacket.Entry>,
) : EntityUpdateEvent()
data class TrackedDataUpdate(
override val entity: Entity,
val trackedValues: List<DataTracker.SerializedEntry<*>>,
) : EntityUpdateEvent()
// TODO: onEntityPassengersSet, onEntityAttach?, onEntityEquipmentUpdate, onEntityStatusEffect
}

View File

@@ -0,0 +1,8 @@
package moe.nea.firmament.events
import moe.nea.firmament.features.FirmamentFeature
data class FeaturesInitializedEvent(val features: List<FirmamentFeature>) : FirmamentEvent() {
companion object : FirmamentEventBus<FeaturesInitializedEvent>()
}

View File

@@ -0,0 +1,10 @@
package moe.nea.firmament.events
import net.minecraft.resource.ReloadableResourceManagerImpl
data class FinalizeResourceManagerEvent(
val resourceManager: ReloadableResourceManagerImpl,
) : FirmamentEvent() {
companion object : FirmamentEventBus<FinalizeResourceManagerEvent>()
}

View File

@@ -0,0 +1,38 @@
package moe.nea.firmament.events
/**
* An event that can be fired by a [FirmamentEventBus].
*
* Typically, that event bus is implemented as a companion object
*
* ```
* class SomeEvent : FirmamentEvent() {
* companion object : FirmamentEventBus<SomeEvent>()
* }
* ```
*/
abstract class FirmamentEvent {
/**
* A [FirmamentEvent] that can be [cancelled]
*/
abstract class Cancellable : FirmamentEvent() {
/**
* Cancels this is event.
*
* @see cancelled
*/
fun cancel() {
cancelled = true
}
/**
* Whether this event is cancelled.
*
* Cancelled events will bypass handlers unless otherwise specified and will prevent the action that this
* event was originally fired for.
*/
var cancelled: Boolean = false
}
}

View File

@@ -0,0 +1,52 @@
package moe.nea.firmament.events
import java.util.concurrent.CopyOnWriteArrayList
import moe.nea.firmament.Firmament
import moe.nea.firmament.util.MC
/**
* A pubsub event bus.
*
* [subscribe] to events [publish]ed on this event bus.
* Subscriptions may not necessarily be delivered in the order of registering.
*/
open class FirmamentEventBus<T : FirmamentEvent> {
data class Handler<T>(
val invocation: (T) -> Unit, val receivesCancelled: Boolean,
var knownErrors: MutableSet<Class<*>> = mutableSetOf(),
)
private val toHandle: MutableList<Handler<T>> = CopyOnWriteArrayList()
fun subscribe(handle: (T) -> Unit) {
subscribe(false, handle)
}
fun subscribe(receivesCancelled: Boolean, handle: (T) -> Unit) {
toHandle.add(Handler(handle, receivesCancelled))
}
fun publish(event: T): T {
for (function in toHandle) {
if (function.receivesCancelled || event !is FirmamentEvent.Cancellable || !event.cancelled) {
try {
function.invocation(event)
} catch (e: Exception) {
val klass = e.javaClass
if (!function.knownErrors.contains(klass) || Firmament.DEBUG) {
function.knownErrors.add(klass)
Firmament.logger.error("Caught exception during processing event $event by $function", e)
}
}
}
}
return event
}
fun publishSync(event: T) {
MC.onMainThread {
publish(event)
}
}
}

View File

@@ -0,0 +1,10 @@
package moe.nea.firmament.events
import net.minecraft.client.gui.screen.ingame.HandledScreen
data class HandledScreenClickEvent(val screen: HandledScreen<*>, val mouseX: Double, val mouseY: Double, val button: Int) :
FirmamentEvent.Cancellable() {
companion object : FirmamentEventBus<HandledScreenClickEvent>()
}

View File

@@ -0,0 +1,16 @@
package moe.nea.firmament.events
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.ingame.HandledScreen
data class HandledScreenForegroundEvent(
val screen: HandledScreen<*>,
val context: DrawContext,
val mouseX: Int,
val mouseY: Int,
val delta: Float
) : FirmamentEvent() {
companion object : FirmamentEventBus<HandledScreenForegroundEvent>()
}

View File

@@ -0,0 +1,24 @@
package moe.nea.firmament.events
import net.minecraft.client.gui.screen.ingame.HandledScreen
import net.minecraft.client.option.KeyBinding
import moe.nea.firmament.keybindings.IKeyBinding
data class HandledScreenKeyPressedEvent(
val screen: HandledScreen<*>,
val keyCode: Int,
val scanCode: Int,
val modifiers: Int
) : FirmamentEvent.Cancellable() {
companion object : FirmamentEventBus<HandledScreenKeyPressedEvent>()
fun matches(keyBinding: KeyBinding): Boolean {
return matches(IKeyBinding.minecraft(keyBinding))
}
fun matches(keyBinding: IKeyBinding): Boolean {
return keyBinding.matches(keyCode, scanCode, modifiers)
}
}

View File

@@ -0,0 +1,18 @@
package moe.nea.firmament.events
import me.shedaniel.math.Rectangle
import net.minecraft.client.gui.screen.ingame.HandledScreen
data class HandledScreenPushREIEvent(
val screen: HandledScreen<*>,
val rectangles: MutableList<Rectangle> = mutableListOf()
) : FirmamentEvent() {
fun block(rectangle: Rectangle) {
rectangles.add(rectangle)
}
companion object : FirmamentEventBus<HandledScreenPushREIEvent>()
}

View File

@@ -0,0 +1,17 @@
package moe.nea.firmament.events
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.render.RenderTickCounter
import net.minecraft.item.ItemStack
data class HotbarItemRenderEvent(
val item: ItemStack,
val context: DrawContext,
val x: Int,
val y: Int,
val tickDelta: RenderTickCounter,
) : FirmamentEvent() {
companion object : FirmamentEventBus<HotbarItemRenderEvent>()
}

View File

@@ -0,0 +1,13 @@
package moe.nea.firmament.events
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.render.RenderTickCounter
/**
* Called when hud elements should be rendered, before the screen, but after the world.
*/
data class HudRenderEvent(val context: DrawContext, val tickDelta: RenderTickCounter) : FirmamentEvent() {
companion object : FirmamentEventBus<HudRenderEvent>()
}

View File

@@ -0,0 +1,46 @@
package moe.nea.firmament.events
import net.minecraft.item.ItemStack
import net.minecraft.screen.slot.Slot
import net.minecraft.screen.slot.SlotActionType
import net.minecraft.text.Text
import moe.nea.firmament.util.CommonSoundEffects
import moe.nea.firmament.util.MC
data class IsSlotProtectedEvent(
val slot: Slot?,
val actionType: SlotActionType,
var isProtected: Boolean,
val itemStackOverride: ItemStack?,
var silent: Boolean = false,
) : FirmamentEvent() {
val itemStack get() = itemStackOverride ?: slot!!.stack
fun protect() {
isProtected = true
}
fun protectSilent() {
if (!isProtected) {
silent = true
}
isProtected = true
}
companion object : FirmamentEventBus<IsSlotProtectedEvent>() {
@JvmStatic
@JvmOverloads
fun shouldBlockInteraction(slot: Slot?, action: SlotActionType, itemStackOverride: ItemStack? = null): Boolean {
if (slot == null && itemStackOverride == null) return false
val event = IsSlotProtectedEvent(slot, action, false, itemStackOverride)
publish(event)
if (event.isProtected && !event.silent) {
MC.player?.sendMessage(Text.translatable("firmament.protectitem").append(event.itemStack.name))
CommonSoundEffects.playFailure()
}
return event.isProtected
}
}
}

View File

@@ -0,0 +1,14 @@
package moe.nea.firmament.events
import net.minecraft.item.Item.TooltipContext
import net.minecraft.item.ItemStack
import net.minecraft.item.tooltip.TooltipType
import net.minecraft.text.Text
data class ItemTooltipEvent(
val stack: ItemStack, val context: TooltipContext, val type: TooltipType, val lines: MutableList<Text>
) : FirmamentEvent() {
companion object : FirmamentEventBus<ItemTooltipEvent>()
}

View File

@@ -0,0 +1,13 @@
package moe.nea.firmament.events
import com.mojang.brigadier.CommandDispatcher
data class MaskCommands(val dispatcher: CommandDispatcher<*>) : FirmamentEvent() {
companion object : FirmamentEventBus<MaskCommands>()
fun mask(name: String) {
dispatcher.root.children.removeIf { it.name.equals(name, ignoreCase = true) }
}
}

View File

@@ -0,0 +1,21 @@
package moe.nea.firmament.events
import moe.nea.firmament.util.unformattedString
import net.minecraft.text.Text
/**
* Allow modification of a chat message before it is sent off to the user. Intended for display purposes.
*/
data class ModifyChatEvent(val originalText: Text) : FirmamentEvent() {
var unformattedString = originalText.unformattedString
private set
var replaceWith: Text = originalText
set(value) {
field = value
unformattedString = value.unformattedString
}
companion object : FirmamentEventBus<ModifyChatEvent>()
}

View File

@@ -0,0 +1,9 @@
package moe.nea.firmament.events
import net.minecraft.network.packet.Packet
data class OutgoingPacketEvent(val packet: Packet<*>) : FirmamentEvent.Cancellable() {
companion object : FirmamentEventBus<OutgoingPacketEvent>()
}

View File

@@ -0,0 +1,18 @@
package moe.nea.firmament.events
import org.joml.Vector3f
import net.minecraft.particle.ParticleEffect
import net.minecraft.util.math.Vec3d
data class ParticleSpawnEvent(
val particleEffect: ParticleEffect,
val position: Vec3d,
val offset: Vector3f,
val longDistance: Boolean,
val count: Int,
val speed: Float,
) : FirmamentEvent.Cancellable() {
companion object : FirmamentEventBus<ParticleSpawnEvent>()
}

View File

@@ -0,0 +1,11 @@
package moe.nea.firmament.events
import net.minecraft.item.ItemStack
sealed class PlayerInventoryUpdate : FirmamentEvent() {
companion object : FirmamentEventBus<PlayerInventoryUpdate>()
data class Single(val slot: Int, val stack: ItemStack) : PlayerInventoryUpdate()
data class Multi(val contents: List<ItemStack>) : PlayerInventoryUpdate()
}

View File

@@ -0,0 +1,28 @@
package moe.nea.firmament.events
import net.minecraft.text.Text
import moe.nea.firmament.util.unformattedString
/**
* Behaves like [AllowChatEvent], but is triggered even when cancelled by other mods. Intended for data collection.
* Make sure to subscribe to cancellable events as well when using.
*/
data class ProcessChatEvent(val text: Text, val wasExternallyCancelled: Boolean) : FirmamentEvent.Cancellable() {
val unformattedString = text.unformattedString
val nameHeuristic: String? = run {
val firstColon = unformattedString.indexOf(':')
if (firstColon < 0) return@run null
val firstSpace = unformattedString.lastIndexOf(' ', firstColon)
unformattedString.substring(firstSpace + 1 until firstColon).takeIf { it.isNotEmpty() }
}
init {
if (wasExternallyCancelled)
cancelled = true
}
companion object : FirmamentEventBus<ProcessChatEvent>()
}

View File

@@ -0,0 +1,7 @@
package moe.nea.firmament.events
import io.github.moulberry.repo.NEURepository
data class ReloadRegistrationEvent(val repo: NEURepository) : FirmamentEvent() {
companion object : FirmamentEventBus<ReloadRegistrationEvent>()
}

View File

@@ -0,0 +1,10 @@
package moe.nea.firmament.events
import net.minecraft.client.gui.screen.Screen
data class ScreenChangeEvent(val old: Screen?, val new: Screen?) : FirmamentEvent.Cancellable() {
var overrideScreen: Screen? = null
companion object : FirmamentEventBus<ScreenChangeEvent>()
}

View File

@@ -0,0 +1,16 @@
package moe.nea.firmament.events
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.gui.screen.Screen
data class ScreenRenderPostEvent(
val screen: Screen,
val mouseX: Int,
val mouseY: Int,
val tickDelta: Float,
val drawContext: DrawContext
) : FirmamentEvent() {
companion object : FirmamentEventBus<ScreenRenderPostEvent>()
}

View File

@@ -0,0 +1,18 @@
package moe.nea.firmament.events
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents
import net.minecraft.client.MinecraftClient
import net.minecraft.client.network.ClientPlayNetworkHandler
import net.minecraft.network.ClientConnection
data class ServerConnectedEvent(
val connection: ClientConnection
) : FirmamentEvent() {
companion object : FirmamentEventBus<ServerConnectedEvent>() {
init {
ClientPlayConnectionEvents.INIT.register(ClientPlayConnectionEvents.Init { clientPlayNetworkHandler: ClientPlayNetworkHandler, minecraftClient: MinecraftClient ->
publishSync(ServerConnectedEvent(clientPlayNetworkHandler.connection))
})
}
}
}

View File

@@ -0,0 +1,15 @@
package moe.nea.firmament.events
import moe.nea.firmament.util.Locraw
/**
* This event gets published whenever `/locraw` is queried and HyPixel returns a location different to the old one.
*
* **N.B.:** This event may get fired multiple times while on the server (for example, first to null, then to the
* correct location).
*/
data class SkyblockServerUpdateEvent(val oldLocraw: Locraw?, val newLocraw: Locraw?) : FirmamentEvent() {
companion object : FirmamentEventBus<SkyblockServerUpdateEvent>()
}

View File

@@ -0,0 +1,15 @@
package moe.nea.firmament.events
import net.minecraft.item.ItemStack
import net.minecraft.screen.slot.Slot
import net.minecraft.screen.slot.SlotActionType
data class SlotClickEvent(
val slot: Slot,
val stack: ItemStack,
val button: Int,
val actionType: SlotActionType,
) : FirmamentEvent() {
companion object : FirmamentEventBus<SlotClickEvent>()
}

View File

@@ -0,0 +1,34 @@
package moe.nea.firmament.events
import net.minecraft.client.gui.DrawContext
import net.minecraft.screen.slot.Slot
interface SlotRenderEvents {
val context: DrawContext
val slot: Slot
val mouseX: Int
val mouseY: Int
val delta: Float
data class Before(
override val context: DrawContext, override val slot: Slot,
override val mouseX: Int,
override val mouseY: Int,
override val delta: Float
) : FirmamentEvent(),
SlotRenderEvents {
companion object : FirmamentEventBus<Before>()
}
data class After(
override val context: DrawContext, override val slot: Slot,
override val mouseX: Int,
override val mouseY: Int,
override val delta: Float
) : FirmamentEvent(),
SlotRenderEvents {
companion object : FirmamentEventBus<After>()
}
}

View File

@@ -0,0 +1,18 @@
package moe.nea.firmament.events
import net.minecraft.registry.entry.RegistryEntry
import net.minecraft.sound.SoundCategory
import net.minecraft.sound.SoundEvent
import net.minecraft.util.math.Vec3d
data class SoundReceiveEvent(
val sound: RegistryEntry<SoundEvent>,
val category: SoundCategory,
val position: Vec3d,
val pitch: Float,
val volume: Float,
val seed: Long
) : FirmamentEvent.Cancellable() {
companion object : FirmamentEventBus<SoundReceiveEvent>()
}

View File

@@ -0,0 +1,7 @@
package moe.nea.firmament.events
data class TickEvent(val tickCount: Int) : FirmamentEvent() {
companion object : FirmamentEventBus<TickEvent>()
}

View File

@@ -0,0 +1,17 @@
package moe.nea.firmament.events
import net.minecraft.client.gui.tooltip.Tooltip
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
data class TooltipEvent(
val itemStack: ItemStack,
val tooltip: Tooltip,
val tooltipContext: Item.TooltipContext,
val player: PlayerEntity?
) : FirmamentEvent() {
companion object : FirmamentEventBus<TooltipEvent>()
}

View File

@@ -0,0 +1,11 @@
package moe.nea.firmament.events
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.util.Hand
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.world.World
data class UseBlockEvent(val player: PlayerEntity, val world: World, val hand: Hand, val hitResult: BlockHitResult) : FirmamentEvent.Cancellable() {
companion object : FirmamentEventBus<UseBlockEvent>()
}

View File

@@ -0,0 +1,18 @@
package moe.nea.firmament.events
import net.minecraft.client.option.KeyBinding
import moe.nea.firmament.keybindings.IKeyBinding
data class WorldKeyboardEvent(val keyCode: Int, val scanCode: Int, val modifiers: Int) : FirmamentEvent.Cancellable() {
companion object : FirmamentEventBus<WorldKeyboardEvent>()
fun matches(keyBinding: KeyBinding): Boolean {
return matches(IKeyBinding.minecraft(keyBinding))
}
fun matches(keyBinding: IKeyBinding): Boolean {
return keyBinding.matches(keyCode, scanCode, modifiers)
}
}

View File

@@ -0,0 +1,7 @@
package moe.nea.firmament.events
class WorldReadyEvent : FirmamentEvent() {
companion object : FirmamentEventBus<WorldReadyEvent>()
}

View File

@@ -0,0 +1,27 @@
package moe.nea.firmament.events
import net.minecraft.client.render.Camera
import net.minecraft.client.render.GameRenderer
import net.minecraft.client.render.LightmapTextureManager
import net.minecraft.client.render.RenderTickCounter
import net.minecraft.client.render.VertexConsumerProvider
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.util.math.Position
import net.minecraft.util.math.Vec3d
/**
* This event is called after all world rendering is done, but before any GUI rendering (including hand) has been done.
*/
data class WorldRenderLastEvent(
val matrices: MatrixStack,
val tickCounter: RenderTickCounter,
val renderBlockOutline: Boolean,
val camera: Camera,
val gameRenderer: GameRenderer,
val lightmapTextureManager: LightmapTextureManager,
val vertexConsumers: VertexConsumerProvider.Immediate,
) : FirmamentEvent() {
companion object : FirmamentEventBus<WorldRenderLastEvent>()
}

View File

@@ -0,0 +1,54 @@
package moe.nea.firmament.events.registration
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents
import net.fabricmc.fabric.api.event.player.AttackBlockCallback
import net.fabricmc.fabric.api.event.player.UseBlockCallback
import net.minecraft.text.Text
import net.minecraft.util.ActionResult
import moe.nea.firmament.events.AllowChatEvent
import moe.nea.firmament.events.AttackBlockEvent
import moe.nea.firmament.events.ModifyChatEvent
import moe.nea.firmament.events.ProcessChatEvent
import moe.nea.firmament.events.UseBlockEvent
private var lastReceivedMessage: Text? = null
fun registerFirmamentEvents() {
ClientReceiveMessageEvents.ALLOW_CHAT.register(ClientReceiveMessageEvents.AllowChat { message, signedMessage, sender, params, receptionTimestamp ->
lastReceivedMessage = message
!ProcessChatEvent.publish(ProcessChatEvent(message, false)).cancelled
&& !AllowChatEvent.publish(AllowChatEvent(message)).cancelled
})
ClientReceiveMessageEvents.ALLOW_GAME.register(ClientReceiveMessageEvents.AllowGame { message, overlay ->
lastReceivedMessage = message
overlay || (!ProcessChatEvent.publish(ProcessChatEvent(message, false)).cancelled &&
!AllowChatEvent.publish(AllowChatEvent(message)).cancelled)
})
ClientReceiveMessageEvents.MODIFY_GAME.register(ClientReceiveMessageEvents.ModifyGame { message, overlay ->
if (overlay) message
else ModifyChatEvent.publish(ModifyChatEvent(message)).replaceWith
})
ClientReceiveMessageEvents.GAME_CANCELED.register(ClientReceiveMessageEvents.GameCanceled { message, overlay ->
if (!overlay && lastReceivedMessage !== message) {
ProcessChatEvent.publish(ProcessChatEvent(message, true))
}
})
ClientReceiveMessageEvents.CHAT_CANCELED.register(ClientReceiveMessageEvents.ChatCanceled { message, signedMessage, sender, params, receptionTimestamp ->
if (lastReceivedMessage !== message) {
ProcessChatEvent.publish(ProcessChatEvent(message, true))
}
})
AttackBlockCallback.EVENT.register(AttackBlockCallback { player, world, hand, pos, direction ->
if (AttackBlockEvent.publish(AttackBlockEvent(player, world, hand, pos, direction)).cancelled)
ActionResult.CONSUME
else ActionResult.PASS
})
UseBlockCallback.EVENT.register(UseBlockCallback { player, world, hand, hitResult ->
if (UseBlockEvent.publish(UseBlockEvent(player, world, hand, hitResult)).cancelled)
ActionResult.CONSUME
else ActionResult.PASS
})
}

View File

@@ -0,0 +1,16 @@
package moe.nea.firmament.events.subscription
import moe.nea.firmament.events.FirmamentEvent
import moe.nea.firmament.events.FirmamentEventBus
import moe.nea.firmament.features.FirmamentFeature
interface SubscriptionOwner {
val delegateFeature: FirmamentFeature
}
data class Subscription<T : FirmamentEvent>(
val owner: Any,
val invoke: (T) -> Unit,
val eventBus: FirmamentEventBus<T>,
)