2018-09-12 01:29:49 +02:00
|
|
|
package com.minelittlepony.unicopia.player;
|
|
|
|
|
2019-01-10 18:46:40 +01:00
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import javax.annotation.Nonnull;
|
2019-02-01 09:38:45 +01:00
|
|
|
import javax.annotation.Nullable;
|
2019-01-10 18:46:40 +01:00
|
|
|
|
|
|
|
import com.google.common.collect.Lists;
|
2018-09-27 22:12:32 +02:00
|
|
|
import com.minelittlepony.model.anim.BasicEasingInterpolator;
|
|
|
|
import com.minelittlepony.model.anim.IInterpolator;
|
2018-09-12 01:29:49 +02:00
|
|
|
import com.minelittlepony.unicopia.Race;
|
2019-02-01 09:38:45 +01:00
|
|
|
import com.minelittlepony.unicopia.UEffects;
|
2018-09-12 22:37:06 +02:00
|
|
|
import com.minelittlepony.unicopia.Unicopia;
|
2018-09-21 17:53:33 +02:00
|
|
|
import com.minelittlepony.unicopia.network.EffectSync;
|
2018-09-12 22:37:06 +02:00
|
|
|
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
|
2018-09-12 01:29:49 +02:00
|
|
|
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
2019-01-22 17:39:30 +01:00
|
|
|
import com.minelittlepony.unicopia.spell.SpellAffinity;
|
2018-09-12 01:29:49 +02:00
|
|
|
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
|
|
|
|
2018-09-20 16:28:17 +02:00
|
|
|
import net.minecraft.entity.Entity;
|
2018-09-12 01:29:49 +02:00
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
2018-09-20 16:28:17 +02:00
|
|
|
import net.minecraft.entity.player.EntityPlayerMP;
|
2018-09-12 01:29:49 +02:00
|
|
|
import net.minecraft.init.MobEffects;
|
2019-02-01 09:38:45 +01:00
|
|
|
import net.minecraft.item.ItemFood;
|
|
|
|
import net.minecraft.item.ItemStack;
|
2018-09-12 01:29:49 +02:00
|
|
|
import net.minecraft.nbt.NBTTagCompound;
|
2019-01-10 18:46:40 +01:00
|
|
|
import net.minecraft.nbt.NBTTagIntArray;
|
2018-09-12 22:37:06 +02:00
|
|
|
import net.minecraft.network.datasync.DataParameter;
|
|
|
|
import net.minecraft.network.datasync.DataSerializers;
|
|
|
|
import net.minecraft.network.datasync.EntityDataManager;
|
2018-09-20 16:28:17 +02:00
|
|
|
import net.minecraft.network.play.server.SPacketSetPassengers;
|
2018-09-12 01:29:49 +02:00
|
|
|
import net.minecraft.potion.PotionEffect;
|
2018-09-12 22:37:06 +02:00
|
|
|
import net.minecraft.stats.StatList;
|
2019-02-01 09:38:45 +01:00
|
|
|
import net.minecraft.world.EnumDifficulty;
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2019-01-22 17:39:30 +01:00
|
|
|
class PlayerCapabilities implements IPlayer {
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
private static final DataParameter<Integer> PLAYER_RACE = EntityDataManager
|
|
|
|
.createKey(EntityPlayer.class, DataSerializers.VARINT);
|
2018-09-21 17:53:33 +02:00
|
|
|
|
2019-01-22 17:39:30 +01:00
|
|
|
private static final DataParameter<Float> ENERGY = EntityDataManager
|
|
|
|
.createKey(EntityPlayer.class, DataSerializers.FLOAT);
|
2019-01-10 18:46:40 +01:00
|
|
|
|
2018-09-13 14:04:24 +02:00
|
|
|
private static final DataParameter<Float> EXERTION = EntityDataManager
|
|
|
|
.createKey(EntityPlayer.class, DataSerializers.FLOAT);
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
private static final DataParameter<NBTTagCompound> EFFECT = EntityDataManager
|
|
|
|
.createKey(EntityPlayer.class, DataSerializers.COMPOUND_TAG);
|
|
|
|
|
2019-01-10 18:46:40 +01:00
|
|
|
private final List<Integer> pages = Lists.newArrayList();
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
private final PlayerAbilityDelegate powers = new PlayerAbilityDelegate(this);
|
|
|
|
|
|
|
|
private final PlayerGravityDelegate gravity = new PlayerGravityDelegate(this);
|
|
|
|
|
2018-09-19 09:09:30 +02:00
|
|
|
private final PlayerAttributes attributes = new PlayerAttributes();
|
|
|
|
|
2018-09-27 22:12:32 +02:00
|
|
|
private final PlayerView view = new PlayerView(this);
|
|
|
|
|
2019-02-01 09:38:45 +01:00
|
|
|
private final PlayerFood food = new PlayerFood(this);
|
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
private final EffectSync<EntityPlayer> effectDelegate = new EffectSync<>(this, EFFECT);
|
2018-09-16 00:45:44 +02:00
|
|
|
|
2018-09-27 22:12:32 +02:00
|
|
|
private final IInterpolator interpolator = new BasicEasingInterpolator();
|
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
private float nextStepDistance = 1;
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2018-09-12 02:26:35 +02:00
|
|
|
private EntityPlayer entity;
|
|
|
|
|
2019-02-02 12:23:49 +01:00
|
|
|
private boolean dirty = false;
|
|
|
|
|
2019-02-02 17:50:15 +01:00
|
|
|
private boolean invisible = false;
|
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
PlayerCapabilities(EntityPlayer player) {
|
|
|
|
setOwner(player);
|
2018-09-12 02:26:35 +02:00
|
|
|
|
2019-01-29 13:13:06 +01:00
|
|
|
player.getDataManager().register(PLAYER_RACE, Race.EARTH.ordinal());
|
2018-09-13 14:04:24 +02:00
|
|
|
player.getDataManager().register(EXERTION, 0F);
|
2019-01-22 17:39:30 +01:00
|
|
|
player.getDataManager().register(ENERGY, 0F);
|
2018-09-21 17:53:33 +02:00
|
|
|
player.getDataManager().register(EFFECT, new NBTTagCompound());
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Race getPlayerSpecies() {
|
2018-09-12 22:37:06 +02:00
|
|
|
if (getOwner() == null) {
|
|
|
|
return Race.HUMAN;
|
|
|
|
}
|
2018-09-13 12:45:24 +02:00
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
return Race.fromId(getOwner().getDataManager().get(PLAYER_RACE));
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setPlayerSpecies(Race race) {
|
2018-09-21 17:53:33 +02:00
|
|
|
EntityPlayer player = getOwner();
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
if (!PlayerSpeciesList.instance().speciesPermitted(race, player)) {
|
2019-01-29 13:13:06 +01:00
|
|
|
race = Race.EARTH;
|
|
|
|
|
|
|
|
if (!PlayerSpeciesList.instance().speciesPermitted(race, player)) {
|
|
|
|
race = Race.HUMAN;
|
|
|
|
}
|
2018-09-13 12:45:24 +02:00
|
|
|
}
|
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
player.getDataManager().set(PLAYER_RACE, race.ordinal());
|
2018-09-12 22:37:06 +02:00
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
player.capabilities.allowFlying = race.canFly();
|
|
|
|
gravity.updateFlightStat(player, player.capabilities.isFlying);
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
player.sendPlayerAbilities();
|
|
|
|
sendCapabilities(false);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
2018-09-13 14:04:24 +02:00
|
|
|
@Override
|
|
|
|
public float getExertion() {
|
|
|
|
return getOwner().getDataManager().get(EXERTION);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setExertion(float exertion) {
|
|
|
|
getOwner().getDataManager().set(EXERTION, Math.max(0, exertion));
|
|
|
|
}
|
|
|
|
|
2019-01-22 17:39:30 +01:00
|
|
|
@Override
|
|
|
|
public float getEnergy() {
|
|
|
|
return getOwner().getDataManager().get(ENERGY);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setEnergy(float energy) {
|
|
|
|
getOwner().getDataManager().set(ENERGY, Math.max(0, energy));
|
|
|
|
}
|
|
|
|
|
2019-02-02 17:50:15 +01:00
|
|
|
@Override
|
|
|
|
public boolean isInvisible() {
|
|
|
|
return invisible;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setInvisible(boolean invisible) {
|
|
|
|
this.invisible = invisible;
|
|
|
|
}
|
|
|
|
|
2019-01-22 17:39:30 +01:00
|
|
|
@Override
|
|
|
|
public SpellAffinity getAffinity() {
|
|
|
|
return SpellAffinity.NEUTRAL;
|
|
|
|
}
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
@Override
|
2018-09-12 22:37:06 +02:00
|
|
|
public void sendCapabilities(boolean full) {
|
2019-02-02 12:23:49 +01:00
|
|
|
dirty = false;
|
|
|
|
|
|
|
|
if (!getWorld().isRemote) {
|
2018-09-12 22:37:06 +02:00
|
|
|
if (full) {
|
|
|
|
Unicopia.channel.broadcast(new MsgPlayerCapabilities(this));
|
|
|
|
} else {
|
2018-09-21 17:53:33 +02:00
|
|
|
Unicopia.channel.broadcast(new MsgPlayerCapabilities(getPlayerSpecies(), getOwner()));
|
2018-09-12 22:37:06 +02:00
|
|
|
}
|
|
|
|
}
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
2019-02-02 12:23:49 +01:00
|
|
|
@Override
|
|
|
|
public void onDimensionalTravel(int destinationDimension) {
|
|
|
|
if (!getWorld().isRemote) {
|
|
|
|
dirty = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
@Override
|
|
|
|
public IAbilityReceiver getAbilities() {
|
|
|
|
return powers;
|
|
|
|
}
|
|
|
|
|
2018-09-25 00:22:04 +02:00
|
|
|
@Override
|
|
|
|
public IGravity getGravity() {
|
|
|
|
return gravity;
|
|
|
|
}
|
|
|
|
|
2018-09-27 22:12:32 +02:00
|
|
|
@Override
|
|
|
|
public IView getCamera() {
|
|
|
|
return view;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public IInterpolator getInterpolator() {
|
|
|
|
return interpolator;
|
|
|
|
}
|
|
|
|
|
2018-09-20 16:28:17 +02:00
|
|
|
@Override
|
|
|
|
public void beforeUpdate(EntityPlayer entity) {
|
|
|
|
if (entity.world.isRemote) {
|
|
|
|
if (entity.isRiding() && entity.isSneaking()) {
|
|
|
|
|
|
|
|
Entity ridee = entity.getRidingEntity();
|
|
|
|
|
|
|
|
entity.dismountRidingEntity();
|
|
|
|
|
|
|
|
if (ridee instanceof EntityPlayerMP) {
|
|
|
|
((EntityPlayerMP)ridee).getServerWorld().getEntityTracker().sendToTrackingAndSelf(ridee, new SPacketSetPassengers(ridee));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
@Override
|
2018-09-12 02:26:35 +02:00
|
|
|
public void onUpdate(EntityPlayer entity) {
|
|
|
|
powers.onUpdate(entity);
|
|
|
|
gravity.onUpdate(entity);
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
if (hasEffect()) {
|
2019-02-02 17:50:15 +01:00
|
|
|
if (entity.getEntityWorld().isRemote) {
|
|
|
|
getEffect().renderOnPerson(this);
|
|
|
|
}
|
2018-09-12 22:37:06 +02:00
|
|
|
|
2019-02-02 17:50:15 +01:00
|
|
|
if (!getEffect().updateOnPerson(this)) {
|
|
|
|
setEffect(null);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
2018-09-12 22:37:06 +02:00
|
|
|
}
|
2018-09-13 14:04:24 +02:00
|
|
|
|
|
|
|
addExertion(-1);
|
2019-01-22 17:39:30 +01:00
|
|
|
addEnergy(-1);
|
2018-09-16 00:45:44 +02:00
|
|
|
|
2018-09-19 09:09:30 +02:00
|
|
|
attributes.applyAttributes(entity, getPlayerSpecies());
|
2019-02-02 12:23:49 +01:00
|
|
|
|
|
|
|
if (dirty) {
|
|
|
|
sendCapabilities(true);
|
|
|
|
}
|
2018-09-12 22:37:06 +02:00
|
|
|
}
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
@Override
|
|
|
|
public void onFall(float distance, float damageMultiplier) {
|
2019-02-02 12:23:49 +01:00
|
|
|
if (!getWorld().isRemote) {
|
2018-09-12 22:37:06 +02:00
|
|
|
if (getPlayerSpecies().canFly()) {
|
|
|
|
if (entity.fallDistance > 2) {
|
|
|
|
entity.addStat(StatList.FALL_ONE_CM, (int)Math.round(distance * 100));
|
|
|
|
}
|
|
|
|
|
|
|
|
gravity.landHard(entity, distance, damageMultiplier);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-16 00:45:44 +02:00
|
|
|
@Override
|
|
|
|
public boolean stepOnCloud() {
|
|
|
|
EntityPlayer player = getOwner();
|
|
|
|
|
2019-01-31 16:21:14 +01:00
|
|
|
if (player.fallDistance > 1 || player.distanceWalkedOnStepModified > nextStepDistance) {
|
2018-09-16 00:45:44 +02:00
|
|
|
nextStepDistance = player.distanceWalkedOnStepModified + 2;
|
|
|
|
player.fallDistance = 0;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-02-01 09:38:45 +01:00
|
|
|
public IFood getFood() {
|
|
|
|
return food;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-02-01 10:00:56 +01:00
|
|
|
public void onEat(ItemStack stack, @Nullable ItemFood food) {
|
2018-09-12 01:29:49 +02:00
|
|
|
if (getPlayerSpecies() == Race.CHANGELING) {
|
|
|
|
EntityPlayer player = getOwner();
|
|
|
|
|
2019-02-01 09:38:45 +01:00
|
|
|
if (food != null) {
|
|
|
|
int health = food.getHealAmount(stack);
|
|
|
|
float saturation = food.getSaturationModifier(stack);
|
|
|
|
|
|
|
|
player.getFoodStats().addStats(-health/2, -saturation/2);
|
|
|
|
|
|
|
|
player.addPotionEffect(new PotionEffect(MobEffects.NAUSEA, 100, 3, true, true));
|
|
|
|
} else {
|
|
|
|
player.addPotionEffect(new PotionEffect(MobEffects.NAUSEA, 200, 3, true, true));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (player.world.getDifficulty() != EnumDifficulty.PEACEFUL && player.world.rand.nextInt(20) == 0) {
|
2019-02-01 09:53:06 +01:00
|
|
|
player.addPotionEffect(new PotionEffect(UEffects.FOOD_POISONING, 3, 2, true, true));
|
2019-02-01 09:38:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
player.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 2000, 2, true, true));
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void writeToNBT(NBTTagCompound compound) {
|
2018-09-12 22:37:06 +02:00
|
|
|
compound.setString("playerSpecies", getPlayerSpecies().name());
|
2018-09-21 17:53:33 +02:00
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
compound.setTag("powers", powers.toNBT());
|
|
|
|
compound.setTag("gravity", gravity.toNBT());
|
|
|
|
|
2019-01-10 18:46:40 +01:00
|
|
|
if (hasUnlockedPages()) {
|
|
|
|
compound.setTag("pages", new NBTTagIntArray(pages));
|
|
|
|
}
|
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
IMagicEffect effect = getEffect();
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
if (effect != null) {
|
2018-09-21 17:53:33 +02:00
|
|
|
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(effect));
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void readFromNBT(NBTTagCompound compound) {
|
2019-01-29 13:13:06 +01:00
|
|
|
setPlayerSpecies(Race.fromName(compound.getString("playerSpecies")));
|
2018-09-21 17:53:33 +02:00
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
powers.readFromNBT(compound.getCompoundTag("powers"));
|
|
|
|
gravity.readFromNBT(compound.getCompoundTag("gravity"));
|
2018-09-21 17:53:33 +02:00
|
|
|
|
|
|
|
if (compound.hasKey("effect")) {
|
|
|
|
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
|
|
|
|
}
|
2019-01-10 18:46:40 +01:00
|
|
|
|
|
|
|
if (compound.hasKey("pages")) {
|
|
|
|
pages.clear();
|
|
|
|
for (int i : compound.getIntArray("pages")) {
|
|
|
|
pages.add(i);
|
|
|
|
}
|
|
|
|
}
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
@Override
|
|
|
|
public void copyFrom(IPlayer oldPlayer) {
|
2019-02-02 12:23:49 +01:00
|
|
|
pages.addAll(oldPlayer.getUnlockedPages());
|
2018-09-12 22:37:06 +02:00
|
|
|
setEffect(oldPlayer.getEffect());
|
|
|
|
setPlayerSpecies(oldPlayer.getPlayerSpecies());
|
|
|
|
}
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
@Override
|
|
|
|
public void setEffect(IMagicEffect effect) {
|
2018-09-21 17:53:33 +02:00
|
|
|
effectDelegate.set(effect);
|
2018-09-12 22:37:06 +02:00
|
|
|
|
|
|
|
sendCapabilities(true);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public IMagicEffect getEffect() {
|
2018-09-21 17:53:33 +02:00
|
|
|
return effectDelegate.get();
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
2018-09-12 22:37:06 +02:00
|
|
|
@Override
|
|
|
|
public void setOwner(EntityPlayer owner) {
|
|
|
|
entity = owner;
|
|
|
|
}
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
@Override
|
|
|
|
public EntityPlayer getOwner() {
|
2018-09-12 02:26:35 +02:00
|
|
|
return entity;
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
2018-09-26 17:53:12 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getCurrentLevel() {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setCurrentLevel(int level) {
|
|
|
|
}
|
2019-01-10 18:46:40 +01:00
|
|
|
|
|
|
|
@Nonnull
|
|
|
|
public List<Integer> getUnlockedPages() {
|
|
|
|
return pages;
|
|
|
|
}
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|