2018-09-12 01:29:49 +02:00
|
|
|
package com.minelittlepony.unicopia.player;
|
|
|
|
|
2019-02-01 09:00:43 +01:00
|
|
|
import com.minelittlepony.unicopia.Race;
|
2018-09-25 00:22:04 +02:00
|
|
|
import com.minelittlepony.unicopia.USounds;
|
2018-09-26 00:03:14 +02:00
|
|
|
import com.minelittlepony.unicopia.mixin.MixinEntity;
|
2019-01-22 17:39:30 +01:00
|
|
|
import com.minelittlepony.unicopia.util.serialisation.InbtSerialisable;
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
import net.minecraft.block.Block;
|
|
|
|
import net.minecraft.block.SoundType;
|
|
|
|
import net.minecraft.block.material.Material;
|
|
|
|
import net.minecraft.block.state.IBlockState;
|
2018-09-25 23:30:21 +02:00
|
|
|
import net.minecraft.entity.Entity;
|
2018-09-12 01:29:49 +02:00
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
2018-09-12 22:37:06 +02:00
|
|
|
import net.minecraft.init.MobEffects;
|
|
|
|
import net.minecraft.init.SoundEvents;
|
2018-09-12 01:29:49 +02:00
|
|
|
import net.minecraft.nbt.NBTTagCompound;
|
2018-09-12 22:37:06 +02:00
|
|
|
import net.minecraft.potion.PotionEffect;
|
|
|
|
import net.minecraft.util.DamageSource;
|
|
|
|
import net.minecraft.util.SoundEvent;
|
|
|
|
import net.minecraft.util.math.BlockPos;
|
|
|
|
import net.minecraft.util.math.MathHelper;
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2018-09-25 00:22:04 +02:00
|
|
|
class PlayerGravityDelegate implements IUpdatable<EntityPlayer>, IGravity, InbtSerialisable {
|
2018-09-12 01:29:49 +02:00
|
|
|
|
|
|
|
private final IPlayer player;
|
|
|
|
|
2018-09-24 21:38:21 +02:00
|
|
|
private static final float MAXIMUM_FLIGHT_EXPERIENCE = 500;
|
2018-09-12 22:37:06 +02:00
|
|
|
|
2018-09-25 00:22:04 +02:00
|
|
|
public int ticksInAir = 0;
|
|
|
|
public float flightExperience = 0;
|
2018-09-12 01:29:49 +02:00
|
|
|
|
|
|
|
public boolean isFlying = false;
|
|
|
|
|
|
|
|
public PlayerGravityDelegate(IPlayer player) {
|
|
|
|
this.player = player;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onUpdate(EntityPlayer entity) {
|
2018-09-26 00:03:14 +02:00
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
entity.capabilities.allowFlying = entity.capabilities.isCreativeMode || player.getPlayerSpecies().canFly();
|
2018-09-24 21:38:21 +02:00
|
|
|
|
|
|
|
if (!entity.capabilities.isCreativeMode) {
|
|
|
|
entity.capabilities.isFlying |= entity.capabilities.allowFlying && isFlying && !entity.onGround;
|
|
|
|
}
|
|
|
|
|
2018-09-25 23:30:41 +02:00
|
|
|
isFlying = entity.capabilities.isFlying && !entity.capabilities.isCreativeMode;
|
2018-09-12 22:37:06 +02:00
|
|
|
|
2018-09-26 00:13:30 +02:00
|
|
|
boolean rainboom = Math.sqrt(getHorizontalMotion(entity)) > 0.4F;
|
|
|
|
|
|
|
|
if (isFlying && rainboom) {
|
2018-09-27 22:12:32 +02:00
|
|
|
MixinEntity.setSize(entity, entity.width, player.getInterpolator().interpolate("standingHeight", 0.5F, 10));
|
|
|
|
entity.eyeHeight = player.getInterpolator().interpolate("eyeHeight", entity.height / 2, 10);
|
2018-09-26 00:03:14 +02:00
|
|
|
} else {
|
2018-09-27 22:12:32 +02:00
|
|
|
MixinEntity.setSize(entity, entity.width, player.getInterpolator().interpolate("standingHeight", entity.height, 10));
|
|
|
|
entity.eyeHeight = player.getInterpolator().interpolate("eyeHeight", entity.getDefaultEyeHeight(), 10);
|
2018-09-26 00:03:14 +02:00
|
|
|
}
|
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
if (!entity.capabilities.isCreativeMode && !entity.isElytraFlying()) {
|
2018-09-24 21:38:21 +02:00
|
|
|
if (isFlying && !entity.isRiding()) {
|
2018-09-12 22:37:06 +02:00
|
|
|
|
|
|
|
entity.fallDistance = 0;
|
|
|
|
|
2019-02-01 09:00:43 +01:00
|
|
|
if (player.getPlayerSpecies() != Race.CHANGELING && entity.world.rand.nextInt(100) == 0) {
|
|
|
|
float exhaustion = (0.3F * ticksInAir) / 70;
|
|
|
|
if (entity.isSprinting()) {
|
|
|
|
exhaustion *= 3.11F;
|
|
|
|
}
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2019-02-01 09:00:43 +01:00
|
|
|
exhaustion *= (1 - flightExperience/MAXIMUM_FLIGHT_EXPERIENCE);
|
2018-09-26 20:53:50 +02:00
|
|
|
|
2019-02-01 09:00:43 +01:00
|
|
|
entity.addExhaustion(exhaustion);
|
|
|
|
}
|
2018-09-12 22:37:06 +02:00
|
|
|
|
2019-02-01 09:00:43 +01:00
|
|
|
if (ticksInAir++ >= MAXIMUM_FLIGHT_EXPERIENCE) {
|
2018-09-25 00:22:04 +02:00
|
|
|
ticksInAir = 0;
|
2018-09-12 22:37:06 +02:00
|
|
|
addFlightExperience(entity);
|
2018-09-24 21:38:21 +02:00
|
|
|
entity.playSound(SoundEvents.ENTITY_GUARDIAN_FLOP, 1, 1);
|
2018-09-12 22:37:06 +02:00
|
|
|
}
|
2018-09-24 21:38:21 +02:00
|
|
|
|
|
|
|
float forward = 0.00015F * flightExperience;
|
|
|
|
|
|
|
|
entity.motionX += - forward * MathHelper.sin(entity.rotationYaw * 0.017453292F);
|
2018-09-25 23:30:21 +02:00
|
|
|
entity.motionY -= 0.05F - getHorizontalMotion(entity) / 100;
|
2018-09-24 21:38:21 +02:00
|
|
|
entity.motionZ += forward * MathHelper.cos(entity.rotationYaw * 0.017453292F);
|
2018-09-25 00:22:04 +02:00
|
|
|
|
|
|
|
if (ticksInAir > 0 && ticksInAir % 12 == 0) {
|
2019-01-30 21:17:46 +01:00
|
|
|
entity.playSound(USounds.WING_FLAP, 0.5F, 1);
|
2018-09-25 00:22:04 +02:00
|
|
|
}
|
2018-09-12 22:37:06 +02:00
|
|
|
} else {
|
2018-09-25 00:22:04 +02:00
|
|
|
if (ticksInAir != 0) {
|
2019-01-30 21:17:46 +01:00
|
|
|
entity.playSound(USounds.WING_FLAP, 0.4F, 1);
|
2018-09-25 00:22:04 +02:00
|
|
|
}
|
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
ticksInAir = 0;
|
2018-09-25 00:22:04 +02:00
|
|
|
flightExperience *= 0.9991342;
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|
2018-09-12 22:37:06 +02:00
|
|
|
}
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
public void landHard(EntityPlayer player, float distance, float damageMultiplier) {
|
|
|
|
if (distance <= 0) {
|
|
|
|
return;
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
2018-09-12 22:37:06 +02:00
|
|
|
|
|
|
|
PotionEffect potioneffect = player.getActivePotionEffect(MobEffects.JUMP_BOOST);
|
|
|
|
float potion = potioneffect != null ? potioneffect.getAmplifier() + 1 : 0;
|
|
|
|
int i = MathHelper.ceil((distance - 8.0F - potion) * damageMultiplier);
|
|
|
|
|
|
|
|
if (i > 0) {
|
|
|
|
int j = MathHelper.floor(player.posX);
|
|
|
|
int k = MathHelper.floor(player.posY - 0.20000000298023224D);
|
|
|
|
int l = MathHelper.floor(player.posZ);
|
|
|
|
|
|
|
|
BlockPos pos = new BlockPos(j, k, l);
|
|
|
|
|
|
|
|
IBlockState state = player.world.getBlockState(pos);
|
|
|
|
Block block = state.getBlock();
|
|
|
|
|
|
|
|
if (state.getMaterial() != Material.AIR) {
|
|
|
|
|
|
|
|
player.playSound(getFallSound(i), 1, 1);
|
|
|
|
player.attackEntityFrom(DamageSource.FALL, i);
|
|
|
|
|
|
|
|
SoundType soundtype = block.getSoundType(state, player.getEntityWorld(), pos, player);
|
|
|
|
|
|
|
|
player.playSound(soundtype.getStepSound(), soundtype.getVolume() * 0.5f, soundtype.getPitch() * 0.75f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-25 23:30:21 +02:00
|
|
|
protected double getHorizontalMotion(Entity e) {
|
|
|
|
return (e.motionX * e.motionX)
|
|
|
|
+ (e.motionZ * e.motionZ);
|
|
|
|
}
|
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
protected SoundEvent getFallSound(int distance) {
|
|
|
|
return distance > 4 ? SoundEvents.ENTITY_PLAYER_BIG_FALL : SoundEvents.ENTITY_PLAYER_SMALL_FALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void addFlightExperience(EntityPlayer entity) {
|
|
|
|
entity.addExperience(1);
|
|
|
|
|
2018-09-24 21:38:21 +02:00
|
|
|
flightExperience += (MAXIMUM_FLIGHT_EXPERIENCE - flightExperience) / 20;
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void updateFlightStat(EntityPlayer entity, boolean flying) {
|
|
|
|
if (!entity.capabilities.isCreativeMode) {
|
|
|
|
entity.capabilities.allowFlying = player.getPlayerSpecies().canFly();
|
|
|
|
|
|
|
|
if (entity.capabilities.allowFlying) {
|
|
|
|
entity.capabilities.isFlying |= flying;
|
|
|
|
|
|
|
|
isFlying = entity.capabilities.isFlying;
|
|
|
|
|
|
|
|
if (isFlying) {
|
2018-09-12 22:37:06 +02:00
|
|
|
ticksInAir = 0;
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
entity.capabilities.isFlying = false;
|
|
|
|
isFlying = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void writeToNBT(NBTTagCompound compound) {
|
2018-09-12 22:37:06 +02:00
|
|
|
compound.setInteger("flightDuration", ticksInAir);
|
|
|
|
compound.setFloat("flightExperience", flightExperience);
|
2018-09-12 01:29:49 +02:00
|
|
|
compound.setBoolean("isFlying", isFlying);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void readFromNBT(NBTTagCompound compound) {
|
2018-09-12 22:37:06 +02:00
|
|
|
ticksInAir = compound.getInteger("flightDuration");
|
|
|
|
flightExperience = compound.getFloat("flightExperience");
|
2018-09-12 01:29:49 +02:00
|
|
|
isFlying = compound.getBoolean("isFlying");
|
|
|
|
}
|
2018-09-25 00:22:04 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isFlying() {
|
|
|
|
return isFlying;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public float getFlightExperience() {
|
|
|
|
return flightExperience / MAXIMUM_FLIGHT_EXPERIENCE;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public float getFlightDuration() {
|
|
|
|
return ticksInAir / MAXIMUM_FLIGHT_EXPERIENCE;
|
|
|
|
}
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|