Rewrite the changeling feed ability

This commit is contained in:
Sollace 2019-02-07 15:47:53 +02:00
parent 87cf0e7342
commit 58f72a783b

View file

@ -1,18 +1,21 @@
package com.minelittlepony.unicopia.power; package com.minelittlepony.unicopia.power;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.UParticles;
import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.power.data.Hit; import com.minelittlepony.unicopia.power.data.Hit;
import com.minelittlepony.util.MagicalDamageSource; import com.minelittlepony.util.MagicalDamageSource;
import com.minelittlepony.util.vector.VecHelper; import com.minelittlepony.util.vector.VecHelper;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.passive.EntityCow; import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.passive.EntityPig; import net.minecraft.entity.passive.EntityPig;
@ -55,8 +58,7 @@ public class PowerFeed implements IPower<Hit> {
@Override @Override
public Hit tryActivate(IPlayer player) { public Hit tryActivate(IPlayer player) {
if (player.getOwner().getHealth() < player.getOwner().getMaxHealth() || player.getOwner().canEat(false)) { if (player.getOwner().getHealth() < player.getOwner().getMaxHealth() || player.getOwner().canEat(false)) {
Entity i = VecHelper.getLookedAtEntity(player.getOwner(), 15); if (!getTargets(player).isEmpty()) {
if (i != null && canDrain(i)) {
return new Hit(); return new Hit();
} }
} }
@ -65,12 +67,13 @@ public class PowerFeed implements IPower<Hit> {
} }
private boolean canDrain(Entity e) { private boolean canDrain(Entity e) {
return e instanceof EntityCow return (e instanceof EntityLiving)
&& (e instanceof EntityCow
|| e instanceof EntityVillager || e instanceof EntityVillager
|| e instanceof EntityPlayer || e instanceof EntityPlayer
|| e instanceof EntitySheep || e instanceof EntitySheep
|| e instanceof EntityPig || e instanceof EntityPig
|| EnumCreatureType.MONSTER.getCreatureClass().isAssignableFrom(e.getClass()); || EnumCreatureType.MONSTER.getCreatureClass().isAssignableFrom(e.getClass()));
} }
@Override @Override
@ -78,47 +81,65 @@ public class PowerFeed implements IPower<Hit> {
return Hit.class; return Hit.class;
} }
@Override protected List<EntityLiving> getTargets(IPlayer player) {
public void apply(IPlayer iplayer, Hit data) { List<Entity> list = VecHelper.getWithinRange(player.getOwner(), 3, this::canDrain);
EntityPlayer player = iplayer.getOwner();
List<Entity> list = VecHelper.getWithinRange(player, 3, this::canDrain);
Entity looked = VecHelper.getLookedAtEntity(player, 17); Entity looked = VecHelper.getLookedAtEntity(player.getOwner(), 17);
if (looked != null && !list.contains(looked)) { if (looked != null && !list.contains(looked) && canDrain(looked)) {
list.add(looked); list.add(looked);
} }
float lostHealth = player.getMaxHealth() - player.getHealth(); return list.stream().map(i -> (EntityLiving)i).collect(Collectors.toList());
}
if (lostHealth > 0 || player.canEat(false)) { @Override
float totalDrained = (lostHealth < 2 ? lostHealth : 2); public void apply(IPlayer iplayer, Hit data) {
float drained = totalDrained / list.size(); EntityPlayer player = iplayer.getOwner();
for (Entity i : list) { float maximumHealthGain = player.getMaxHealth() - player.getHealth();
DamageSource d = MagicalDamageSource.causePlayerDamage("feed", player); int maximumFoodGain = player.canEat(false) ? (20 - player.getFoodStats().getFoodLevel()) : 0;
if (iplayer.getWorld().rand.nextFloat() > 0.95f) { if (maximumHealthGain > 0 || maximumFoodGain > 0) {
i.attackEntityFrom(d, Integer.MAX_VALUE);
} else { float healAmount = 0;
i.attackEntityFrom(d, drained);
} for (Entity i : getTargets(iplayer)) {
healAmount += drainFrom(player, (EntityLiving)i);
} }
if (lostHealth > 0) { int foodAmount = (int)Math.floor(Math.min(healAmount / 3, maximumFoodGain));
player.getFoodStats().addStats(3, 0.125f);
player.heal(totalDrained); if (foodAmount > 0) {
} else { healAmount -= foodAmount;
player.getFoodStats().addStats(3, 0.25f); player.getFoodStats().addStats(foodAmount, 0.125f);
} }
if (iplayer.getWorld().rand.nextFloat() > 0.9f) { if (healAmount > 0) {
player.addPotionEffect(new PotionEffect(MobEffects.WITHER, 20, 1)); player.heal(Math.min(healAmount, maximumHealthGain));
} }
player.removePotionEffect(MobEffects.NAUSEA);
} }
} }
protected float drainFrom(EntityPlayer changeling, EntityLiving living) {
DamageSource d = MagicalDamageSource.causePlayerDamage("feed", changeling);
float damage = living.getHealth()/2;
if (damage > 0) {
living.attackEntityFrom(d, damage);
}
IPower.spawnParticles(UParticles.CHANGELING_MAGIC, living, 7);
if (changeling.isPotionActive(MobEffects.NAUSEA)) {
living.addPotionEffect(changeling.removeActivePotionEffect(MobEffects.NAUSEA));
} else if (changeling.getEntityWorld().rand.nextInt(2300) == 0) {
living.addPotionEffect(new PotionEffect(MobEffects.WITHER, 20, 1));
}
return damage;
}
@Override @Override
public void preApply(IPlayer player) { public void preApply(IPlayer player) {
player.addExertion(6); player.addExertion(6);
@ -128,7 +149,7 @@ public class PowerFeed implements IPower<Hit> {
public void postApply(IPlayer player) { public void postApply(IPlayer player) {
EntityPlayer entity = player.getOwner(); EntityPlayer entity = player.getOwner();
IPower.spawnParticles(EnumParticleTypes.HEART.getParticleID(), entity, 10); IPower.spawnParticles(EnumParticleTypes.HEART.getParticleID(), entity, 1);
} }
} }