Unicopia/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java

178 lines
5.8 KiB
Java
Raw Normal View History

package com.minelittlepony.unicopia.ability;
2020-01-16 12:35:46 +01:00
import java.util.List;
2023-08-16 00:18:41 +02:00
import java.util.Optional;
2020-01-16 12:35:46 +01:00
import java.util.stream.Collectors;
2021-08-04 15:38:03 +02:00
import org.jetbrains.annotations.Nullable;
2020-01-16 12:35:46 +01:00
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.ability.data.Hit;
2023-06-02 21:20:30 +02:00
import com.minelittlepony.unicopia.entity.damage.UDamageTypes;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
import com.minelittlepony.unicopia.particle.ParticleUtils;
import com.minelittlepony.unicopia.particle.UParticles;
2022-10-01 18:20:53 +02:00
import com.minelittlepony.unicopia.util.TraceHelper;
import com.minelittlepony.unicopia.util.VecHelper;
2020-01-16 12:35:46 +01:00
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.entity.passive.CowEntity;
2020-12-17 19:17:47 +01:00
import net.minecraft.entity.passive.MerchantEntity;
2020-01-16 12:35:46 +01:00
import net.minecraft.entity.passive.PigEntity;
import net.minecraft.entity.passive.SheepEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.sound.SoundEvents;
2020-01-16 12:35:46 +01:00
/**
* Changeling ability to restore health from mobs
*/
public class ChangelingFeedAbility implements Ability<Hit> {
2020-01-16 12:35:46 +01:00
@Override
2020-04-15 18:12:00 +02:00
public int getWarmupTime(Pony player) {
2020-01-16 12:35:46 +01:00
return 5;
}
@Override
2020-04-15 18:12:00 +02:00
public int getCooldownTime(Pony player) {
2020-01-16 12:35:46 +01:00
return canFeed(player) ? 15 : 80;
}
@Override
public boolean canUse(Race race) {
return race == Race.CHANGELING;
2020-01-16 12:35:46 +01:00
}
@Nullable
@Override
2023-08-16 00:18:41 +02:00
public Optional<Hit> prepare(Pony player) {
return Hit.of(canFeed(player) && !getTargets(player).isEmpty());
2020-01-16 12:35:46 +01:00
}
2020-04-15 18:12:00 +02:00
private boolean canFeed(Pony player) {
return player.asEntity().getHealth() < player.asEntity().getMaxHealth()
|| player.asEntity().canConsume(false);
2020-01-16 12:35:46 +01:00
}
private boolean canDrain(Entity e) {
return (e instanceof LivingEntity)
&& (e instanceof CowEntity
2020-12-17 19:17:47 +01:00
|| e instanceof MerchantEntity
2020-01-16 12:35:46 +01:00
|| e instanceof PlayerEntity
|| e instanceof SheepEntity
|| e instanceof PigEntity
|| e instanceof HostileEntity);
}
@Override
public Hit.Serializer<Hit> getSerializer() {
return Hit.SERIALIZER;
2020-01-16 12:35:46 +01:00
}
2020-04-15 18:12:00 +02:00
protected List<LivingEntity> getTargets(Pony player) {
List<Entity> list = VecHelper.findInRange(player.asEntity(), player.asWorld(), player.getOriginVector(), 3, this::canDrain);
2020-01-16 12:35:46 +01:00
TraceHelper.<LivingEntity>findEntity(player.asEntity(), 17, 1,
2020-09-27 20:07:55 +02:00
looked -> looked instanceof LivingEntity && !list.contains(looked) && canDrain(looked))
.ifPresent(list::add);
2020-01-16 12:35:46 +01:00
return list.stream().map(i -> (LivingEntity)i).collect(Collectors.toList());
}
@Override
public double getCostEstimate(Pony player) {
return 0;
}
2020-01-16 12:35:46 +01:00
@Override
2023-08-16 00:18:41 +02:00
public boolean apply(Pony iplayer, Hit data) {
if (!canFeed(iplayer)) {
2023-08-16 00:18:41 +02:00
return false;
}
PlayerEntity player = iplayer.asEntity();
2020-01-16 12:35:46 +01:00
2020-06-26 11:44:47 +02:00
float maximumHealthGain = player.getMaxHealth() - player.getHealth();
2020-01-16 12:35:46 +01:00
int maximumFoodGain = player.canConsume(false) ? (20 - player.getHungerManager().getFoodLevel()) : 0;
if (maximumHealthGain > 0 || maximumFoodGain > 0) {
float healAmount = 0;
for (LivingEntity i : getTargets(iplayer)) {
2023-06-02 21:20:30 +02:00
healAmount += drainFrom(iplayer, i);
2020-01-16 12:35:46 +01:00
}
int foodAmount = (int)Math.floor(Math.min(healAmount / 3, maximumFoodGain));
if (foodAmount > 0) {
healAmount -= foodAmount;
}
player.getHungerManager().add(Math.max(1, foodAmount), 0.125f);
2020-01-16 12:35:46 +01:00
player.heal(Math.max(1, Math.min(healAmount, maximumHealthGain)));
}
if (!canFeed(iplayer)) {
2023-06-03 13:40:54 +02:00
iplayer.playSound(SoundEvents.ENTITY_PLAYER_BURP, 1, (float)player.getWorld().random.nextTriangular(1F, 0.2F));
} else {
iplayer.playSound(SoundEvents.ENTITY_GENERIC_DRINK, 0.1F, iplayer.getRandomPitch());
2020-01-16 12:35:46 +01:00
}
2023-08-16 00:18:41 +02:00
return true;
2020-01-16 12:35:46 +01:00
}
2023-06-02 21:20:30 +02:00
public float drainFrom(Pony changeling, LivingEntity living) {
2023-06-02 21:20:30 +02:00
DamageSource d = changeling.damageOf(UDamageTypes.LOVE_DRAINING, changeling);
2020-01-16 12:35:46 +01:00
float damage = living.getHealth()/2;
if (damage > 0) {
living.damage(d, damage);
}
2020-04-22 16:28:20 +02:00
ParticleUtils.spawnParticles(UParticles.CHANGELING_MAGIC, living, 7);
2023-06-02 21:20:30 +02:00
ParticleUtils.spawnParticles(new FollowingParticleEffect(UParticles.HEALTH_DRAIN, changeling.asEntity(), 0.2F), living, 1);
2020-01-16 12:35:46 +01:00
2023-06-02 21:20:30 +02:00
if (changeling.asEntity().hasStatusEffect(StatusEffects.NAUSEA)) {
StatusEffectInstance effect = changeling.asEntity().getStatusEffect(StatusEffects.NAUSEA);
changeling.asEntity().removeStatusEffect(StatusEffects.NAUSEA);
living.addStatusEffect(effect);
2023-06-02 21:20:30 +02:00
} else if (changeling.asWorld().random.nextInt(2300) == 0) {
2020-04-22 16:28:20 +02:00
living.addStatusEffect(new StatusEffectInstance(StatusEffects.WITHER, 20, 1));
2020-01-16 12:35:46 +01:00
}
if (living instanceof PlayerEntity) {
damage ++;
damage *= 1.6F;
2023-06-02 21:20:30 +02:00
if (!changeling.asEntity().hasStatusEffect(StatusEffects.HEALTH_BOOST)) {
changeling.asEntity().addStatusEffect(new StatusEffectInstance(StatusEffects.HEALTH_BOOST, 13000, 1));
2020-01-16 12:35:46 +01:00
}
}
return damage;
}
@Override
2023-08-16 00:18:41 +02:00
public void warmUp(Pony player, AbilitySlot slot) {
2020-10-01 17:04:48 +02:00
player.getMagicalReserves().getExertion().add(6);
2020-01-16 12:35:46 +01:00
}
@Override
2023-08-16 00:18:41 +02:00
public void coolDown(Pony player, AbilitySlot slot) {
if (player.asWorld().random.nextInt(10) == 0) {
player.spawnParticles(ParticleTypes.HEART, 1);
}
2020-01-16 12:35:46 +01:00
}
}