diff --git a/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java b/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java index 8ddde5669b..45af9fee79 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java @@ -83,6 +83,13 @@ default Component getRawHookI18n(ResourceLocation name) { return Component.translatable(getRawHookI18nKey(name)).withStyle(ChatFormatting.LIGHT_PURPLE); } + /** + * If the entity has a special getter return that, otherwise return its normal look angle + */ + default Vec3 getEntityLookDirSpecial(Entity entity) { + return entity.getLookAngle(); + } + /** * Register an entity with the given ID to have its velocity as perceived by OpEntityVelocity be different * than it's "normal" velocity diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt index 23e47e9076..81ad7d3a1f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/queryentity/OpEntityLook.kt @@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.casting.castables.ConstMediaAction import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.getEntity import at.petrak.hexcasting.api.casting.iota.Iota +import at.petrak.hexcasting.api.HexAPI object OpEntityLook : ConstMediaAction { override val argc = 1 @@ -12,6 +13,8 @@ object OpEntityLook : ConstMediaAction { override fun execute(args: List, env: CastingEnvironment): List { val e = args.getEntity(0, argc) env.assertEntityInRange(e) - return e.lookAngle.asActionResult + + val lookDir = HexAPI.instance().getEntityLookDirSpecial(e) + return lookDir.asActionResult } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt index e13b7b3eb8..2882984ebd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/actions/spells/OpBlink.kt @@ -1,5 +1,6 @@ package at.petrak.hexcasting.common.casting.actions.spells +import at.petrak.hexcasting.api.HexAPI import at.petrak.hexcasting.api.casting.ParticleSpray import at.petrak.hexcasting.api.casting.RenderedSpell import at.petrak.hexcasting.api.casting.castables.SpellAction @@ -14,6 +15,7 @@ import at.petrak.hexcasting.api.mod.HexConfig import at.petrak.hexcasting.api.mod.HexTags import at.petrak.hexcasting.common.casting.actions.spells.great.OpTeleport import net.minecraft.world.entity.Entity +import net.minecraft.world.phys.Vec3 import kotlin.math.absoluteValue import kotlin.math.roundToLong @@ -36,7 +38,7 @@ object OpBlink : SpellAction { throw MishapImmuneEntity(immunePassengers.get(0)) } - val dvec = target.lookAngle.scale(delta) + val dvec = HexAPI.instance().getEntityLookDirSpecial(target).scale(delta) val endPos = target.position().add(dvec) if (!HexConfig.server().canTeleportInThisDimension(env.world.dimension())) @@ -51,7 +53,7 @@ object OpBlink : SpellAction { val targetMiddlePos = target.position().add(0.0, target.eyeHeight / 2.0, 0.0) return SpellAction.Result( - Spell(target, delta), + Spell(target, dvec), (MediaConstants.SHARD_UNIT * delta.absoluteValue * 0.5).roundToLong(), listOf( ParticleSpray.cloud(targetMiddlePos, 2.0, 50), @@ -60,13 +62,12 @@ object OpBlink : SpellAction { ) } - private data class Spell(val target: Entity, val delta: Double) : RenderedSpell { + private data class Spell(val target: Entity, val dvec: Vec3) : RenderedSpell { override fun cast(env: CastingEnvironment) { if (!HexConfig.server().canTeleportInThisDimension(env.world.dimension())) return - val delta = target.lookAngle.scale(delta) - OpTeleport.teleportRespectSticky(target, delta, env.world) + OpTeleport.teleportRespectSticky(target, dvec, env.world) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/impl/HexAPIImpl.java b/Common/src/main/java/at/petrak/hexcasting/common/impl/HexAPIImpl.java index 0ff996b907..f5479ac888 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/impl/HexAPIImpl.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/impl/HexAPIImpl.java @@ -12,7 +12,11 @@ import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.monster.Phantom; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.AbstractHurtingProjectile; +import net.minecraft.world.entity.projectile.Projectile; +import net.minecraft.world.entity.projectile.ShulkerBullet; import net.minecraft.world.item.ArmorItem; import net.minecraft.world.item.ArmorMaterial; import net.minecraft.world.item.ItemStack; @@ -31,6 +35,21 @@ public class HexAPIImpl implements HexAPI { private static final ConcurrentMap, Consumer> SPECIAL_BRAINSWEEPS = new ConcurrentHashMap<>(); + @Override public Vec3 getEntityLookDirSpecial(Entity entity) { + var lookDir = entity.getLookAngle(); + if (entity instanceof AbstractHurtingProjectile || entity instanceof ShulkerBullet) { + // couldn't find a report but these are bugged differently than other projectiles + lookDir = new Vec3(-1 * lookDir.x, lookDir.y, -1 * lookDir.z); + } else if (entity instanceof Projectile) { + // https://bugs.mojang.com/browse/MC/issues/MC-112474 + lookDir = new Vec3(-1 * lookDir.x, -1 * lookDir.y, lookDir.z); + } else if (entity instanceof Phantom) { + // https://bugs.mojang.com/browse/MC/issues/MC-134707 + lookDir = new Vec3(lookDir.x, -1 * lookDir.y, lookDir.z); + } + return lookDir; + } + public void registerSpecialVelocityGetter(EntityType key, EntityVelocityGetter getter) { if (SPECIAL_VELOCITIES.containsKey(key)) {