package net.glowstone.io.entity; import net.glowstone.entity.GlowLivingEntity; import net.glowstone.io.nbt.NbtSerialization; import net.glowstone.util.nbt.CompoundTag; import net.glowstone.util.nbt.TagType; import org.bukkit.inventory.EntityEquipment; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import java.util.Arrays; import java.util.LinkedList; import java.util.List; abstract class LivingEntityStore<T extends GlowLivingEntity> extends EntityStore<T> { public LivingEntityStore(Class<T> clazz, String id) { super(clazz, id); } // these tags that apply to living entities only are documented as global: // - short "Air" // - string "CustomName" // - bool "CustomNameVisible" // todo: the following tags // - float "AbsorptionAmount" // - short "HurtTime" // - int "HurtByTimestamp" // - short "DeathTime" // - compound "Attributes" // - bool "PersistenceRequired" // - bool "Leashed" // - compound "Leash" // on ActiveEffects, bool "ShowParticles" @Override public void load(T entity, CompoundTag compound) { super.load(entity, compound); if (compound.isShort("Air")) { entity.setRemainingAir(compound.getShort("Air")); } if (compound.isString("CustomName")) { entity.setCustomName(compound.getString("CustomName")); } if (compound.isByte("CustomNameVisible")) { entity.setCustomNameVisible(compound.getBool("CustomNameVisible")); } if (compound.isFloat("HealF")) { entity.setHealth(compound.getFloat("HealF")); } else if (compound.isShort("Health")) { entity.setHealth(compound.getShort("Health")); } if (compound.isShort("AttackTime")) { entity.setNoDamageTicks(compound.getShort("AttackTime")); } if (compound.isList("ActiveEffects", TagType.COMPOUND)) { for (CompoundTag effect : compound.getCompoundList("ActiveEffects")) { // should really always have every field, but be forgiving if possible if (!effect.isByte("Id") || !effect.isInt("Duration")) { continue; } PotionEffectType type = PotionEffectType.getById(effect.getByte("Id")); int duration = effect.getInt("Duration"); if (type == null || duration < 0) { continue; } int amplifier = 0; boolean ambient = false; if (compound.isByte("Amplifier")) { amplifier = compound.getByte("Amplifier"); } if (compound.isByte("Ambient")) { ambient = compound.getBool("Ambient"); } // bool "ShowParticles" entity.addPotionEffect(new PotionEffect(type, duration, amplifier, ambient), true); } } EntityEquipment equip = entity.getEquipment(); if (compound.isList("Equipment", TagType.COMPOUND)) { List<CompoundTag> list = compound.getCompoundList("Equipment"); if (list.size() == 5) { equip.setItemInHand(NbtSerialization.readItem(list.get(0))); equip.setBoots(NbtSerialization.readItem(list.get(1))); equip.setLeggings(NbtSerialization.readItem(list.get(2))); equip.setChestplate(NbtSerialization.readItem(list.get(3))); equip.setHelmet(NbtSerialization.readItem(list.get(4))); } } if (compound.isList("DropChances", TagType.FLOAT)) { List<Float> list = compound.getList("DropChances", TagType.FLOAT); if (list.size() == 5) { equip.setItemInHandDropChance(list.get(0)); equip.setBootsDropChance(list.get(1)); equip.setLeggingsDropChance(list.get(2)); equip.setChestplateDropChance(list.get(3)); equip.setHelmetDropChance(list.get(4)); } } if (compound.isByte("CanPickUpLoot")) { entity.setCanPickupItems(compound.getBool("CanPickUpLoot")); } } @Override public void save(T entity, CompoundTag tag) { super.save(entity, tag); tag.putShort("Air", entity.getRemainingAir()); if (entity.getCustomName() != null && !entity.getCustomName().isEmpty()) { tag.putString("CustomName", entity.getCustomName()); tag.putBool("CustomNameVisible", entity.isCustomNameVisible()); } tag.putFloat("HealF", entity.getHealth()); tag.putShort("Health", (int) entity.getHealth()); tag.putShort("AttackTime", entity.getNoDamageTicks()); List<CompoundTag> effects = new LinkedList<>(); for (PotionEffect effect : entity.getActivePotionEffects()) { CompoundTag effectTag = new CompoundTag(); effectTag.putByte("Id", effect.getType().getId()); effectTag.putByte("Amplifier", effect.getAmplifier()); effectTag.putInt("Duration", effect.getDuration()); effectTag.putBool("Ambient", effect.isAmbient()); effectTag.putBool("ShowParticles", true); effects.add(effectTag); } tag.putCompoundList("ActiveEffects", effects); EntityEquipment equip = entity.getEquipment(); tag.putCompoundList("Equipment", Arrays.asList( NbtSerialization.writeItem(equip.getItemInHand(), -1), NbtSerialization.writeItem(equip.getBoots(), -1), NbtSerialization.writeItem(equip.getLeggings(), -1), NbtSerialization.writeItem(equip.getChestplate(), -1), NbtSerialization.writeItem(equip.getHelmet(), -1) )); tag.putList("DropChances", TagType.FLOAT, Arrays.asList( equip.getItemInHandDropChance(), equip.getBootsDropChance(), equip.getLeggingsDropChance(), equip.getChestplateDropChance(), equip.getHelmetDropChance() )); tag.putBool("CanPickUpLoot", entity.getCanPickupItems()); } }