2020-04-15 14:22:03 +02:00
|
|
|
package com.minelittlepony.unicopia.ability;
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2021-08-04 15:38:03 +02:00
|
|
|
import org.jetbrains.annotations.Nullable;
|
2020-04-26 19:33:10 +02:00
|
|
|
|
2020-04-15 14:22:03 +02:00
|
|
|
import com.minelittlepony.unicopia.Race;
|
2020-04-25 15:37:17 +02:00
|
|
|
import com.minelittlepony.unicopia.ability.data.Hit;
|
2022-09-16 17:54:46 +02:00
|
|
|
import com.minelittlepony.unicopia.block.data.BlockDestructionManager;
|
2022-01-04 16:58:31 +01:00
|
|
|
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
2020-09-22 15:11:20 +02:00
|
|
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
2021-09-02 19:11:51 +02:00
|
|
|
import com.minelittlepony.unicopia.item.UItems;
|
2021-02-16 12:39:39 +01:00
|
|
|
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
2021-02-05 20:19:41 +01:00
|
|
|
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
|
|
|
import com.minelittlepony.unicopia.particle.UParticles;
|
2020-04-15 14:22:03 +02:00
|
|
|
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
2021-02-05 20:19:41 +01:00
|
|
|
import com.minelittlepony.unicopia.util.PosHelper;
|
2021-08-25 14:22:11 +02:00
|
|
|
|
|
|
|
import net.minecraft.block.Block;
|
2020-01-16 12:35:46 +01:00
|
|
|
import net.minecraft.block.BlockState;
|
2021-09-02 19:11:51 +02:00
|
|
|
import net.minecraft.block.Material;
|
2021-02-16 12:39:39 +01:00
|
|
|
import net.minecraft.enchantment.EnchantmentHelper;
|
2021-09-18 22:03:06 +02:00
|
|
|
import net.minecraft.entity.Entity;
|
2021-02-16 12:39:39 +01:00
|
|
|
import net.minecraft.entity.LivingEntity;
|
2020-01-16 12:35:46 +01:00
|
|
|
import net.minecraft.entity.attribute.EntityAttributes;
|
|
|
|
import net.minecraft.entity.damage.DamageSource;
|
|
|
|
import net.minecraft.entity.player.PlayerEntity;
|
2021-09-02 19:11:51 +02:00
|
|
|
import net.minecraft.item.ItemStack;
|
|
|
|
import net.minecraft.server.world.ServerWorld;
|
2018-09-12 01:29:49 +02:00
|
|
|
import net.minecraft.util.math.BlockPos;
|
2020-01-16 12:35:46 +01:00
|
|
|
import net.minecraft.util.math.Box;
|
2021-01-27 16:16:15 +01:00
|
|
|
import net.minecraft.util.math.MathHelper;
|
2018-09-12 01:29:49 +02:00
|
|
|
import net.minecraft.world.World;
|
2021-08-25 14:22:11 +02:00
|
|
|
import net.minecraft.world.WorldEvents;
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2020-01-27 17:37:22 +01:00
|
|
|
/**
|
|
|
|
* Earth Pony stomping ability
|
|
|
|
*/
|
2020-10-11 13:14:41 +02:00
|
|
|
public class EarthPonyStompAbility implements Ability<Hit> {
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2019-02-03 10:45:45 +01:00
|
|
|
private final double rad = 4;
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
private final Box areaOfEffect = new Box(
|
2019-02-03 10:45:45 +01:00
|
|
|
-rad, -rad, -rad,
|
|
|
|
rad, rad, rad
|
|
|
|
);
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
@Override
|
2020-04-15 18:12:00 +02:00
|
|
|
public int getWarmupTime(Pony player) {
|
2019-02-07 10:46:59 +01:00
|
|
|
return 3;
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-04-15 18:12:00 +02:00
|
|
|
public int getCooldownTime(Pony player) {
|
2019-02-07 10:46:59 +01:00
|
|
|
return 50;
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-05-10 17:18:45 +02:00
|
|
|
public boolean canUse(Race race) {
|
|
|
|
return race.canUseEarth();
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
2020-10-09 19:05:12 +02:00
|
|
|
@Override
|
|
|
|
public double getCostEstimate(Pony player) {
|
|
|
|
return rad;
|
|
|
|
}
|
|
|
|
|
2020-04-26 19:33:10 +02:00
|
|
|
@Nullable
|
2018-09-12 01:29:49 +02:00
|
|
|
@Override
|
2020-10-11 13:14:41 +02:00
|
|
|
public Hit tryActivate(Pony player) {
|
2021-08-04 15:38:03 +02:00
|
|
|
if (!player.getMaster().isOnGround() && player.getMaster().getVelocity().y * player.getPhysics().getGravitySignum() < 0 && !player.getMaster().getAbilities().flying) {
|
2021-03-01 08:41:55 +01:00
|
|
|
thrustDownwards(player);
|
2020-10-11 13:14:41 +02:00
|
|
|
return Hit.INSTANCE;
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
2020-04-26 19:33:10 +02:00
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-10-11 13:14:41 +02:00
|
|
|
public Hit.Serializer<Hit> getSerializer() {
|
|
|
|
return Hit.SERIALIZER;
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
2021-03-01 08:41:55 +01:00
|
|
|
private void thrustDownwards(Pony player) {
|
|
|
|
BlockPos ppos = player.getOrigin();
|
2022-06-23 16:24:45 +02:00
|
|
|
BlockPos pos = PosHelper.findSolidGroundAt(player.getReferenceWorld(), ppos, player.getPhysics().getGravitySignum());
|
2021-02-18 21:59:32 +01:00
|
|
|
|
2021-03-01 08:41:55 +01:00
|
|
|
double downV = Math.sqrt(ppos.getSquaredDistance(pos)) * player.getPhysics().getGravitySignum();
|
|
|
|
player.getMaster().addVelocity(0, -downV, 0);
|
2021-02-18 21:59:32 +01:00
|
|
|
}
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
@Override
|
2020-10-11 13:14:41 +02:00
|
|
|
public void apply(Pony iplayer, Hit data) {
|
2020-10-08 19:22:20 +02:00
|
|
|
PlayerEntity player = iplayer.getMaster();
|
2018-09-12 22:37:06 +02:00
|
|
|
|
2022-01-04 16:58:31 +01:00
|
|
|
iplayer.setAnimation(Animation.STOMP, 10);
|
|
|
|
|
2021-03-01 08:41:55 +01:00
|
|
|
thrustDownwards(iplayer);
|
2018-09-13 14:04:24 +02:00
|
|
|
|
2021-02-05 20:19:41 +01:00
|
|
|
iplayer.waitForFall(() -> {
|
2021-03-01 08:41:55 +01:00
|
|
|
BlockPos center = PosHelper.findSolidGroundAt(player.getEntityWorld(), player.getBlockPos(), iplayer.getPhysics().getGravitySignum());
|
2018-09-13 14:04:24 +02:00
|
|
|
|
2021-02-16 12:39:39 +01:00
|
|
|
float heavyness = 1 + EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, player);
|
|
|
|
|
2022-06-23 16:24:45 +02:00
|
|
|
iplayer.getReferenceWorld().getOtherEntities(player, areaOfEffect.offset(iplayer.getOriginVector())).forEach(i -> {
|
2021-02-05 20:19:41 +01:00
|
|
|
double dist = Math.sqrt(center.getSquaredDistance(i.getBlockPos()));
|
2018-09-13 14:04:24 +02:00
|
|
|
|
2021-02-05 20:19:41 +01:00
|
|
|
if (dist <= rad + 3) {
|
2021-02-19 17:53:28 +01:00
|
|
|
double inertia = 2 / dist;
|
2021-02-16 12:39:39 +01:00
|
|
|
|
|
|
|
if (i instanceof LivingEntity) {
|
|
|
|
inertia *= 1 + EnchantmentHelper.getEquipmentLevel(UEnchantments.HEAVY, (LivingEntity)i);
|
|
|
|
}
|
|
|
|
inertia /= heavyness;
|
|
|
|
|
2021-03-01 08:41:55 +01:00
|
|
|
double liftAmount = Math.sin(Math.PI * dist / rad) * 12 * iplayer.getPhysics().getGravitySignum();
|
2021-02-18 21:57:55 +01:00
|
|
|
|
2021-02-05 20:19:41 +01:00
|
|
|
i.addVelocity(
|
2021-02-16 12:39:39 +01:00
|
|
|
-(player.getX() - i.getX()) / inertia,
|
2021-02-18 21:57:55 +01:00
|
|
|
-(player.getY() - i.getY() - liftAmount) / inertia + (dist < 1 ? dist : 0),
|
2021-02-16 12:39:39 +01:00
|
|
|
-(player.getZ() - i.getZ()) / inertia);
|
2018-09-13 14:04:24 +02:00
|
|
|
|
2021-03-06 13:27:52 +01:00
|
|
|
DamageSource damage = MagicalDamageSource.create("smash", iplayer);
|
2018-09-13 14:04:24 +02:00
|
|
|
|
2021-02-19 17:53:28 +01:00
|
|
|
double amount = (1.5F * player.getAttributeInstance(EntityAttributes.GENERIC_ATTACK_DAMAGE).getValue() + heavyness * 0.4) / (float)(dist * 1.3F);
|
2018-09-13 14:04:24 +02:00
|
|
|
|
2021-02-05 20:19:41 +01:00
|
|
|
if (i instanceof PlayerEntity) {
|
|
|
|
Race race = Pony.of((PlayerEntity)i).getSpecies();
|
|
|
|
if (race.canUseEarth()) {
|
|
|
|
amount /= 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (race.canFly()) {
|
|
|
|
amount *= 4;
|
|
|
|
}
|
2020-10-11 13:14:41 +02:00
|
|
|
}
|
2018-09-12 22:37:06 +02:00
|
|
|
|
2021-02-16 22:12:09 +01:00
|
|
|
if (i instanceof LivingEntity) {
|
|
|
|
amount /= 1 + (EnchantmentHelper.getEquipmentLevel(UEnchantments.PADDED, (LivingEntity)i) / 6F);
|
|
|
|
}
|
|
|
|
|
2021-02-05 20:19:41 +01:00
|
|
|
i.damage(damage, (float)amount);
|
|
|
|
}
|
|
|
|
});
|
2018-09-12 22:37:06 +02:00
|
|
|
|
2021-02-16 12:39:39 +01:00
|
|
|
double radius = rad + heavyness * 0.3;
|
|
|
|
|
2021-09-18 22:03:06 +02:00
|
|
|
spawnEffectAround(player, center, radius, rad);
|
2019-02-09 20:08:32 +01:00
|
|
|
|
2021-02-05 20:19:41 +01:00
|
|
|
ParticleUtils.spawnParticle(player.world, UParticles.GROUND_POUND, player.getX(), player.getY() - 1, player.getZ(), 0, 0, 0);
|
2020-10-11 13:14:41 +02:00
|
|
|
|
2021-02-05 20:19:41 +01:00
|
|
|
iplayer.subtractEnergyCost(rad);
|
|
|
|
});
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
2021-09-18 22:03:06 +02:00
|
|
|
public static void spawnEffectAround(Entity source, BlockPos center, double radius, double range) {
|
|
|
|
|
|
|
|
BlockPos.iterate(center.add(-radius, -radius, -radius), center.add(radius, radius, radius)).forEach(i -> {
|
2022-03-26 20:34:15 +01:00
|
|
|
double dist = Math.sqrt(i.getSquaredDistance(source.getX(), source.getY(), source.getZ()));
|
2021-09-18 22:03:06 +02:00
|
|
|
|
|
|
|
if (dist <= radius) {
|
|
|
|
spawnEffect(source.world, i, dist, range);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void spawnEffect(World w, BlockPos pos, double dist, double rad) {
|
2020-01-16 12:35:46 +01:00
|
|
|
BlockState state = w.getBlockState(pos);
|
2021-01-26 21:33:45 +01:00
|
|
|
BlockDestructionManager destr = ((BlockDestructionManager.Source)w).getDestructionManager();
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
if (!state.isAir() && w.getBlockState(pos.up()).isAir()) {
|
2021-01-27 16:16:15 +01:00
|
|
|
|
|
|
|
double amount = (1 - dist / rad) * 9;
|
|
|
|
float hardness = state.getHardness(w, pos);
|
|
|
|
float scaledHardness = (1 - hardness / 70);
|
|
|
|
|
|
|
|
int damage = hardness < 0 ? 0 : MathHelper.clamp((int)(amount * scaledHardness), 2, 9);
|
|
|
|
|
|
|
|
if (destr.damageBlock(pos, damage) >= BlockDestructionManager.MAX_DAMAGE) {
|
2021-01-26 21:33:45 +01:00
|
|
|
w.breakBlock(pos, true);
|
2021-09-02 19:11:51 +02:00
|
|
|
|
|
|
|
if (w instanceof ServerWorld) {
|
|
|
|
if (state.getMaterial() == Material.STONE && w.getRandom().nextInt(4) == 0) {
|
|
|
|
ItemStack stack = UItems.PEBBLES.getDefaultStack();
|
|
|
|
stack.setCount(1 + w.getRandom().nextInt(2));
|
|
|
|
Block.dropStack(w, pos, stack);
|
2022-06-25 00:19:55 +02:00
|
|
|
state.onStacksDropped((ServerWorld)w, pos, stack, true);
|
2021-09-02 19:11:51 +02:00
|
|
|
}
|
|
|
|
}
|
2021-01-26 21:33:45 +01:00
|
|
|
} else {
|
2021-08-25 14:22:11 +02:00
|
|
|
w.syncWorldEvent(WorldEvents.BLOCK_BROKEN, pos, Block.getRawIdFromState(state));
|
2021-01-26 21:33:45 +01:00
|
|
|
}
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-05-10 20:45:07 +02:00
|
|
|
public void preApply(Pony player, AbilitySlot slot) {
|
2020-10-01 17:04:48 +02:00
|
|
|
player.getMagicalReserves().getExertion().add(40);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-05-10 20:45:07 +02:00
|
|
|
public void postApply(Pony player, AbilitySlot slot) {
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|