diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java index 86c225f1..872aba90 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.*; import com.minelittlepony.unicopia.ability.Ability; +import com.minelittlepony.unicopia.ability.magic.spell.effect.AreaProtectionSpell; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.entity.*; import com.minelittlepony.unicopia.entity.damage.UDamageSources; @@ -111,7 +112,19 @@ public interface Caster extends } default boolean canCastAt(Vec3d pos) { - return !Ether.get(asWorld()).anyMatch(SpellType.ARCANE_PROTECTION, (spell, caster) -> spell.blocksMagicFor(caster, this, pos)); + return !Ether.get(asWorld()).anyMatch(SpellType.ARCANE_PROTECTION, entry -> { + var target = entry.entity.getTarget().orElse(null); + if (target != null && target.pos().distanceTo(pos) <= entry.getRadius()) { + Caster caster = entry.getCaster(); + if (caster != null) { + AreaProtectionSpell spell = entry.getSpell(); + if (spell != null) { + return spell.blocksMagicFor(caster, this, pos); + } + } + } + return false; + }); } default boolean canUse(Ability ability) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AreaProtectionSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AreaProtectionSpell.java index 5ae9df44..093ea63f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AreaProtectionSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/AreaProtectionSpell.java @@ -1,10 +1,13 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect; +import java.util.List; + import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.spell.AbstractAreaEffectSpell; import com.minelittlepony.unicopia.ability.magic.spell.Situation; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; +import com.minelittlepony.unicopia.entity.effect.EffectUtils; import com.minelittlepony.unicopia.entity.mob.UEntities; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.FriendshipBraceletItem; @@ -13,6 +16,8 @@ import com.minelittlepony.unicopia.server.world.Ether; import com.minelittlepony.unicopia.util.shape.Sphere; import net.minecraft.entity.Entity; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -22,6 +27,15 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell { .with(Trait.STRENGTH, 30) .build(); + + static void appendTooltip(CustomisedSpellType type, List tooltip) { + float addedRange = type.traits().get(Trait.POWER); + if (addedRange != 0) { + tooltip.add(EffectUtils.formatModifierChange("spell.unicopia.shield.additional_range", addedRange, false)); + } + tooltip.add(Text.literal(" ").append(Text.translatable("spell.unicopia.shield.caston.location")).formatted(Formatting.GRAY)); + } + protected AreaProtectionSpell(CustomisedSpellType type) { super(type); } @@ -33,7 +47,7 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell { return false; } - float radius = (float)getDrawDropOffRange(source); + float radius = (float)getRange(source); if (source.isClient()) { Vec3d origin = source.getOriginVector(); @@ -44,7 +58,7 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell { } }); } else { - Ether.get(source.asWorld()).getOrCreate(this, source); + Ether.get(source.asWorld()).getOrCreate(this, source).setRadius(radius); } source.findAllSpellsInRange(radius, e -> isValidTarget(source, e)).filter(caster -> !caster.hasCommonOwner(source)).forEach(caster -> { @@ -54,10 +68,7 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell { return !isDead(); } - /** - * Calculates the maximum radius of the shield. aka The area of effect. - */ - public double getDrawDropOffRange(Caster source) { + private double getRange(Caster source) { float multiplier = source instanceof Pony pony && pony.asEntity().isSneaking() ? 1 : 2; float min = 4 + getTraits().get(Trait.POWER); double range = (min + (source.getLevel().getScaled(4) * 2)) / multiplier; @@ -69,7 +80,7 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell { public boolean blocksMagicFor(Caster source, Caster other, Vec3d position) { return !FriendshipBraceletItem.isComrade(other, other.asEntity()) - && source.getOriginVector().distanceTo(position) <= getDrawDropOffRange(source); + && source.getOriginVector().distanceTo(position) <= getRange(source); } protected boolean isValidTarget(Caster source, Entity entity) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java index 434d6ad7..cec7e61a 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java @@ -178,15 +178,17 @@ public class HydrophobicSpell extends AbstractSpell { } public static boolean blocksFluidFlow(BlockView world, BlockPos pos, FluidState state) { - if (world instanceof ServerWorld sw) { - return Ether.get(sw).anyMatch(SpellType.HYDROPHOBIC, entry -> { - var spell = entry.getSpell(); - var target = entry.entity.getTarget().orElse(null); - return spell != null && target != null && spell.blocksFlow(entry, target.pos(), pos, state); - }); + if (!(world instanceof ServerWorld sw)) { + return false; } - return false; - + return Ether.get(sw).anyMatch(SpellType.HYDROPHOBIC, entry -> { + var target = entry.entity.getTarget().orElse(null); + if (target == null || !pos.isWithinDistance(target.pos(), entry.getRadius() + 1)) { + return false; + } + var spell = entry.getSpell(); + return spell != null && target != null && spell.blocksFlow(entry, target.pos(), pos, state); + }); } }