mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-26 06:24:31 +01:00
Move various gravitation/force/physics stuff to a utility class
This commit is contained in:
parent
ca7ff47451
commit
ddbf75a44f
7 changed files with 89 additions and 58 deletions
|
@ -17,6 +17,13 @@ public interface SpellPredicate<T extends Spell> extends Predicate<Spell> {
|
||||||
SpellPredicate<AbstractDisguiseSpell> IS_DISGUISE = s -> s instanceof AbstractDisguiseSpell;
|
SpellPredicate<AbstractDisguiseSpell> IS_DISGUISE = s -> s instanceof AbstractDisguiseSpell;
|
||||||
SpellPredicate<ShieldSpell> IS_SHIELD_LIKE = spell -> spell instanceof ShieldSpell;
|
SpellPredicate<ShieldSpell> IS_SHIELD_LIKE = spell -> spell instanceof ShieldSpell;
|
||||||
|
|
||||||
|
default SpellPredicate<T> and(SpellPredicate<T> predicate) {
|
||||||
|
SpellPredicate<T> self = this;
|
||||||
|
return s -> {
|
||||||
|
return self.test(s) && predicate.test(s);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
default boolean isOn(Caster<?> caster) {
|
default boolean isOn(Caster<?> caster) {
|
||||||
return caster.getSpellSlot().contains(this);
|
return caster.getSpellSlot().contains(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
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.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public interface AttractionUtils {
|
||||||
|
|
||||||
|
static double getAttractiveForce(double wellMass, Vec3d wellPosition, Entity target) {
|
||||||
|
return (wellMass * AttractionUtils.getMass(target)) / MathHelper.square(wellPosition.distanceTo(target.getPos()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static double getMass(Entity entity) {
|
||||||
|
return entity.getWidth() * entity.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a force to the given entity relative to a given center position
|
||||||
|
*/
|
||||||
|
static void applyForce(Vec3d center, Entity target, double force, double yChange, boolean clampVelocity) {
|
||||||
|
if (clampVelocity) {
|
||||||
|
target.setVelocity(target.getVelocity().multiply(Math.min(1, 1 - force)));
|
||||||
|
}
|
||||||
|
center = target.getPos().subtract(center).normalize().multiply(force);
|
||||||
|
|
||||||
|
if (target instanceof LivingEntity) {
|
||||||
|
center = center.multiply(1 / (1 + EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, (LivingEntity)target)));
|
||||||
|
}
|
||||||
|
|
||||||
|
target.addVelocity(
|
||||||
|
center.x,
|
||||||
|
center.y + yChange,
|
||||||
|
center.z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a force to apply based on the given player's given race.
|
||||||
|
*/
|
||||||
|
static double getForceAdjustment(Entity entity) {
|
||||||
|
return Pony.of(entity).map(pony -> {
|
||||||
|
double force = 0.75;
|
||||||
|
|
||||||
|
if (pony.getSpecies().canUseEarth()) {
|
||||||
|
force /= 2;
|
||||||
|
|
||||||
|
if (pony.getMaster().isSneaking()) {
|
||||||
|
force /= 6;
|
||||||
|
}
|
||||||
|
} else if (pony.getSpecies().canFly()) {
|
||||||
|
force *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return force;
|
||||||
|
}).orElse(1D);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.ProjectileSpell;
|
||||||
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.player.Pony;
|
|
||||||
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.UParticles;
|
import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
|
@ -13,7 +12,6 @@ import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.ItemEntity;
|
import net.minecraft.entity.ItemEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
@ -53,15 +51,15 @@ public class AttractiveSpell extends ShieldSpell implements ProjectileSpell {
|
||||||
|
|
||||||
boolean isGood = isFriendlyTogether(source);
|
boolean isGood = isFriendlyTogether(source);
|
||||||
|
|
||||||
if (isGood && target instanceof PlayerEntity) {
|
if (isGood) {
|
||||||
force *= calculateAdjustedForce(Pony.of((PlayerEntity)target));
|
force *= AttractionUtils.getForceAdjustment(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isGood && source.getWorld().random.nextInt(4500) == 0) {
|
if (!isGood && source.getWorld().random.nextInt(4500) == 0) {
|
||||||
source.getEntity().damage(MagicalDamageSource.create("vortex"), 4);
|
source.getEntity().damage(MagicalDamageSource.create("vortex"), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForce(getOrigin(source), target, -force, 0);
|
AttractionUtils.applyForce(getOrigin(source), target, -force, 0, false);
|
||||||
|
|
||||||
float maxVel = !isFriendlyTogether(source) ? 1 : 1.6f;
|
float maxVel = !isFriendlyTogether(source) ? 1 : 1.6f;
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileSpell
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getAttractiveForce(Caster<?> source, Entity target) {
|
private double getAttractiveForce(Caster<?> source, Entity target) {
|
||||||
return (getMass() * getMass(target)) / Math.pow(getOrigin(source).distanceTo(target.getPos()), 2);
|
return AttractionUtils.getAttractiveForce(getMass(), getOrigin(source), target);
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getMass() {
|
private double getMass() {
|
||||||
|
@ -197,10 +197,6 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileSpell
|
||||||
return 10 + Math.min(15, Math.min(0.5F + pulse, (float)Math.exp(age) / 8F - 90) + accumulatedMass / 10F) + pulse;
|
return 10 + Math.min(15, Math.min(0.5F + pulse, (float)Math.exp(age) / 8F - 90) + accumulatedMass / 10F) + pulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getMass(Entity entity) {
|
|
||||||
return entity.getWidth() * entity.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyRadialEffect(Caster<?> source, Entity target, double distance, double radius) {
|
protected void applyRadialEffect(Caster<?> source, Entity target, double distance, double radius) {
|
||||||
|
|
||||||
|
@ -227,20 +223,21 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileSpell
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
accumulatedMass += getMass(target);
|
double massOfTarget = AttractionUtils.getMass(target);
|
||||||
|
|
||||||
|
accumulatedMass += massOfTarget;
|
||||||
setDirty();
|
setDirty();
|
||||||
target.damage(MagicalDamageSource.create("black_hole"), Integer.MAX_VALUE);
|
target.damage(MagicalDamageSource.create("black_hole"), Integer.MAX_VALUE);
|
||||||
if (!(target instanceof PlayerEntity)) {
|
if (!(target instanceof PlayerEntity)) {
|
||||||
target.discard();
|
target.discard();
|
||||||
}
|
}
|
||||||
|
|
||||||
source.subtractEnergyCost(-getMass(target) * 10);
|
source.subtractEnergyCost(-massOfTarget * 10);
|
||||||
source.getWorld().playSound(null, source.getOrigin(), USounds.AMBIENT_DARK_VORTEX_MOOD, SoundCategory.AMBIENT, 2, 0.02F);
|
source.getWorld().playSound(null, source.getOrigin(), USounds.AMBIENT_DARK_VORTEX_MOOD, SoundCategory.AMBIENT, 2, 0.02F);
|
||||||
} else {
|
} else {
|
||||||
double force = getAttractiveForce(source, target);
|
double force = getAttractiveForce(source, target);
|
||||||
|
|
||||||
target.setVelocity(target.getVelocity().multiply(Math.min(1, 1 - force)));
|
AttractionUtils.applyForce(getOrigin(source), target, -force, 0, true);
|
||||||
applyForce(getOrigin(source), target, -force, 0);
|
|
||||||
|
|
||||||
source.subtractEnergyCost(-2);
|
source.subtractEnergyCost(-2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,6 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
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.player.Pony;
|
|
||||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
|
||||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||||
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
||||||
|
@ -16,7 +14,6 @@ import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||||
|
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EyeOfEnderEntity;
|
import net.minecraft.entity.EyeOfEnderEntity;
|
||||||
import net.minecraft.entity.FallingBlockEntity;
|
import net.minecraft.entity.FallingBlockEntity;
|
||||||
|
@ -24,7 +21,6 @@ import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.TntEntity;
|
import net.minecraft.entity.TntEntity;
|
||||||
import net.minecraft.entity.Entity.RemovalReason;
|
import net.minecraft.entity.Entity.RemovalReason;
|
||||||
import net.minecraft.entity.decoration.ArmorStandEntity;
|
import net.minecraft.entity.decoration.ArmorStandEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
|
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
|
||||||
import net.minecraft.entity.vehicle.BoatEntity;
|
import net.minecraft.entity.vehicle.BoatEntity;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
@ -160,50 +156,13 @@ public class ShieldSpell extends AbstractSpell {
|
||||||
} else if (target instanceof LivingEntity) {
|
} else if (target instanceof LivingEntity) {
|
||||||
double force = Math.max(0.1, radius / 4);
|
double force = Math.max(0.1, radius / 4);
|
||||||
|
|
||||||
if (isFriendlyTogether(source) && target instanceof PlayerEntity) {
|
if (isFriendlyTogether(source)) {
|
||||||
force *= calculateAdjustedForce(Pony.of((PlayerEntity)target));
|
force *= AttractionUtils.getForceAdjustment(target);
|
||||||
} else {
|
} else {
|
||||||
force *= 0.75;
|
force *= 0.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForce(pos, target, force, distance);
|
AttractionUtils.applyForce(pos, target, force, (distance < 1 ? distance : 0), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies a force to the given entity based on distance from the source.
|
|
||||||
*/
|
|
||||||
protected void applyForce(Vec3d pos, Entity target, double force, double distance) {
|
|
||||||
pos = target.getPos().subtract(pos).normalize().multiply(force);
|
|
||||||
|
|
||||||
if (target instanceof LivingEntity) {
|
|
||||||
pos = pos.multiply(1 / (1 + EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, (LivingEntity)target)));
|
|
||||||
}
|
|
||||||
|
|
||||||
target.addVelocity(
|
|
||||||
pos.x,
|
|
||||||
pos.y + (distance < 1 ? distance : 0),
|
|
||||||
pos.z
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a force to apply based on the given player's given race.
|
|
||||||
*/
|
|
||||||
protected double calculateAdjustedForce(Pony player) {
|
|
||||||
double force = 0.75;
|
|
||||||
|
|
||||||
if (player.getSpecies().canUseEarth()) {
|
|
||||||
force /= 2;
|
|
||||||
|
|
||||||
if (player.getMaster().isSneaking()) {
|
|
||||||
force /= 6;
|
|
||||||
}
|
|
||||||
} else if (player.getSpecies().canFly()) {
|
|
||||||
force *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return force;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,10 @@ public class EntityReference<T extends Entity> implements NbtSerialisable {
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean referenceEquals(Entity entity) {
|
||||||
|
return entity != null && entity.getUuid().equals(uuid.orElse(null));
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPresent(World world) {
|
public boolean isPresent(World world) {
|
||||||
return getOrEmpty(world).isPresent();
|
return getOrEmpty(world).isPresent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -598,6 +598,10 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
||||||
return player == null ? null : ((PonyContainer<Pony>)player).get();
|
return player == null ? null : ((PonyContainer<Pony>)player).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Optional<Pony> of(Entity entity) {
|
||||||
|
return entity instanceof PlayerEntity ? PonyContainer.of(entity).map(a -> (Pony)a.get()) : Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean equal(GameProfile one, GameProfile two) {
|
public static boolean equal(GameProfile one, GameProfile two) {
|
||||||
return one == two || (one != null && two != null && one.getId().equals(two.getId()));
|
return one == two || (one != null && two != null && one.getId().equals(two.getId()));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue