package net.techcable.sonarpet.nms.entity.type; import java.lang.invoke.MethodHandle; import javax.annotation.Nullable; import com.dsh105.echopet.compat.api.entity.HorseArmour; import com.dsh105.echopet.compat.api.entity.HorseMarking; import com.dsh105.echopet.compat.api.entity.HorseType; import com.dsh105.echopet.compat.api.entity.HorseVariant; import com.dsh105.echopet.compat.api.entity.IPet; import com.dsh105.echopet.compat.api.entity.SizeCategory; import com.dsh105.echopet.compat.api.entity.type.nms.IEntityHorsePet; import net.techcable.sonarpet.EntityHook; import net.techcable.sonarpet.EntityHookType; import net.techcable.sonarpet.SafeSound; import net.techcable.sonarpet.nms.BlockSoundData; import net.techcable.sonarpet.nms.INMS; import net.techcable.sonarpet.nms.NMSEntity; import net.techcable.sonarpet.nms.NMSEntityHorse; import net.techcable.sonarpet.nms.NMSInsentientEntity; import net.techcable.sonarpet.nms.entity.EntityAgeablePet; import net.techcable.sonarpet.utils.NmsVersion; import net.techcable.sonarpet.utils.Versioning; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.ChestedHorse; import org.bukkit.entity.Entity; import org.bukkit.entity.Tameable; import org.bukkit.inventory.HorseInventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; @EntityHook({ EntityHookType.HORSE, EntityHookType.MULE, EntityHookType.DONKEY, EntityHookType.ZOMBIE_HORSE, EntityHookType.SKELETON_HORSE, EntityHookType.LLAMA }) public class EntityHorsePet extends EntityAgeablePet implements IEntityHorsePet { protected EntityHorsePet(IPet pet, NMSInsentientEntity entity, EntityHookType hookType) { super(pet, entity, hookType); } private int rearingCounter = 0; int stepSoundCount = 0; @Override public void initiateEntityPet() { super.initiateEntityPet(); ((Tameable) getBukkitEntity()).setOwner(Bukkit.getOfflinePlayer(getPet().getOwnerUUID())); } @Override public void setSaddled(boolean flag) { getEntity().setSaddled(flag); } public HorseType getHorseType() { return getEntity().getHorseType(); } @Override public void setVariant(HorseVariant v, HorseMarking m) { getEntity().setColor(v.getBukkitColour()); getEntity().setStyle(m.getBukkitStyle()); } @Override public void setArmour(HorseArmour a) { ((HorseInventory) ((InventoryHolder) getBukkitEntity()).getInventory()) .setArmor(a.getMaterial() == null ? null : new ItemStack(a.getMaterial(), 1)); } @Override public void setChested(boolean flag) { if (Versioning.NMS_VERSION.compareTo(NmsVersion.v1_11_R1) >= 0) { if (!(getBukkitEntity() instanceof ChestedHorse)) { /* * To fail silently, or to throw an exception; that is the question. * Whether is nobler to be confusing and get a bug report, * or be annoying and get a bug report? */ return; } } getEntity().setCarryingChest(flag); } private void setRearing(boolean b) { getEntity().setRearing(b); } @Override public boolean attack(Entity entity) { boolean flag = super.attack(entity); if (flag) { this.setRearing(true); switch (getHorseType()) { case DONKEY: getEntity().playSound(SafeSound.DONKEY_ANGRY, 1, 1); break; default: getEntity().playSound(SafeSound.HORSE_ANGRY, 1, 1); break; } } return flag; } @Override public void makeStepSound(int i, int j, int k, Material block) { BlockSoundData soundData = INMS.getInstance().getBlockSoundData(block); if (getBukkitEntity().getWorld().getBlockAt(i, j + 1, k).getType() == Material.SNOW) { soundData = INMS.getInstance().getBlockSoundData(Material.SNOW); } if (!INMS.getInstance().isLiquid(block)) { if (!getEntity().getPassengers().isEmpty() && getHorseType() != HorseType.NORMAL && getHorseType() != HorseType.MULE) { ++this.stepSoundCount; if (this.stepSoundCount > 5 && this.stepSoundCount % 3 == 0) { getEntity().playSound(SafeSound.HORSE_GALLOP, soundData.getVolume() * 0.15F, soundData.getPitch()); if (getHorseType() == HorseType.NORMAL && this.random() .nextInt(10) == 0) { getEntity().playSound(SafeSound.HORSE_BREATHE, soundData.getVolume() * 0.6F, soundData.getPitch()); } } else if (this.stepSoundCount <= 5) { getEntity().playSound(SafeSound.HORSE_STEP_WOOD, soundData.getVolume() * 0.15F, soundData.getPitch()); } } else if (soundData.equals(BlockSoundData.WOOD)) { getEntity().playSound(SafeSound.HORSE_STEP_WOOD, soundData.getVolume() * 0.15F, soundData.getPitch()); } else { getEntity().playSound(SafeSound.HORSE_STEP, soundData.getVolume() * 0.15F, soundData.getPitch()); } } } @Override public void move(float sideMot, float forwMot, @Nullable Float upwardsMotion, MethodHandle superMoveFunction) { super.move(sideMot, forwMot, upwardsMotion, superMoveFunction); if (forwMot <= 0.0F) { this.stepSoundCount = 0; } } private boolean previouslySaddled; @Override public void onMounted(NMSEntity passenger) { super.onMounted(passenger); if (passenger.equals(getPlayerEntity())) { // When the owner starts to ride, give them a saddle previouslySaddled = getEntity().isSaddled(); setSaddled(true); } } @Override public void onDismounted(NMSEntity passenger) { super.onDismounted(passenger); if (passenger.equals(getPlayerEntity())) { // Reset to our previous saddle-state once the owner dismounts setSaddled(previouslySaddled); } } @Override public SizeCategory getSizeCategory() { if (this.isBaby()) { return SizeCategory.TINY; } else { return SizeCategory.LARGE; } } @Override public void onLive() { super.onLive(); if (rearingCounter > 0 && ++rearingCounter > 20) { setRearing(false); } } @Override public void doJumpAnimation() { getEntity().playSound(SafeSound.HORSE_JUMP, 0.4F, 1.0F); this.rearingCounter = 1; setRearing(true); } @Override public NMSEntityHorse getEntity() { return (NMSEntityHorse) super.getEntity(); } }