diff options
Diffstat (limited to 'src/main/kotlin/events')
-rw-r--r-- | src/main/kotlin/events/CustomItemModelEvent.kt | 34 | ||||
-rw-r--r-- | src/main/kotlin/events/EntityRenderTintEvent.kt | 66 | ||||
-rw-r--r-- | src/main/kotlin/events/EntityUpdateEvent.kt | 31 | ||||
-rw-r--r-- | src/main/kotlin/events/IsSlotProtectedEvent.kt | 11 |
4 files changed, 128 insertions, 14 deletions
diff --git a/src/main/kotlin/events/CustomItemModelEvent.kt b/src/main/kotlin/events/CustomItemModelEvent.kt index 21ee326..7b86980 100644 --- a/src/main/kotlin/events/CustomItemModelEvent.kt +++ b/src/main/kotlin/events/CustomItemModelEvent.kt @@ -1,10 +1,13 @@ package moe.nea.firmament.events +import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull +import net.minecraft.component.DataComponentTypes import net.minecraft.item.ItemStack import net.minecraft.util.Identifier import moe.nea.firmament.util.collections.WeakCache +import moe.nea.firmament.util.collections.WeakCache.CacheFunction import moe.nea.firmament.util.mc.IntrospectableItemModelManager // TODO: assert an order on these events @@ -14,7 +17,36 @@ data class CustomItemModelEvent( var overrideModel: Identifier? = null, ) : FirmamentEvent() { companion object : FirmamentEventBus<CustomItemModelEvent>() { - val cache = WeakCache.memoize("ItemModelIdentifier", ::getModelIdentifier0) + val weakCache = + object : WeakCache<ItemStack, IntrospectableItemModelManager, Optional<Identifier>>("ItemModelIdentifier") { + override fun mkRef( + key: ItemStack, + extraData: IntrospectableItemModelManager + ): WeakCache<ItemStack, IntrospectableItemModelManager, Optional<Identifier>>.Ref { + return IRef(key, extraData) + } + + inner class IRef(weakInstance: ItemStack, data: IntrospectableItemModelManager) : + Ref(weakInstance, data) { + override fun shouldBeEvicted(): Boolean = false + val isSimpleStack = weakInstance.componentChanges.isEmpty || (weakInstance.componentChanges.size() == 1 && weakInstance.get( + DataComponentTypes.CUSTOM_DATA)?.isEmpty == true) + val item = weakInstance.item + override fun hashCode(): Int { + if (isSimpleStack) + return Objects.hash(item, extraData) + return super.hashCode() + } + + override fun equals(other: Any?): Boolean { + if (other is IRef && isSimpleStack) { + return other.isSimpleStack && item == other.item + } + return super.equals(other) + } + } + } + val cache = CacheFunction.WithExtraData(weakCache, ::getModelIdentifier0) @JvmStatic fun getModelIdentifier(itemStack: ItemStack?, itemModelManager: IntrospectableItemModelManager): Identifier? { diff --git a/src/main/kotlin/events/EntityRenderTintEvent.kt b/src/main/kotlin/events/EntityRenderTintEvent.kt new file mode 100644 index 0000000..29b888b --- /dev/null +++ b/src/main/kotlin/events/EntityRenderTintEvent.kt @@ -0,0 +1,66 @@ +package moe.nea.firmament.events + +import net.minecraft.client.render.GameRenderer +import net.minecraft.client.render.OverlayTexture +import net.minecraft.client.render.entity.state.EntityRenderState +import net.minecraft.entity.Entity +import net.minecraft.entity.LivingEntity +import moe.nea.firmament.util.render.TintedOverlayTexture + +/** + * Change the tint color of a [LivingEntity] + */ +class EntityRenderTintEvent( + val entity: Entity, + val renderState: HasTintRenderState +) : FirmamentEvent.Cancellable() { + init { + if (entity !is LivingEntity) { + cancel() + } + } + + companion object : FirmamentEventBus<EntityRenderTintEvent>() { + /** + * Static variable containing an override for [GameRenderer.getOverlayTexture]. Should be only set briefly. + * + * This variable only affects render layers that naturally make use of the overlay texture, have proper overlay UVs set (`overlay u != 0`), and have a shader that makes use of the overlay (does not have the `NO_OVERLAY` flag set in its json definition). + * + * Currently supported layers: [net.minecraft.client.render.entity.equipment.EquipmentRenderer], [net.minecraft.client.render.entity.model.PlayerEntityModel], as well as some others naturally. + * + * @see moe.nea.firmament.mixins.render.entitytints.ReplaceOverlayTexture + * @see TintedOverlayTexture + */ + @JvmField + var overlayOverride: OverlayTexture? = null + } + + @Suppress("PropertyName", "FunctionName") + interface HasTintRenderState { + /** + * Multiplicative tint applied before the overlay. + */ + var tint_firmament: Int + + /** + * Must be set for [tint_firmament] to have any effect. + */ + var hasTintOverride_firmament: Boolean + + // TODO: allow for more specific selection of which layers get tinted + /** + * Specify a [TintedOverlayTexture] to be used. This does not apply to render layers not using the overlay texture. + * @see overlayOverride + */ + var overlayTexture_firmament: TintedOverlayTexture? + fun reset_firmament() + + companion object { + @JvmStatic + fun cast(state: EntityRenderState): HasTintRenderState { + return state as HasTintRenderState + } + } + } + +} diff --git a/src/main/kotlin/events/EntityUpdateEvent.kt b/src/main/kotlin/events/EntityUpdateEvent.kt index d091984..27a90f9 100644 --- a/src/main/kotlin/events/EntityUpdateEvent.kt +++ b/src/main/kotlin/events/EntityUpdateEvent.kt @@ -1,9 +1,11 @@ - package moe.nea.firmament.events +import com.mojang.datafixers.util.Pair import net.minecraft.entity.Entity +import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.LivingEntity import net.minecraft.entity.data.DataTracker +import net.minecraft.item.ItemStack import net.minecraft.network.packet.s2c.play.EntityAttributesS2CPacket /** @@ -13,19 +15,24 @@ import net.minecraft.network.packet.s2c.play.EntityAttributesS2CPacket * *after* the values have been applied to the entity. */ sealed class EntityUpdateEvent : FirmamentEvent() { - companion object : FirmamentEventBus<EntityUpdateEvent>() + companion object : FirmamentEventBus<EntityUpdateEvent>() + + abstract val entity: Entity - abstract val entity: Entity + data class AttributeUpdate( + override val entity: LivingEntity, + val attributes: List<EntityAttributesS2CPacket.Entry>, + ) : EntityUpdateEvent() - 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() - data class TrackedDataUpdate( - override val entity: Entity, - val trackedValues: List<DataTracker.SerializedEntry<*>>, - ) : EntityUpdateEvent() + data class EquipmentUpdate( + override val entity: Entity, + val newEquipment: List<Pair<EquipmentSlot, ItemStack>>, + ) : EntityUpdateEvent() -// TODO: onEntityPassengersSet, onEntityAttach?, onEntityEquipmentUpdate, onEntityStatusEffect +// TODO: onEntityPassengersSet, onEntityAttach?, onEntityStatusEffect } diff --git a/src/main/kotlin/events/IsSlotProtectedEvent.kt b/src/main/kotlin/events/IsSlotProtectedEvent.kt index eac2d9b..8fe0a96 100644 --- a/src/main/kotlin/events/IsSlotProtectedEvent.kt +++ b/src/main/kotlin/events/IsSlotProtectedEvent.kt @@ -6,6 +6,10 @@ import net.minecraft.screen.slot.SlotActionType import net.minecraft.text.Text import moe.nea.firmament.util.CommonSoundEffects import moe.nea.firmament.util.MC +import moe.nea.firmament.util.grey +import moe.nea.firmament.util.hover +import moe.nea.firmament.util.red +import moe.nea.firmament.util.tr data class IsSlotProtectedEvent( val slot: Slot?, @@ -35,6 +39,7 @@ data class IsSlotProtectedEvent( INVENTORY_MOVE ; } + companion object : FirmamentEventBus<IsSlotProtectedEvent>() { @JvmStatic @JvmOverloads @@ -47,7 +52,11 @@ data class IsSlotProtectedEvent( val event = IsSlotProtectedEvent(slot, action, false, itemStackOverride, origin) publish(event) if (event.isProtected && !event.silent) { - MC.sendChat(Text.translatable("firmament.protectitem").append(event.itemStack.name)) + MC.sendChat(tr("firmament.protectitem", "Firmament protected your item: ${event.itemStack.name}.\n") + .red() + .append(tr("firmament.protectitem.hoverhint", "Hover for more info.").grey()) + .hover(tr("firmament.protectitem.hint", + "To unlock this item use the Lock Slot or Lock Item keybind from Firmament while hovering over this item."))) CommonSoundEffects.playFailure() } return event.isProtected |