Add tooltip for area protection spell and make use of the cached radius from the Ether entry

This commit is contained in:
Sollace 2024-05-23 17:38:11 +01:00
parent d909ee47f1
commit c61f2ce834
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
3 changed files with 42 additions and 16 deletions

View file

@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.*; import com.minelittlepony.unicopia.*;
import com.minelittlepony.unicopia.ability.Ability; 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.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.entity.*; import com.minelittlepony.unicopia.entity.*;
import com.minelittlepony.unicopia.entity.damage.UDamageSources; import com.minelittlepony.unicopia.entity.damage.UDamageSources;
@ -111,7 +112,19 @@ public interface Caster<E extends Entity> extends
} }
default boolean canCastAt(Vec3d pos) { 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) { default boolean canUse(Ability<?> ability) {

View file

@ -1,10 +1,13 @@
package com.minelittlepony.unicopia.ability.magic.spell.effect; 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.Caster;
import com.minelittlepony.unicopia.ability.magic.spell.AbstractAreaEffectSpell; import com.minelittlepony.unicopia.ability.magic.spell.AbstractAreaEffectSpell;
import com.minelittlepony.unicopia.ability.magic.spell.Situation; 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.SpellTraits;
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; 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.mob.UEntities;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.item.FriendshipBraceletItem; 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 com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.entity.Entity; 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.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -22,6 +27,15 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell {
.with(Trait.STRENGTH, 30) .with(Trait.STRENGTH, 30)
.build(); .build();
static void appendTooltip(CustomisedSpellType<PortalSpell> type, List<Text> 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) { protected AreaProtectionSpell(CustomisedSpellType<?> type) {
super(type); super(type);
} }
@ -33,7 +47,7 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell {
return false; return false;
} }
float radius = (float)getDrawDropOffRange(source); float radius = (float)getRange(source);
if (source.isClient()) { if (source.isClient()) {
Vec3d origin = source.getOriginVector(); Vec3d origin = source.getOriginVector();
@ -44,7 +58,7 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell {
} }
}); });
} else { } 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 -> { 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(); return !isDead();
} }
/** private double getRange(Caster<?> source) {
* Calculates the maximum radius of the shield. aka The area of effect.
*/
public double getDrawDropOffRange(Caster<?> source) {
float multiplier = source instanceof Pony pony && pony.asEntity().isSneaking() ? 1 : 2; float multiplier = source instanceof Pony pony && pony.asEntity().isSneaking() ? 1 : 2;
float min = 4 + getTraits().get(Trait.POWER); float min = 4 + getTraits().get(Trait.POWER);
double range = (min + (source.getLevel().getScaled(4) * 2)) / multiplier; 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) { public boolean blocksMagicFor(Caster<?> source, Caster<?> other, Vec3d position) {
return !FriendshipBraceletItem.isComrade(other, other.asEntity()) 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) { protected boolean isValidTarget(Caster<?> source, Entity entity) {

View file

@ -178,15 +178,17 @@ public class HydrophobicSpell extends AbstractSpell {
} }
public static boolean blocksFluidFlow(BlockView world, BlockPos pos, FluidState state) { public static boolean blocksFluidFlow(BlockView world, BlockPos pos, FluidState state) {
if (world instanceof ServerWorld sw) { if (!(world instanceof ServerWorld sw)) {
return Ether.get(sw).anyMatch(SpellType.HYDROPHOBIC, entry -> { return false;
var spell = entry.getSpell();
var target = entry.entity.getTarget().orElse(null);
return spell != null && target != null && spell.blocksFlow(entry, target.pos(), pos, state);
});
} }
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);
});
} }
} }