diff --git a/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java b/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java index ab9100e8..f62073f2 100644 --- a/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java +++ b/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java @@ -7,9 +7,10 @@ import com.minelittlepony.unicopia.entity.Equine; import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.Entity; -import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.*; +import net.minecraft.entity.decoration.AbstractDecorationEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.predicate.entity.EntityPredicates; public interface EquinePredicates { Predicate IS_PLAYER = e -> e instanceof PlayerEntity; @@ -28,6 +29,8 @@ public interface EquinePredicates { Predicate HAS_WANT_IT_NEED_IT = e -> EnchantmentHelper.getEquipmentLevel(UEnchantments.WANT_IT_NEED_IT, e) > 0; + Predicate VALID_FOR_DISGUISE = EntityPredicates.EXCEPT_SPECTATOR.and(e -> !(e instanceof LightningEntity || e instanceof AbstractDecorationEntity)); + static Predicate ofRace(Race race) { return raceMatches(race::equals); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/BatPonyHangAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/BatPonyHangAbility.java index 7fad6e19..f5441b76 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/BatPonyHangAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/BatPonyHangAbility.java @@ -3,9 +3,8 @@ package com.minelittlepony.unicopia.ability; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.ability.data.Multi; import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.TraceHelper; -import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.util.math.BlockPos; /** @@ -41,7 +40,7 @@ public class BatPonyHangAbility implements Ability { return new Multi(BlockPos.ZERO, 0); } - return RayTraceHelper.doTrace(player.getMaster(), 5, 1, EntityPredicates.EXCEPT_SPECTATOR).getBlockPos() + return TraceHelper.findBlock(player.getMaster(), 5, 1) .map(BlockPos::down) .filter(player::canHangAt) .map(pos -> new Multi(pos, 1)) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/CarryAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/CarryAbility.java index 4dd4c7d7..957502ca 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/CarryAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/CarryAbility.java @@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.ability; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.ability.data.Hit; import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.TraceHelper; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; @@ -42,7 +42,7 @@ public class CarryAbility implements Ability { } protected LivingEntity findRider(PlayerEntity player, World w) { - return RayTraceHelper.findEntity(player, 10, 1, hit -> { + return TraceHelper.findEntity(player, 10, 1, hit -> { return hit instanceof LivingEntity && !player.isConnectedThroughVehicle(hit) && !(hit instanceof IPickupImmuned); }).orElse(null); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java index 346638fc..d9d4893f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingDisguiseAbility.java @@ -3,21 +3,18 @@ package com.minelittlepony.unicopia.ability; import org.jetbrains.annotations.Nullable; +import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.ability.data.Hit; -import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; -import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.mixin.MixinFallingBlockEntity; import com.minelittlepony.unicopia.particle.UParticles; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.Trace; + import net.minecraft.entity.Entity; -import net.minecraft.entity.LightningEntity; -import net.minecraft.entity.decoration.AbstractDecorationEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.sound.SoundCategory; /** @@ -42,16 +39,9 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility { return; } - RayTraceHelper.Trace trace = RayTraceHelper.doTrace(player, 10, 1, EntityPredicates.EXCEPT_SPECTATOR.and(e -> !(e instanceof LightningEntity))); + Trace trace = Trace.create(player, 10, 1, EquinePredicates.VALID_FOR_DISGUISE); - Entity looked = trace.getEntity().filter(e -> !(e instanceof AbstractDecorationEntity)).map(e -> { - return e instanceof PlayerEntity ? Pony.of((PlayerEntity)e) - .getSpellSlot() - .get(SpellPredicate.IS_DISGUISE, true) - .map(AbstractDisguiseSpell::getDisguise) - .map(EntityAppearance::getAppearance) - .orElse(e) : e; - }).orElseGet(() -> trace.getBlockPos().map(pos -> { + Entity looked = trace.getEntity().map(AbstractDisguiseSpell::getAppearance).orElseGet(() -> trace.getBlockPos().map(pos -> { if (!iplayer.getReferenceWorld().isAir(pos)) { return MixinFallingBlockEntity.createInstance(player.getEntityWorld(), 0, 0, 0, iplayer.getReferenceWorld().getBlockState(pos)); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java index 1061f23f..75b96e78 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java @@ -12,7 +12,7 @@ import com.minelittlepony.unicopia.particle.FollowingParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.util.MagicalDamageSource; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.TraceHelper; import com.minelittlepony.unicopia.util.VecHelper; import net.minecraft.entity.Entity; @@ -82,7 +82,7 @@ public class ChangelingFeedAbility implements Ability { protected List getTargets(Pony player) { List list = VecHelper.findInRange(player.getMaster(), player.getReferenceWorld(), player.getOriginVector(), 3, this::canDrain); - RayTraceHelper.findEntity(player.getMaster(), 17, 1, + TraceHelper.findEntity(player.getMaster(), 17, 1, looked -> looked instanceof LivingEntity && !list.contains(looked) && canDrain(looked)) .ifPresent(list::add); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java index 7d7f797c..1ae34e1c 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java @@ -5,7 +5,7 @@ import com.minelittlepony.unicopia.ability.data.Hit; import com.minelittlepony.unicopia.ability.data.Pos; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.particle.MagicParticleEffect; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.TraceHelper; import net.minecraft.block.BlockState; import net.minecraft.item.BoneMealItem; import net.minecraft.item.ItemStack; @@ -36,7 +36,7 @@ public class EarthPonyGrowAbility implements Ability { @Override public Pos tryActivate(Pony player) { - return RayTraceHelper.doTrace(player.getMaster(), 3, 1).getBlockPos().map(Pos::new).orElse(null); + return TraceHelper.findBlock(player.getMaster(), 3, 1).map(Pos::new).orElse(null); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyKickAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyKickAbility.java index fa42717c..322935d8 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyKickAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyKickAbility.java @@ -60,8 +60,7 @@ public class EarthPonyKickAbility implements Ability { public double getCostEstimate(Pony player) { double distance = MineLPDelegate.getInstance().getPlayerPonyRace(player.getMaster()).isDefault() ? 6 : -6; - return RayTraceHelper.doTrace(player.getMaster(), distance, 1) - .getBlockPos() + return TraceHelper.findBlock(player.getMaster(), distance, 1) .filter(pos -> TreeType.at(pos, player.getReferenceWorld()) != TreeType.NONE) .isPresent() ? 3 : 1; } @@ -107,8 +106,7 @@ public class EarthPonyKickAbility implements Ability { @Nullable @Override public Pos tryActivate(Pony player) { - return RayTraceHelper.doTrace(player.getMaster(), 6 * getKickDirection(player), 1) - .getBlockPos() + return TraceHelper.findBlock(player.getMaster(), 6 * getKickDirection(player), 1) .filter(pos -> TreeType.at(pos, player.getReferenceWorld()) != TreeType.NONE) .map(Pos::new) .orElseGet(() -> getDefaultKickLocation(player)); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java index 2a9d800d..d3cea2f5 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java @@ -12,7 +12,7 @@ import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.AmuletItem; import com.minelittlepony.unicopia.particle.MagicParticleEffect; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.TraceHelper; import com.minelittlepony.unicopia.util.VecHelper; import net.minecraft.item.ItemStack; @@ -117,7 +117,7 @@ public class UnicornCastingAbility implements Ability { } else { player.setAnimation(Animation.ARMS_UP); if (s instanceof HomingSpell homer) { - RayTraceHelper.doTrace(player.getMaster(), homer.getRange(player), 1, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.and(EntityPredicates.VALID_ENTITY)).getEntity().ifPresent(homer::setTarget); + TraceHelper.findEntity(player.getMaster(), homer.getRange(player), 1, EntityPredicates.VALID_ENTITY).ifPresent(homer::setTarget); } player.playSound(USounds.SPELL_CAST_SUCCESS, 0.05F, 2.2F); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornDispellAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornDispellAbility.java index 0880e713..a9895576 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornDispellAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornDispellAbility.java @@ -10,7 +10,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.particle.MagicParticleEffect; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.TraceHelper; import com.minelittlepony.unicopia.util.VecHelper; import net.minecraft.text.Text; @@ -83,14 +83,9 @@ public class UnicornDispellAbility implements Ability { private Optional> getTarget(Pony player) { int maxDistance = player.getMaster().isCreative() ? 1000 : 100; - return RayTraceHelper.doTrace(player.getMaster(), maxDistance, 1, - EquinePredicates.IS_PLACED_SPELL) - .getEntity() - .flatMap(Caster::of); + return TraceHelper.findEntity(player.getMaster(), maxDistance, 1, EquinePredicates.IS_PLACED_SPELL).flatMap(Caster::of); } - - @Override public void preApply(Pony player, AbilitySlot slot) { player.getMagicalReserves().getExhaustion().multiply(3.3F); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java index 30ddc504..a860f396 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java @@ -8,9 +8,8 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellTyp import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.particle.MagicParticleEffect; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.TraceHelper; -import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; @@ -94,9 +93,7 @@ public class UnicornProjectileAbility implements Ability { projectile.setHydrophobic(); if (spell instanceof HomingSpell) { - RayTraceHelper.doTrace(player.getMaster(), 600, 1, EntityPredicates.EXCEPT_SPECTATOR).getEntity().filter(((HomingSpell)spell)::setTarget).ifPresent(target -> { - projectile.setHomingTarget(target); - }); + TraceHelper.findEntity(player.getMaster(), 600, 1).filter(((HomingSpell)spell)::setTarget).ifPresent(projectile::setHomingTarget); } }); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java index 074d8229..f5dca965 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java @@ -7,7 +7,8 @@ import com.minelittlepony.unicopia.ability.data.Pos; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.particle.MagicParticleEffect; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.Trace; + import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.FenceBlock; @@ -21,10 +22,7 @@ import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.sound.SoundCategory; import net.minecraft.util.Identifier; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -72,55 +70,46 @@ public class UnicornTeleportAbility implements Ability { } int maxDistance = player.getMaster().isCreative() ? 1000 : 100; - HitResult ray = RayTraceHelper.doTrace(player.getMaster(), maxDistance, 1, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR).getResult(); + World w = player.getReferenceWorld(); - if (ray.getType() == HitResult.Type.MISS) { - return null; - } + Trace trace = Trace.create(player.getMaster(), maxDistance, 1, EntityPredicates.EXCEPT_SPECTATOR); + return trace.getBlockOrEntityPos().map(pos -> { + final BlockPos originalPos = pos; - BlockPos pos; + boolean airAbove = enterable(w, pos.up()) && enterable(w, pos.up(2)); - if (ray.getType() == HitResult.Type.ENTITY) { - pos = new BlockPos(ray.getPos()); - } else { - pos = ((BlockHitResult)ray).getBlockPos(); - } + if (exception(w, pos, player.getMaster())) { + final BlockPos p = pos; + pos = trace.getSide().map(sideHit -> { + if (player.getMaster().isSneaking()) { + sideHit = sideHit.getOpposite(); + } - boolean airAbove = enterable(w, pos.up()) && enterable(w, pos.up(2)); - - if (exception(w, pos, player.getMaster()) && ray.getType() == HitResult.Type.BLOCK) { - Direction sideHit = ((BlockHitResult)ray).getSide(); - - if (player.getMaster().isSneaking()) { - sideHit = sideHit.getOpposite(); + return p.offset(sideHit); + }).orElse(pos); } - pos = pos.offset(sideHit); - } - - if (enterable(w, pos.down())) { - pos = pos.down(); - if (enterable(w, pos.down())) { - if (!airAbove) { - return null; + pos = pos.down(); + + if (enterable(w, pos.down())) { + if (!airAbove) { + return null; + } + + pos = originalPos.up(2); } - - pos = new BlockPos( - ray.getPos().getX(), - pos.getY() + 2, - ray.getPos().getZ()); } - } - if ((!enterable(w, pos) && exception(w, pos, player.getMaster())) - || (!enterable(w, pos.up()) && exception(w, pos.up(), player.getMaster()))) { - return null; - } + if ((!enterable(w, pos) && exception(w, pos, player.getMaster())) + || (!enterable(w, pos.up()) && exception(w, pos.up(), player.getMaster()))) { + return null; + } - return new Pos(pos.getX(), pos.getY(), pos.getZ()); + return new Pos(pos); + }).orElse(null); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java index 85d9db0c..55541abd 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDisguiseSpell.java @@ -3,12 +3,15 @@ package com.minelittlepony.unicopia.ability.magic.spell; import java.util.Optional; import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.effect.*; import com.minelittlepony.unicopia.entity.behaviour.Disguise; import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.projectile.ProjectileImpactListener; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.nbt.NbtCompound; @@ -70,4 +73,13 @@ public abstract class AbstractDisguiseSpell extends AbstractSpell implements Dis public Optional getAppearance() { return Optional.ofNullable(disguise); } + + public static Entity getAppearance(Entity e) { + return e instanceof PlayerEntity ? Pony.of((PlayerEntity)e) + .getSpellSlot() + .get(SpellPredicate.IS_DISGUISE, true) + .map(AbstractDisguiseSpell::getDisguise) + .map(EntityAppearance::getAppearance) + .orElse(e) : e; + } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CatapultSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CatapultSpell.java index 1cb9dfd5..547f596a 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CatapultSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CatapultSpell.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect; -import java.util.Optional; import java.util.function.Consumer; import org.jetbrains.annotations.Nullable; @@ -12,15 +11,12 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.mixin.MixinFallingBlockEntity; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.Trace; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.FallingBlockEntity; import net.minecraft.predicate.entity.EntityPredicates; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -87,16 +83,14 @@ public class CatapultSpell extends AbstractSpell implements ProjectileSpell { double maxDistance = 2 + (getTraits().get(Trait.FOCUS) - 50) * 8; - HitResult ray = RayTraceHelper.doTrace(caster.getEntity(), maxDistance, 1, EntityPredicates.EXCEPT_SPECTATOR).getResult(); - - if (ray.getType() == HitResult.Type.ENTITY) { - EntityHitResult result = (EntityHitResult)ray; - Optional.ofNullable(result.getEntity()).ifPresent(apply); - } else if (ray.getType() == HitResult.Type.BLOCK) { - if (caster.canModifyAt(((BlockHitResult)ray).getBlockPos())) { - createBlockEntity(caster.getReferenceWorld(), ((BlockHitResult)ray).getBlockPos(), apply); - } - } + Trace trace = Trace.create(caster.getEntity(), maxDistance, 1, EntityPredicates.EXCEPT_SPECTATOR); + trace.getEntity().ifPresentOrElse(apply, () -> { + trace.ifBlock(pos -> { + if (caster.canModifyAt(pos)) { + createBlockEntity(caster.getReferenceWorld(), pos, apply); + } + }); + }); } static void createBlockEntity(World world, BlockPos bpos, @Nullable Consumer apply) { diff --git a/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java b/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java index 56af4365..701b4864 100644 --- a/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java +++ b/src/main/java/com/minelittlepony/unicopia/command/DisguiseCommand.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.command; import java.util.function.Function; +import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; @@ -20,7 +21,6 @@ import net.minecraft.command.argument.NbtCompoundArgumentType; import net.minecraft.command.suggestion.SuggestionProviders; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; -import net.minecraft.entity.decoration.AbstractDecorationEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtCompound; import net.minecraft.server.command.CommandManager; @@ -77,7 +77,7 @@ public class DisguiseCommand { } static int disguise(ServerCommandSource source, PlayerEntity player, Entity entity) throws CommandSyntaxException { - if (entity == null || entity instanceof AbstractDecorationEntity) { + if (entity == null || !EquinePredicates.VALID_FOR_DISGUISE.test(entity)) { throw FAILED_EXCEPTION.create(); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java index ca94cf0f..82b1fce5 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/MobBehaviour.java @@ -1,7 +1,7 @@ package com.minelittlepony.unicopia.entity.behaviour; import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.TraceHelper; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.MobEntity; @@ -26,7 +26,7 @@ public class MobBehaviour extends EntityBehaviour { } protected LivingEntity findTarget(Pony player, T entity) { - return RayTraceHelper.findEntity(player.getEntity(), 6, 1, + return TraceHelper.findEntity(player.getEntity(), 6, 1, e -> e instanceof LivingEntity && e != entity && !player.isOwnedBy(e)) .orElseGet(() -> getDummy(entity)); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java b/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java index 092d1402..cf516d71 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java @@ -1,7 +1,5 @@ package com.minelittlepony.unicopia.item; -import java.util.Optional; - import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.advancement.UCriteria; @@ -10,7 +8,7 @@ import com.minelittlepony.unicopia.item.toxin.*; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.util.MagicalDamageSource; -import com.minelittlepony.unicopia.util.RayTraceHelper; +import com.minelittlepony.unicopia.util.TraceHelper; import com.minelittlepony.unicopia.util.Registries; import net.minecraft.entity.Entity; @@ -22,7 +20,6 @@ import net.minecraft.entity.passive.PigEntity; import net.minecraft.entity.passive.VillagerEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.*; -import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; @@ -44,14 +41,9 @@ public class ZapAppleItem extends Item implements ChameleonItem, ToxicHolder { @Override public TypedActionResult use(World world, PlayerEntity player, Hand hand) { ItemStack stack = player.getStackInHand(hand); - - Optional entity = RayTraceHelper.doTrace(player, 5, 1, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.and(e -> canFeedTo(stack, e))).getEntity(); - - if (entity.isPresent()) { - return onFedTo(stack, player, entity.get()); - } - - return super.use(world, player, hand); + return TraceHelper.findEntity(player, 5, 1, e -> canFeedTo(stack, e)) + .map(entity -> onFedTo(stack, player, entity)) + .orElseGet(() -> super.use(world, player, hand)); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/util/RayTraceHelper.java b/src/main/java/com/minelittlepony/unicopia/util/RayTraceHelper.java deleted file mode 100644 index 753fb8f0..00000000 --- a/src/main/java/com/minelittlepony/unicopia/util/RayTraceHelper.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.minelittlepony.unicopia.util; - -import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Predicate; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.projectile.ProjectileUtil; -import net.minecraft.predicate.entity.EntityPredicates; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; -import net.minecraft.util.math.Vec3d; - -public class RayTraceHelper { - public static Optional findEntity(Entity e, double distance, float tickDelta, Predicate predicate) { - return doTrace(e, distance, tickDelta, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.and(predicate)).getEntity(); - } - - /** - * Performs a ray trace from the given entity and returns - * a result for the first Entity or block that the ray intercepts. - * - * - * @param e Entity to start from - * @param distance Maximum distance - * @param tickDelta Client partial ticks - * - * @return A Trace describing what was found. - */ - public static Trace doTrace(Entity e, double distance, float tickDelta) { - return doTrace(e, distance, tickDelta, EntityPredicates.EXCEPT_SPECTATOR); - } - - /** - * Performs a ray trace from the given entity and returns - * a result for the first Entity that passes the given predicate - * or block that the ray intercepts. - * - * - * @param e Entity to start from - * @param distance Maximum distance - * @param tickDelta Client partial ticks - * @param predicate Predicate test to filter entities - * - * @return A Trace describing what was found. - */ - public static Trace doTrace(Entity e, double distance, float tickDelta, Predicate predicate) { - final Vec3d orientation = e.getRotationVec(tickDelta); - final Vec3d start = e.getCameraPosVec(tickDelta); - - final Box box = e.getBoundingBox().stretch(orientation.multiply(Math.abs(distance))).expand(10); - - EntityHitResult pointedEntity = ProjectileUtil.raycast(e, start, start.add(orientation.multiply(distance)), box, predicate, Math.abs(distance)); - - if (pointedEntity != null) { - return new Trace(pointedEntity); - } - - return new Trace(e.raycast(distance, tickDelta, false)); - } - - public static class Trace { - @Nullable - private final HitResult result; - - Trace(@Nullable HitResult result) { - this.result = result; - } - - @Nullable - public HitResult getResult() { - return result; - } - - @SuppressWarnings("unchecked") - public Optional getEntity() { - if (result != null && result.getType() == HitResult.Type.ENTITY) { - return Optional.of((T)((EntityHitResult)result).getEntity()); - } - return Optional.empty(); - } - - @SuppressWarnings("unchecked") - public Optional getEntity(Predicate predicate) { - if (result != null && result.getType() == HitResult.Type.ENTITY) { - return Optional.of((T)((EntityHitResult)result).getEntity()).filter(predicate); - } - return Optional.empty(); - } - - public Optional getBlockPos() { - if (result != null && result.getType() == HitResult.Type.BLOCK) { - return Optional.of(((BlockHitResult)result).getBlockPos()); - } - return Optional.empty(); - } - - public Trace ifEntity(Consumer consumer) { - getEntity().ifPresent(consumer); - return this; - } - - public Trace ifBlock(Consumer consumer) { - getBlockPos().ifPresent(consumer); - return this; - } - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/util/Trace.java b/src/main/java/com/minelittlepony/unicopia/util/Trace.java new file mode 100644 index 00000000..e3d78d15 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/util/Trace.java @@ -0,0 +1,76 @@ +package com.minelittlepony.unicopia.util; + +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import net.minecraft.entity.Entity; +import net.minecraft.util.hit.*; +import net.minecraft.util.math.*; + +@SuppressWarnings("unchecked") +public record Trace( + Optional result + ) { + /** + * Performs a ray trace from the given entity and returns + * a result for the first Entity that passes the given predicate + * or block that the ray intercepts. + * + * + * @param e Entity to start from + * @param distance Maximum distance + * @param tickDelta Client partial ticks + * @param predicate Predicate test to filter entities + * + * @return A Trace describing what was found. + */ + public static Trace create(Entity e, double distance, float tickDelta, Predicate predicate) { + return new Trace( + ((Optional)(Optional)TraceHelper.traceEntity(e, distance, tickDelta, predicate)) + .or(() -> Optional.ofNullable(e.raycast(distance, tickDelta, false))) + ); + } + + static T toEntity(EntityHitResult hit) { + return (T)hit.getEntity(); + } + + public Optional getEntityResult() { + return result() + .filter(s -> s.getType() == HitResult.Type.ENTITY) + .map(EntityHitResult.class::cast); + } + + public Optional getBlockResult() { + return result() + .filter(s -> s.getType() == HitResult.Type.BLOCK) + .map(BlockHitResult.class::cast); + } + + public Optional getEntity() { + return getEntityResult().map(Trace::toEntity); + } + + public Optional getBlockPos() { + return getBlockResult().map(BlockHitResult::getBlockPos); + } + + public Optional getBlockOrEntityPos() { + return getBlockPos().or(() -> getEntity().map(Entity::getBlockPos)); + } + + public Optional getSide() { + return getBlockResult().map(BlockHitResult::getSide); + } + + public Trace ifEntity(Consumer consumer) { + getEntity().ifPresent(consumer); + return this; + } + + public Trace ifBlock(Consumer consumer) { + getBlockPos().ifPresent(consumer); + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/util/TraceHelper.java b/src/main/java/com/minelittlepony/unicopia/util/TraceHelper.java new file mode 100644 index 00000000..e8a2ddca --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/util/TraceHelper.java @@ -0,0 +1,88 @@ +package com.minelittlepony.unicopia.util; + +import java.util.*; +import java.util.function.*; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.projectile.ProjectileUtil; +import net.minecraft.predicate.entity.EntityPredicates; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.math.*; +import net.minecraft.world.BlockView; + +public class TraceHelper { + /** + * Performs a ray trace from the given entity and returns + * a result for the first Entity that the ray intercepts. + * + * + * @param e Entity to start from + * @param distance Maximum distance + * @param tickDelta Client partial ticks + */ + public static Optional findEntity(Entity e, double distance, float tickDelta, Predicate predicate) { + return traceEntity(e, distance, tickDelta, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.and(predicate)).map(Trace::toEntity); + } + + /** + * Performs a ray trace from the given entity and returns + * a result for the first Entity that the ray intercepts. + * + * + * @param e Entity to start from + * @param distance Maximum distance + * @param tickDelta Client partial ticks + */ + public static Optional findEntity(Entity e, double distance, float tickDelta) { + return traceEntity(e, distance, tickDelta, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR).map(Trace::toEntity); + } + + /** + * Performs a ray trace from the given entity and returns + * a result for the first block that the ray intercepts. + * + * + * @param e Entity to start from + * @param distance Maximum distance + * @param tickDelta Client partial ticks + */ + public static Optional findBlock(Entity e, double distance, float tickDelta) { + return Trace.create(e, distance, tickDelta, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR).getBlockPos(); + } + + /** + * Performs a raytrace and returns all matching blocks the ray passed through. + * + * @param e Entity to start from + * @param distance Maximum distance + * @param tickDelta Client partial ticks + * @param predicate Predicate test to filter block states + * + * @return List of matching positions + */ + public static List findBlocks(Entity e, double distance, float tickDelta, Predicate predicate) { + final Vec3d orientation = e.getRotationVec(tickDelta); + final Vec3d start = e.getCameraPosVec(tickDelta); + + return BlockView.raycast(start, start.add(orientation.multiply(distance)), new ArrayList(), (ctx, pos) -> { + if (predicate.test(e.world.getBlockState(pos))) { + ctx.add(pos); + } + return null; + }, ctx -> { + return ctx; + }); + } + + static Optional traceEntity(Entity e, double distance, float tickDelta, Predicate predicate) { + final Vec3d orientation = e.getRotationVec(tickDelta); + final Vec3d start = e.getCameraPosVec(tickDelta); + + final Box box = e.getBoundingBox().stretch(orientation.multiply(Math.abs(distance))).expand(10); + + return Optional.ofNullable( + ProjectileUtil.raycast(e, start, start.add(orientation.multiply(distance)), box, predicate, Math.abs(distance)) + ); + } +}