/** Copyright (C) <2015> <coolAlias> This file is part of coolAlias' Zelda Sword Skills Minecraft Mod; as such, you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package zeldaswordskills.entity.buff; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.WorldServer; import zeldaswordskills.ZSSMain; import zeldaswordskills.network.PacketDispatcher; import zeldaswordskills.network.client.UpdateBuffPacket; /** * * An actual instance of a Buff, with duration and amplitude * */ public class BuffBase { private final Buff buff; private int duration; private int amplifier; /** * @param buff The type of buff * @param duration Number of ticks; a duration equal to Integer.MAX_VALUE is 'permanent' * @param amplifier How powerful the effect is: see individual {@link Buff buffs} for valid values */ public BuffBase(Buff buff, int duration, int amplifier) { this.buff = buff; this.duration = duration; this.amplifier = amplifier; } public BuffBase(BuffBase b) { this.buff = b.buff; this.duration = b.duration; this.amplifier = b.amplifier; } /** The type of Buff that this effect is */ public Buff getBuff() { return buff; } /** The duration remaining for this buff's effect, in ticks */ public int getDuration() { return duration; } /** Returns the amplitude of this buff's effect */ public int getAmplifier() { return amplifier; } /** Shortcut to get Buff's icon index */ public int getIconIndex() { return buff.iconIndex; } /** Shortcut to Buff method; true if this buff is a negative effect */ public boolean isDebuff() { return buff.isDebuff; } /** Shortcut to Buff method; true if this buff displays an arrow icon overlay */ public boolean displayArrow() { return buff.displayArrow; } /** Whether this buff is applied permanently, used for mobs with permanent resistances */ public boolean isPermanent() { return duration == Integer.MAX_VALUE; } @Override public int hashCode() { return 31 * (31 + buff.ordinal()) + amplifier; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } BuffBase base = (BuffBase) obj; return this.buff == base.buff && this.duration == base.duration && this.amplifier == base.amplifier; } @Override public String toString() { return buff.getName(); // TODO add more information } /** * Combines the new buff's duration and amplifier with the old buff */ public void combine(BuffBase newBuff) { if (newBuff.buff != this.buff) { ZSSMain.logger.warn("Combining two buffs of different types should be impossible!"); } else if (this.isPermanent()) { // can't combine permanent effects } else if (newBuff.amplifier > this.amplifier) { this.amplifier = newBuff.amplifier; this.duration = newBuff.duration; } else if (newBuff.amplifier == this.amplifier && newBuff.duration > this.duration) { this.duration = newBuff.duration; } } /** * Adds any effects the buff may have to the entity when first applied */ public void onAdded(EntityLivingBase entity) { if (!entity.worldObj.isRemote) { buff.onAdded(entity, amplifier); if (entity instanceof EntityPlayerMP) { PacketDispatcher.sendTo(new UpdateBuffPacket(this, false), (EntityPlayerMP) entity); } else if (buff.syncNonPlayerEntity && entity.worldObj instanceof WorldServer) { PacketDispatcher.sendToPlayers(new UpdateBuffPacket(this, entity, false), ((WorldServer) entity.worldObj).getEntityTracker().getTrackingPlayers(entity)); } } } /** * Removes any effects that may have been applied when the buff is removed */ public void onRemoved(EntityLivingBase entity) { onRemoved(entity, true); } /** * Removes any effects that may have been applied when the buff is removed, * updating the client player if needsUpdate is true */ public void onRemoved(EntityLivingBase entity, boolean needsUpdate) { if (!entity.worldObj.isRemote) { buff.onRemoved(entity, amplifier); if (needsUpdate) { if (entity instanceof EntityPlayerMP) { PacketDispatcher.sendTo(new UpdateBuffPacket(this, true), (EntityPlayerMP) entity); } else if (buff.syncNonPlayerEntity && entity.worldObj instanceof WorldServer) { PacketDispatcher.sendToPlayers(new UpdateBuffPacket(this, entity, true), ((WorldServer) entity.worldObj).getEntityTracker().getTrackingPlayers(entity)); } } } } /** * Called when a buff has changed, removing the old effects and applying the new */ public void onChanged(EntityLivingBase entity) { if (!entity.worldObj.isRemote) { onRemoved(entity, false); onAdded(entity); } } /** * Updates this buff's duration and effects, if any * @return true if this buff needs to be removed (duration remaining is zero) */ public boolean onUpdate(EntityLivingBase entity) { buff.onUpdate(entity, duration, amplifier); if (duration > 0 && !isPermanent()) { --duration; } return duration == 0; } /** * Reads and returns a new BuffBase from the tag compound */ public static BuffBase readFromNBT(NBTTagCompound compound) { Buff b = Buff.values()[compound.getByte("buffId")]; byte amp = compound.getByte("amplifier"); int dur = compound.getInteger("duration"); return new BuffBase(b, dur, (int) amp); } /** * Writes this buff effect into the new tag compound, returning it for ease of use */ public NBTTagCompound writeToNBT(NBTTagCompound compound) { compound.setByte("buffId", (byte) buff.ordinal()); compound.setByte("amplifier", (byte) amplifier); compound.setInteger("duration", duration); return compound; } }