mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-30 16:28:00 +01:00
Fix shields, fix black holes being offset, and remove the maximum cap on black holes sizes
This commit is contained in:
parent
4e8f683737
commit
f3f38aae7b
9 changed files with 69 additions and 39 deletions
|
@ -32,7 +32,11 @@ public interface Owned<E extends Entity> {
|
|||
Optional<UUID> getMasterId();
|
||||
|
||||
default boolean isOwnerOrFriend(Entity target) {
|
||||
return FriendshipBraceletItem.isComrade(this, target) || isOwnerOrVehicle(target);
|
||||
return isFriend(target) || isOwnerOrVehicle(target);
|
||||
}
|
||||
|
||||
default boolean isFriend(Entity target) {
|
||||
return FriendshipBraceletItem.isComrade(this, target);
|
||||
}
|
||||
|
||||
default boolean isOwnerOrVehicle(@Nullable Entity target) {
|
||||
|
|
|
@ -160,7 +160,7 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS
|
|||
|
||||
private void spawnPlacedEntity(Caster<?> source) {
|
||||
CastSpellEntity entity = UEntities.CAST_SPELL.create(source.asWorld());
|
||||
Vec3d pos = getPosition().orElse(position.orElse(source.getOriginVector()));
|
||||
Vec3d pos = getPosition().orElse(position.orElse(source.asEntity().getPos()));
|
||||
entity.updatePositionAndAngles(pos.x, pos.y, pos.z, source.asEntity().getYaw(), source.asEntity().getPitch());
|
||||
PlaceableSpell copy = spell.toPlaceable();
|
||||
if (spell instanceof PlacementDelegate delegate) {
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
@ -17,7 +21,16 @@ public interface AttractionUtils {
|
|||
}
|
||||
|
||||
static double getMass(Entity entity) {
|
||||
return entity.getWidth() * entity.getHeight();
|
||||
double baseMass = entity.getWidth() * entity.getHeight();
|
||||
if (entity instanceof ItemEntity item) {
|
||||
baseMass *= item.getStack().getCount();
|
||||
@Nullable
|
||||
Block block = Block.getBlockFromItem(item.getStack().getItem());
|
||||
if (block != null) {
|
||||
baseMass *= MathHelper.clamp(1 + block.getHardness(), 1, 5);
|
||||
}
|
||||
}
|
||||
return baseMass;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,12 +46,11 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
|
|||
.with(Trait.DARKNESS, 100)
|
||||
.build();
|
||||
|
||||
private static final Vec3d SPHERE_OFFSET = new Vec3d(0, 2, 0);
|
||||
|
||||
private float accumulatedMass = 0;
|
||||
|
||||
protected DarkVortexSpell(CustomisedSpellType<?> type) {
|
||||
super(type);
|
||||
targetSelecter.setTargetowner(true).setTargetAllies(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,7 +86,8 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
|
|||
ParticleUtils.spawnParticle(source.asWorld(), LightningBoltParticleEffect.DEFAULT, getOrigin(source), Vec3d.ZERO);
|
||||
}
|
||||
|
||||
return super.tick(source, situation);
|
||||
super.tick(source, situation);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -134,7 +134,7 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
|
|||
|
||||
@Override
|
||||
protected Vec3d getOrigin(Caster<?> source) {
|
||||
return source.getOriginVector().add(SPHERE_OFFSET);
|
||||
return source.getOriginVector().add(0, getEventHorizonRadius() / 2D, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -182,7 +182,7 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
|
|||
}
|
||||
|
||||
private double getMass() {
|
||||
return Math.min(15, 0.1F + accumulatedMass / 10F);
|
||||
return 0.1F + accumulatedMass / 10F;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
|||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||
import com.minelittlepony.unicopia.util.Lerp;
|
||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
@ -41,13 +42,10 @@ public class ShieldSpell extends AbstractSpell {
|
|||
.with(Trait.AIR, 9)
|
||||
.build();
|
||||
|
||||
private final TargetSelecter targetSelecter = new TargetSelecter(this).setFilter(this::isValidTarget);
|
||||
protected final TargetSelecter targetSelecter = new TargetSelecter(this).setFilter(this::isValidTarget);
|
||||
|
||||
private float prevRadius;
|
||||
private float radius;
|
||||
|
||||
private float rangeMultiplier;
|
||||
private float targetRangeMultiplier;
|
||||
private final Lerp radius = new Lerp(0);
|
||||
private final Lerp rangeMultiplier = new Lerp(1);
|
||||
|
||||
private int prevTicksDying;
|
||||
private int ticksDying;
|
||||
|
@ -69,7 +67,7 @@ public class ShieldSpell extends AbstractSpell {
|
|||
protected void generateParticles(Caster<?> source) {
|
||||
Vec3d origin = getOrigin(source);
|
||||
|
||||
source.spawnParticles(origin, new Sphere(true, radius), (int)(radius * 6), pos -> {
|
||||
source.spawnParticles(origin, new Sphere(true, radius.getValue()), (int)(radius.getValue() * 6), pos -> {
|
||||
source.addParticle(new MagicParticleEffect(getType().getColor()), pos, Vec3d.ZERO);
|
||||
|
||||
if (source.asWorld().random.nextInt(10) == 0 && source.asWorld().random.nextFloat() < source.getCorruption().getScaled(1)) {
|
||||
|
@ -80,8 +78,7 @@ public class ShieldSpell extends AbstractSpell {
|
|||
|
||||
@Override
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
prevRadius = radius;
|
||||
radius = (float)getDrawDropOffRange(source);
|
||||
radius.update((float)getDrawDropOffRange(source), 200L);
|
||||
|
||||
if (source.isClient()) {
|
||||
generateParticles(source);
|
||||
|
@ -118,7 +115,7 @@ public class ShieldSpell extends AbstractSpell {
|
|||
|
||||
cost *= costMultiplier / ((1 + source.getLevel().get()) * 3F);
|
||||
cost /= knowledge;
|
||||
cost += radius / 10F;
|
||||
cost += radius.getValue() / 10F;
|
||||
|
||||
if (!source.subtractEnergyCost(cost)) {
|
||||
setDead();
|
||||
|
@ -126,8 +123,8 @@ public class ShieldSpell extends AbstractSpell {
|
|||
}
|
||||
|
||||
public float getRadius(float tickDelta) {
|
||||
float base = MathHelper.lerp(tickDelta, prevRadius, radius);
|
||||
float scale = MathHelper.clamp(MathHelper.lerp(tickDelta, prevTicksDying, ticksDying), 0, 1);
|
||||
float base = radius.getValue();
|
||||
float scale = 1 - MathHelper.clamp(MathHelper.lerp(tickDelta, (float)prevTicksDying, ticksDying), 0, 1);
|
||||
return base * scale;
|
||||
}
|
||||
|
||||
|
@ -135,17 +132,10 @@ public class ShieldSpell extends AbstractSpell {
|
|||
* Calculates the maximum radius of the shield. aka The area of effect.
|
||||
*/
|
||||
public double getDrawDropOffRange(Caster<?> source) {
|
||||
targetRangeMultiplier = source instanceof Pony pony && pony.asEntity().isSneaking() ? 1 : 2;
|
||||
if (rangeMultiplier < targetRangeMultiplier - 0.1F) {
|
||||
rangeMultiplier += 0.1F;
|
||||
} else if (rangeMultiplier > targetRangeMultiplier + 0.1) {
|
||||
rangeMultiplier -= 0.1F;
|
||||
} else {
|
||||
rangeMultiplier = targetRangeMultiplier;
|
||||
}
|
||||
rangeMultiplier.update(source instanceof Pony pony && pony.asEntity().isSneaking() ? 1 : 2, 500L);
|
||||
|
||||
float min = (source instanceof Pony ? 4 : 6) + getTraits().get(Trait.POWER);
|
||||
double range = (min + (source.getLevel().getScaled(source instanceof Pony ? 4 : 40) * (source instanceof Pony ? 2 : 10))) / rangeMultiplier;
|
||||
double range = (min + (source.getLevel().getScaled(source instanceof Pony ? 4 : 40) * (source instanceof Pony ? 2 : 10))) / rangeMultiplier.getValue();
|
||||
|
||||
return range;
|
||||
}
|
||||
|
@ -175,9 +165,9 @@ public class ShieldSpell extends AbstractSpell {
|
|||
|
||||
protected long applyEntities(Caster<?> source) {
|
||||
Vec3d origin = getOrigin(source);
|
||||
targetSelecter.getEntities(source, radius).forEach(i -> {
|
||||
targetSelecter.getEntities(source, radius.getValue()).forEach(i -> {
|
||||
try {
|
||||
applyRadialEffect(source, i, i.getPos().distanceTo(origin), radius);
|
||||
applyRadialEffect(source, i, i.getPos().distanceTo(origin), radius.getValue());
|
||||
} catch (Throwable e) {
|
||||
Unicopia.LOGGER.error("Error updating radial effect", e);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ public class TargetSelecter {
|
|||
|
||||
private BiPredicate<Caster<?>, Entity> filter = (a, b) -> true;
|
||||
|
||||
private boolean targetOwner;
|
||||
private boolean targetAllies;
|
||||
|
||||
public TargetSelecter(Spell spell) {
|
||||
this.spell = spell;
|
||||
}
|
||||
|
@ -30,18 +33,34 @@ public class TargetSelecter {
|
|||
return this;
|
||||
}
|
||||
|
||||
public TargetSelecter setTargetowner(boolean targetOwner) {
|
||||
this.targetOwner = targetOwner;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TargetSelecter setTargetAllies(boolean targetAllies) {
|
||||
this.targetAllies = targetAllies;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Stream<Entity> getEntities(Caster<?> source, double radius) {
|
||||
targets.values().removeIf(Target::tick);
|
||||
return source.findAllEntitiesInRange(radius)
|
||||
.filter(EntityPredicates.VALID_ENTITY)
|
||||
.filter(EquinePredicates.EXCEPT_MAGIC_IMMUNE)
|
||||
.filter(entity -> entity != source.asEntity() && validTarget(spell, source, entity) && filter.test(source, entity))
|
||||
.filter(entity -> entity != source.asEntity() && checkAlliegance(spell, source, entity) && filter.test(source, entity))
|
||||
.map(i -> {
|
||||
targets.computeIfAbsent(i.getUuid(), Target::new);
|
||||
return i;
|
||||
});
|
||||
}
|
||||
|
||||
private boolean checkAlliegance(Affine affine, Caster<?> source, Entity target) {
|
||||
boolean isOwner = !targetOwner && source.isOwnerOrVehicle(target);
|
||||
boolean isFriend = !targetAllies && affine.applyInversion(source, source.isFriend(target));
|
||||
return !(isOwner || isFriend);
|
||||
}
|
||||
|
||||
public long getTotalDamaged() {
|
||||
return targets.values().stream().filter(Target::canHurt).count();
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public class DarkVortexSpellRenderer extends SpellRenderer<DarkVortexSpell> {
|
|||
SphereModel.DISK.render(matrices, vertices.getBuffer(RenderLayers.getEndPortal()), light, 1, radius * 0.5F, 1, 0.5F, 0, 1);
|
||||
|
||||
if (radius > 0.3F && absDistance > radius) {
|
||||
radius *= 3 + radius;
|
||||
radius *= Math.min(2, 3 + radius);
|
||||
|
||||
matrices.scale(radius, radius, radius);
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90));
|
||||
|
|
|
@ -43,9 +43,9 @@ public class ShieldSpellRenderer extends SpellRenderer<ShieldSpell> {
|
|||
model.render(matrices, buffer, light, 1, radius, colors[0], colors[1], colors[2], alpha * 0.2F);
|
||||
} else {
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180));
|
||||
model.render(matrices, buffer, light, 1, radius + thickness, colors[0], colors[1], colors[2], alpha * 0.08F);
|
||||
model.render(matrices, buffer, light, 1, radius - thickness, colors[0], colors[1], colors[2], alpha * 0.05F);
|
||||
model.render(matrices, buffer, light, 1, radius + thickness * 2, colors[0], colors[1], colors[2], alpha * 0.05F);
|
||||
SphereModel.SPHERE.render(matrices, buffer, light, 1, radius + thickness, colors[0], colors[1], colors[2], alpha * 0.08F);
|
||||
SphereModel.SPHERE.render(matrices, buffer, light, 1, radius - thickness, colors[0], colors[1], colors[2], alpha * 0.05F);
|
||||
SphereModel.SPHERE.render(matrices, buffer, light, 1, radius + thickness * 2, colors[0], colors[1], colors[2], alpha * 0.05F);
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
|
|
|
@ -105,11 +105,15 @@ public class EffectSync implements SpellContainer, NbtSerialisable {
|
|||
|
||||
@Override
|
||||
public boolean removeWhere(Predicate<Spell> test, boolean update) {
|
||||
return reduce(update, (initial, effect) -> {
|
||||
if (!test.test(effect)) {
|
||||
return reduce(update, (initial, spell) -> {
|
||||
if (!test.test(spell)) {
|
||||
return initial;
|
||||
}
|
||||
spells.removeReference(effect);
|
||||
spell.setDead();
|
||||
spell.tickDying(owner);
|
||||
if (spell.isDead()) {
|
||||
spells.removeReference(spell);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue