Skip to content

Commit

Permalink
Backend: Add compat files for preprocessing (hannibal002#2872)
Browse files Browse the repository at this point in the history
  • Loading branch information
CalMWolfs authored Nov 1, 2024
1 parent 50fedee commit 23d5f57
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 83 deletions.
9 changes: 7 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ specifically compile 1.8.9 using `./gradlew :1.8.9:build`. This does not affect

`compile` enables compilation for the `:1.21` subproject. This means that a `build` or `assemble` task will try (and fail) to compile a
1.21 (as well as 1.8.9) JAR. This mode may be useful for someone seeking out issues to fix, but is generally not useful in day to day
operations since the compile will never succeed and will block things like hotswap compilations (via <kbd>CTRL+F9</kbd>) from completing.
operations since the compile task will never succeed and will block things like hotswap compilations (via <kbd>CTRL+F9</kbd>) from completing.

### Improving mappings

Expand Down Expand Up @@ -416,7 +416,7 @@ Let's look at the syntax of those `#if` expressions.

First of all, the `#else` block is optional. If you just want code on some versions (for example for adding a method call that is implicitly
done on newer versions, or simply because the corresponding code for newer versions has to be done in some other place), you can just omit
the `#else` section and you will simply not compile any code at that spot.
the `#else` section, and you will simply not compile any code at that spot.

There is also an `#elseif` in case you want to switch behaviour based on multiple version brackets. Again, while we don't actually target
1.12 or 1.16, making those versions compile will help other parts of the code to upgrade to 1.21 more cleanly and easily. So, making those
Expand All @@ -439,3 +439,8 @@ for the variable using `#if FORGE`.
Sadly, `#if` expressions cannot be applied globally (unlike name changes), so it is often very helpful to create a helper method and call
that method from various places in the codebase. This is generally already policy in SH for a lot of things. For more complex types that
change beyond just their name (for example different generics), a `typealias` can be used in combination with `#if` expressions.

These helper methods should generally be placed in the `at.hannibal2.skyhanni.utils.compat` package and should be named after what they are
compatability methods for. For example, `WorldClient.getAllEntities()` could be placed in `WorldCompat.kt`. This is not a strict rule, but
it is a good guideline to follow as for the most part we do not want to be doing large amount of preprocessing in the feature files
themselves.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import at.hannibal2.skyhanni.events.SkyHanniRenderEntityEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.ConfigUtils
import at.hannibal2.skyhanni.utils.EntityUtils.getArmorInventory
import at.hannibal2.skyhanni.utils.EntityUtils.hasPotionEffect
import at.hannibal2.skyhanni.utils.EntityUtils.isNPC
import at.hannibal2.skyhanni.utils.FakePlayer
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.compat.Effects
import at.hannibal2.skyhanni.utils.compat.EffectsCompat
import at.hannibal2.skyhanni.utils.compat.EffectsCompat.Companion.hasPotionEffect
import net.minecraft.client.entity.EntityPlayerSP
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.player.EntityPlayer
Expand All @@ -28,7 +28,7 @@ object HideArmor {
if (!LorenzUtils.inSkyBlock) return false
if (entity !is EntityPlayer) return false
if (entity is FakePlayer) return false
if (entity.hasPotionEffect(Effects.invisibility)) return false
if (entity.hasPotionEffect(EffectsCompat.INVISIBILITY)) return false
if (entity.isNPC()) return false

return when (config.mode) {
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package at.hannibal2.skyhanni.utils

import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.CollectionUtils.drainTo
import at.hannibal2.skyhanni.utils.compat.isOnMainThread
import net.minecraft.client.Minecraft
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.Executor
Expand Down Expand Up @@ -42,10 +41,10 @@ object DelayedRun {
@JvmField
val onThread = Executor {
val mc = Minecraft.getMinecraft()
if (mc.isOnMainThread()) {
if (mc.isCallingFromMinecraftThread) {
it.run()
} else {
Minecraft.getMinecraft().addScheduledTask(it)
mc.addScheduledTask(it)
}
}
}
44 changes: 13 additions & 31 deletions src/main/java/at/hannibal2/skyhanni/utils/EntityUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ import at.hannibal2.skyhanni.utils.LocationUtils.distanceToIgnoreY
import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth
import at.hannibal2.skyhanni.utils.LorenzUtils.derpy
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.compat.getArmorOrFullInventory
import at.hannibal2.skyhanni.utils.compat.getLoadedPlayers
import at.hannibal2.skyhanni.utils.compat.getNameAsString
import at.hannibal2.skyhanni.utils.compat.isOnMainThread
import at.hannibal2.skyhanni.utils.compat.getWholeInventory
import at.hannibal2.skyhanni.utils.compat.normalizeAsArray
import net.minecraft.block.state.IBlockState
import net.minecraft.client.Minecraft
Expand All @@ -26,14 +25,11 @@ import net.minecraft.entity.item.EntityArmorStand
import net.minecraft.entity.monster.EntityEnderman
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.potion.Potion
import net.minecraft.tileentity.TileEntity
import net.minecraft.util.AxisAlignedBB
import net.minecraftforge.client.event.RenderLivingEvent
//#if FORGE
import net.minecraftforge.fml.common.eventhandler.Event
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
//#endif

@SkyHanniModule
object EntityUtils {
Expand Down Expand Up @@ -101,7 +97,7 @@ object EntityUtils {
val b = center.add(radius, radius + 3, radius).toBlockPos()
val alignedBB = AxisAlignedBB(a, b)
val clazz = EntityArmorStand::class.java
val worldObj = Minecraft.getMinecraft()?.theWorld ?: return emptyList()
val worldObj = Minecraft.getMinecraft().theWorld ?: return emptyList()
return worldObj.getEntitiesWithinAABB(clazz, alignedBB)
}

Expand Down Expand Up @@ -145,22 +141,14 @@ object EntityUtils {

fun EntityLivingBase.isAtFullHealth() = baseMaxHealth == health.toInt()

// TODO: Make a utils method for just checking the helmet texture
fun EntityArmorStand.hasSkullTexture(skin: String): Boolean {
val inventory = this.getArmorOrFullInventory() ?: return false
val inventory = this.getWholeInventory() ?: return false
return inventory.any { it != null && it.getSkullTexture() == skin }
}

fun EntityPlayer.isNPC() = !isRealPlayer()

fun EntityLivingBase.hasPotionEffect(
potion:
//#if MC <1.21
Potion,
//#else
//$$ net.minecraft.registry.entry.RegistryEntry<net.minecraft.entity.effect.StatusEffect>
//#endif
) = getActivePotionEffect(potion) != null

fun EntityLivingBase.getArmorInventory(): Array<ItemStack?>? =
if (this is EntityPlayer) inventory.armorInventory.normalizeAsArray() else null

Expand All @@ -169,30 +157,26 @@ object EntityUtils {
inline fun <reified R : Entity> getEntities(): Sequence<R> = getAllEntities().filterIsInstance<R>()

private fun WorldClient.getAllEntities(): Iterable<Entity> =
//#if MC < 1.14
//#if MC < 1.14
loadedEntityList
//#else
//$$ entitiesForRendering()
//#endif
//#else
//$$ entitiesForRendering()
//#endif

fun getAllEntities(): Sequence<Entity> = Minecraft.getMinecraft().theWorld?.getAllEntities()?.let {
if (Minecraft.getMinecraft()
.isOnMainThread()
) it
if (Minecraft.getMinecraft().isCallingFromMinecraftThread) it
// TODO: while i am here, i want to point out that copying the entity list does not constitute proper synchronization,
// but *does* make crashes because of it rarer.
else it.toMutableList()
}?.asSequence().orEmpty()

fun getAllTileEntities(): Sequence<TileEntity> = Minecraft.getMinecraft()?.theWorld?.loadedTileEntityList?.let {
if (Minecraft.getMinecraft().isOnMainThread()) it else it.toMutableList()
fun getAllTileEntities(): Sequence<TileEntity> = Minecraft.getMinecraft().theWorld?.loadedTileEntityList?.let {
if (Minecraft.getMinecraft().isCallingFromMinecraftThread) it else it.toMutableList()
}?.asSequence()?.filterNotNull().orEmpty()

fun Entity.canBeSeen(viewDistance: Number = 150.0) = getLorenzVec().up(0.5).canBeSeen(viewDistance)

fun getEntityByID(entityId: Int) = Minecraft.getMinecraft()?.thePlayer?.entityWorld?.getEntityByID(entityId)

//#if FORGE
fun getEntityByID(entityId: Int) = Minecraft.getMinecraft().thePlayer?.entityWorld?.getEntityByID(entityId)

@SubscribeEvent
fun onEntityRenderPre(
Expand Down Expand Up @@ -240,9 +224,7 @@ object EntityUtils {
) {
SkyHanniRenderEntityEvent.Specials.Post(event.entity, event.renderer, event.x, event.y, event.z).postAndCatch()
}
//#endif

//#endif
//#endif

fun EntityLivingBase.isCorrupted() = baseMaxHealth == health.toInt().derpy() * 3 || isRunicAndCorrupt()
fun EntityLivingBase.isRunic() = baseMaxHealth == health.toInt().derpy() * 4 || isRunicAndCorrupt()
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/utils/compat/EffectsCompat.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package at.hannibal2.skyhanni.utils.compat

import net.minecraft.entity.EntityLivingBase
import net.minecraft.potion.Potion
import net.minecraft.potion.PotionEffect
//#if MC > 1.12
//$$ import net.minecraft.init.MobEffects
//#endif

enum class EffectsCompat(val potion: Potion) {
INVISIBILITY(
//#if MC < 1.12
Potion.invisibility
//#else
//$$ MobEffects.INVISIBILITY
//#endif
),
BLINDNESS(
//#if MC < 1.12
Potion.blindness
//#else
//$$ MobEffects.BLINDNESS
//#endif
),
;

companion object {
fun EntityLivingBase.hasPotionEffect(effect: EffectsCompat): Boolean {
return this.isPotionActive(effect.potion)
}

fun EntityLivingBase.activePotionEffect(effect: EffectsCompat): PotionEffect? {
return this.getActivePotionEffect(effect.potion)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package at.hannibal2.skyhanni.utils.compat

import net.minecraft.enchantment.Enchantment
//#if MC >= 1.12
//$$ import net.minecraft.init.Enchantments
//#endif

enum class EnchantmentsCompat(val enchantment: Enchantment) {
PROTECTION(
//#if MC < 1.12
Enchantment.protection
//#else
//$$ Enchantments.PROTECTION
//#endif
),
}
52 changes: 52 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/utils/compat/EntityCompat.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package at.hannibal2.skyhanni.utils.compat


import net.minecraft.entity.Entity
import net.minecraft.entity.EntityLiving
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.item.EntityArmorStand
import net.minecraft.item.ItemStack
//#if MC >= 1.12
//$$ import net.minecraft.inventory.EntityEquipmentSlot
//#endif

fun Entity.getNameAsString(): String =
this.name
//#if MC >= 1.14
//$$ .string
//#endif

fun EntityArmorStand.getStandHelmet(): ItemStack? =
//#if MC < 1.12
this.getEquipmentInSlot(4)
//#else
//$$ this.getItemStackFromSlot(EntityEquipmentSlot.HEAD)
//#endif

fun EntityLiving.getEntityHelmet(): ItemStack? =
//#if MC < 1.12
this.getEquipmentInSlot(4)
//#else
//$$ this.getItemStackFromSlot(EntityEquipmentSlot.HEAD)
//#endif

fun EntityLivingBase.getWholeInventory() =
//#if MC < 1.12
this.inventory
//#else
//$$ this.equipmentAndArmor.toList()
//#endif

fun Entity.getFirstPassenger(): Entity? =
//#if MC < 1.12
this.riddenByEntity
//#else
//$$ this.passengers.firstOrNull()
//#endif

fun EntityArmorStand.getHandItem(): ItemStack? =
//#if MC < 1.12
this.getEquipmentInSlot(0)
//#else
//$$ this.getItemStackFromSlot(EntityEquipmentSlot.MAINHAND)
//#endif
12 changes: 12 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/utils/compat/ItemCompat.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package at.hannibal2.skyhanni.utils.compat

import net.minecraft.client.Minecraft
import net.minecraft.item.ItemStack

fun ItemStack.getTooltipCompat(advanced: Boolean): MutableList<String> {
//#if MC < 1.12
return this.getTooltip(Minecraft.getMinecraft().thePlayer, advanced)
//#else
//$$ return this.getTooltip(Minecraft.getMinecraft().player) { advanced }
//#endif
}
22 changes: 22 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/utils/compat/PacketCompat.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package at.hannibal2.skyhanni.utils.compat

import net.minecraft.item.ItemStack
import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement
import net.minecraft.util.EnumFacing
//#if MC > 1.12
//$$ import net.minecraft.client.Minecraft
//#endif

fun C08PacketPlayerBlockPlacement.getFacing(): EnumFacing =
//#if MC < 1.12
EnumFacing.getFront(placedBlockDirection)
//#else
//$$ direction
//#endif

fun C08PacketPlayerBlockPlacement.getUsedItem(): ItemStack? =
//#if MC < 1.12
stack
//#else
//$$ Minecraft.getMinecraft().player.getHeldItem(hand)
//#endif
44 changes: 0 additions & 44 deletions src/main/java/at/hannibal2/skyhanni/utils/compat/World.kt

This file was deleted.

11 changes: 11 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/utils/compat/WorldCompat.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package at.hannibal2.skyhanni.utils.compat

import net.minecraft.client.multiplayer.WorldClient
import net.minecraft.entity.player.EntityPlayer

fun WorldClient.getLoadedPlayers(): List<EntityPlayer> =
//#if MC < 1.14
this.playerEntities
//#else
//$$ this.players()
//#endif

0 comments on commit 23d5f57

Please sign in to comment.