2020-04-15 14:22:03 +02:00
|
|
|
package com.minelittlepony.unicopia.ability;
|
2020-01-16 12:35:46 +01:00
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
|
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;
|
2020-09-22 15:11:20 +02:00
|
|
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
|
|
|
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;
|
2020-09-27 20:07:55 +02:00
|
|
|
import com.minelittlepony.unicopia.util.RayTraceHelper;
|
2020-04-15 14:22:03 +02:00
|
|
|
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;
|
|
|
|
|
2020-01-27 17:37:22 +01:00
|
|
|
/**
|
|
|
|
* Changeling ability to restore health from mobs
|
|
|
|
*/
|
2020-04-25 15:37:17 +02:00
|
|
|
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
|
2020-05-10 17:18:45 +02:00
|
|
|
public boolean canUse(Race race) {
|
|
|
|
return race == Race.CHANGELING;
|
2020-01-16 12:35:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
@Override
|
2020-04-15 18:12:00 +02:00
|
|
|
public Hit tryActivate(Pony player) {
|
2020-01-16 12:35:46 +01:00
|
|
|
if (canFeed(player)) {
|
|
|
|
if (!getTargets(player).isEmpty()) {
|
2020-04-25 15:37:17 +02:00
|
|
|
return Hit.INSTANCE;
|
2020-01-16 12:35:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-04-15 18:12:00 +02:00
|
|
|
private boolean canFeed(Pony player) {
|
2020-10-08 19:22:20 +02:00
|
|
|
return player.getMaster().getHealth() < player.getMaster().getMaxHealth() || player.getMaster().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
|
2020-04-25 15:37:17 +02:00
|
|
|
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) {
|
2020-10-08 19:22:20 +02:00
|
|
|
List<Entity> list = VecHelper.findInReach(player.getMaster(), 3, this::canDrain);
|
2020-01-16 12:35:46 +01:00
|
|
|
|
2020-10-08 19:22:20 +02:00
|
|
|
RayTraceHelper.<LivingEntity>findEntity(player.getMaster(), 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());
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:05:12 +02:00
|
|
|
@Override
|
|
|
|
public double getCostEstimate(Pony player) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-01-16 12:35:46 +01:00
|
|
|
@Override
|
2020-04-15 18:12:00 +02:00
|
|
|
public void apply(Pony iplayer, Hit data) {
|
2020-10-08 19:22:20 +02:00
|
|
|
PlayerEntity player = iplayer.getMaster();
|
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)) {
|
|
|
|
healAmount += drainFrom(player, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
int foodAmount = (int)Math.floor(Math.min(healAmount / 3, maximumFoodGain));
|
|
|
|
|
|
|
|
if (foodAmount > 0) {
|
|
|
|
healAmount -= foodAmount;
|
|
|
|
player.getHungerManager().add(foodAmount, 0.125f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (healAmount > 0) {
|
|
|
|
player.heal(Math.min(healAmount, maximumHealthGain));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public float drainFrom(PlayerEntity changeling, LivingEntity living) {
|
2020-09-22 15:11:20 +02:00
|
|
|
DamageSource d = MagicalDamageSource.create("feed", 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);
|
2020-01-16 12:35:46 +01:00
|
|
|
|
|
|
|
if (changeling.hasStatusEffect(StatusEffects.NAUSEA)) {
|
2020-05-05 18:48:47 +02:00
|
|
|
StatusEffectInstance effect = changeling.getStatusEffect(StatusEffects.NAUSEA);
|
|
|
|
changeling.removeStatusEffect(StatusEffects.NAUSEA);
|
|
|
|
living.addStatusEffect(effect);
|
2020-01-16 12:35:46 +01:00
|
|
|
} else if (changeling.getEntityWorld().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;
|
|
|
|
|
|
|
|
if (!changeling.hasStatusEffect(StatusEffects.HEALTH_BOOST)) {
|
2020-04-22 16:28:20 +02:00
|
|
|
changeling.addStatusEffect(new StatusEffectInstance(StatusEffects.HEALTH_BOOST, 13000, 1));
|
2020-01-16 12:35:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return damage;
|
|
|
|
}
|
|
|
|
|
|
|
|
@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(6);
|
2020-01-16 12:35:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-05-10 20:45:07 +02:00
|
|
|
public void postApply(Pony player, AbilitySlot slot) {
|
2021-01-27 16:16:31 +01:00
|
|
|
if (player.getWorld().random.nextInt(10) == 0) {
|
|
|
|
player.spawnParticles(ParticleTypes.HEART, 1);
|
|
|
|
}
|
2020-01-16 12:35:46 +01:00
|
|
|
}
|
|
|
|
}
|