/*
* This program is free software: 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 lineage2.gameserver.model.instances;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.concurrent.Future;
import lineage2.commons.dao.JdbcEntityState;
import lineage2.commons.dbutils.DbUtils;
import lineage2.commons.threading.RunnableImpl;
import lineage2.gameserver.Config;
import lineage2.gameserver.ThreadPoolManager;
import lineage2.gameserver.cache.Msg;
import lineage2.gameserver.database.DatabaseFactory;
import lineage2.gameserver.idfactory.IdFactory;
import lineage2.gameserver.model.Creature;
import lineage2.gameserver.model.GameObject;
import lineage2.gameserver.model.Party;
import lineage2.gameserver.model.PetData;
import lineage2.gameserver.model.Player;
import lineage2.gameserver.model.Skill;
import lineage2.gameserver.model.Summon;
import lineage2.gameserver.model.base.BaseStats;
import lineage2.gameserver.model.base.Experience;
import lineage2.gameserver.model.items.ItemInstance;
import lineage2.gameserver.model.items.PetInventory;
import lineage2.gameserver.model.items.attachment.FlagItemAttachment;
import lineage2.gameserver.network.serverpackets.InventoryUpdate;
import lineage2.gameserver.network.serverpackets.SocialAction;
import lineage2.gameserver.network.serverpackets.SystemMessage;
import lineage2.gameserver.network.serverpackets.components.CustomMessage;
import lineage2.gameserver.network.serverpackets.components.SystemMsg;
import lineage2.gameserver.stats.Stats;
import lineage2.gameserver.tables.PetDataTable;
import lineage2.gameserver.templates.item.WeaponTemplate;
import lineage2.gameserver.templates.npc.NpcTemplate;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Mobius
* @version $Revision: 1.0 $
*/
public class PetInstance extends Summon
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Field _log.
*/
private static final Logger _log = LoggerFactory.getLogger(PetInstance.class);
/**
* Field DELUXE_FOOD_FOR_STRIDER. (value is 5169)
*/
private static final int DELUXE_FOOD_FOR_STRIDER = 5169;
/**
* @author Mobius
*/
class FeedTask extends RunnableImpl
{
/**
* Method runImpl.
*/
@Override
public void runImpl()
{
Player owner = getPlayer();
while ((getCurrentFed() <= (0.55 * getMaxFed())) && tryFeed())
{
}
if (PetDataTable.isVitaminPet(getNpcId()) && (getCurrentFed() <= 0))
{
deleteMe();
}
else if (getCurrentFed() <= (0.10 * getMaxFed()))
{
owner.sendMessage(new CustomMessage("lineage2.gameserver.model.instances.L2PetInstance.UnSummonHungryPet", owner));
unSummon();
return;
}
setCurrentFed(getCurrentFed() - 5);
sendStatusUpdate();
startFeed(isInCombat());
}
}
/**
* Field _controlItemObjId.
*/
private final int _controlItemObjId;
/**
* Field _curFed.
*/
private int _curFed;
/**
* Field _data.
*/
protected PetData _data;
/**
* Field _feedTask.
*/
private Future<?> _feedTask;
/**
* Field _inventory.
*/
protected PetInventory _inventory;
/**
* Field _level.
*/
private int _level;
/**
* Field _respawned.
*/
private boolean _respawned;
/**
* Field lostExp.
*/
private int lostExp;
/**
* Method restore.
* @param control ItemInstance
* @param template NpcTemplate
* @param owner Player
* @return PetInstance
*/
public static final PetInstance restore(ItemInstance control, NpcTemplate template, Player owner)
{
PetInstance pet = null;
Connection con = null;
PreparedStatement statement = null;
ResultSet rset = null;
try
{
con = DatabaseFactory.getInstance().getConnection();
statement = con.prepareStatement("SELECT objId, name, level, curHp, curMp, exp, sp, fed FROM pets WHERE item_obj_id=?");
statement.setInt(1, control.getObjectId());
rset = statement.executeQuery();
if (!rset.next())
{
if (PetDataTable.isBabyPet(template.getNpcId()) || PetDataTable.isImprovedBabyPet(template.getNpcId()))
{
pet = new PetBabyInstance(IdFactory.getInstance().getNextId(), template, owner, control);
}
else
{
pet = new PetInstance(IdFactory.getInstance().getNextId(), template, owner, control);
}
return pet;
}
if (PetDataTable.isBabyPet(template.getNpcId()) || PetDataTable.isImprovedBabyPet(template.getNpcId()))
{
pet = new PetBabyInstance(rset.getInt("objId"), template, owner, control, rset.getInt("level"), rset.getLong("exp"));
}
else
{
pet = new PetInstance(rset.getInt("objId"), template, owner, control, rset.getInt("level"), rset.getLong("exp"));
}
pet.setRespawned(true);
String name = rset.getString("name");
pet.setName((name == null) || name.isEmpty() ? template.name : name);
pet.setCurrentHpMp(rset.getDouble("curHp"), rset.getInt("curMp"), true);
pet.setCurrentCp(pet.getMaxCp());
pet.setSp(rset.getInt("sp"));
pet.setCurrentFed(rset.getInt("fed"));
}
catch (Exception e)
{
_log.error("Could not restore Pet data from item: " + control + "!", e);
return null;
}
finally
{
DbUtils.closeQuietly(con, statement, rset);
}
return pet;
}
/**
* Constructor for PetInstance.
* @param objectId int
* @param template NpcTemplate
* @param owner Player
* @param control ItemInstance
*/
public PetInstance(int objectId, NpcTemplate template, Player owner, ItemInstance control)
{
this(objectId, template, owner, control, 0, 0);
}
/**
* Constructor for PetInstance.
* @param objectId int
* @param template NpcTemplate
* @param owner Player
* @param control ItemInstance
* @param currentLevel int
* @param exp long
*/
public PetInstance(int objectId, NpcTemplate template, Player owner, ItemInstance control, int currentLevel, long exp)
{
super(objectId, template, owner);
_controlItemObjId = control.getObjectId();
_exp = exp;
_level = control.getEnchantLevel();
if (_level <= 0)
{
if (template.npcId == PetDataTable.SIN_EATER_ID)
{
_level = owner.getLevel();
}
else
{
_level = template.level;
}
_exp = getExpForThisLevel();
}
int minLevel = PetDataTable.getMinLevel(template.npcId);
if (_level < minLevel)
{
_level = minLevel;
}
if (_exp < getExpForThisLevel())
{
_exp = getExpForThisLevel();
}
while ((_exp >= getExpForNextLevel()) && (_level < Experience.getMaxLevel()))
{
_level++;
}
while ((_exp < getExpForThisLevel()) && (_level > minLevel))
{
_level--;
}
if (PetDataTable.isVitaminPet(template.npcId))
{
_level = owner.getLevel();
_exp = getExpForNextLevel();
}
_data = PetDataTable.getInstance().getInfo(template.npcId, _level);
_inventory = new PetInventory(this);
}
/**
* Method onSpawn.
*/
@Override
protected void onSpawn()
{
super.onSpawn();
startFeed(false);
}
/**
* Method onDespawn.
*/
@Override
protected void onDespawn()
{
super.onSpawn();
stopFeed();
}
/**
* Method tryFeedItem.
* @param item ItemInstance
* @return boolean
*/
public boolean tryFeedItem(ItemInstance item)
{
if (item == null)
{
return false;
}
boolean deluxFood = PetDataTable.isStrider(getNpcId()) && (item.getItemId() == DELUXE_FOOD_FOR_STRIDER);
if ((getFoodId() != item.getItemId()) && !deluxFood)
{
return false;
}
int newFed = Math.min(getMaxFed(), getCurrentFed() + Math.max((getMaxFed() * getAddFed() * (deluxFood ? 2 : 1)) / 100, 1));
if (getCurrentFed() != newFed)
{
if (getInventory().destroyItem(item, 1L))
{
getPlayer().sendPacket(new SystemMessage(SystemMessage.PET_TOOK_S1_BECAUSE_HE_WAS_HUNGRY).addItemName(item.getItemId()));
setCurrentFed(newFed);
sendStatusUpdate();
}
}
return true;
}
/**
* Method tryFeed.
* @return boolean
*/
public boolean tryFeed()
{
ItemInstance food = getInventory().getItemByItemId(getFoodId());
if ((food == null) && PetDataTable.isStrider(getNpcId()))
{
food = getInventory().getItemByItemId(DELUXE_FOOD_FOR_STRIDER);
}
return tryFeedItem(food);
}
/**
* Method addExpAndSp.
* @param addToExp long
* @param addToSp long
*/
@Override
public void addExpAndSp(long addToExp, long addToSp)
{
Player owner = getPlayer();
if (PetDataTable.isVitaminPet(getNpcId()))
{
return;
}
_exp += addToExp;
_sp += addToSp;
if (_exp > getMaxExp())
{
_exp = getMaxExp();
}
if ((addToExp > 0) || (addToSp > 0))
{
owner.sendPacket(new SystemMessage(SystemMessage.THE_PET_ACQUIRED_EXPERIENCE_POINTS_OF_S1).addNumber(addToExp));
}
int old_level = _level;
while ((_exp >= getExpForNextLevel()) && (_level < Experience.getMaxLevel()))
{
_level++;
}
while ((_exp < getExpForThisLevel()) && (_level > getMinLevel()))
{
_level--;
}
if (old_level < _level)
{
owner.sendMessage(new CustomMessage("lineage2.gameserver.model.instances.L2PetInstance.PetLevelUp", owner).addNumber(_level));
broadcastPacket(new SocialAction(getObjectId(), SocialAction.LEVEL_UP));
setCurrentHpMp(getMaxHp(), getMaxMp());
}
if (old_level != _level)
{
updateControlItem();
updateData();
}
if ((addToExp > 0) || (addToSp > 0))
{
sendStatusUpdate();
}
}
/**
* Method consumeItem.
* @param itemConsumeId int
* @param itemCount long
* @return boolean
*/
@Override
public boolean consumeItem(int itemConsumeId, long itemCount)
{
return getInventory().destroyItemByItemId(itemConsumeId, itemCount);
}
/**
* Method deathPenalty.
*/
private void deathPenalty()
{
if (isInZoneBattle())
{
return;
}
int lvl = getLevel();
double percentLost = (-0.07 * lvl) + 6.5;
lostExp = (int) Math.round(((getExpForNextLevel() - getExpForThisLevel()) * percentLost) / 100);
addExpAndSp(-lostExp, 0);
}
/**
* Method destroyControlItem.
*/
private void destroyControlItem()
{
Player owner = getPlayer();
if (getControlItemObjId() == 0)
{
return;
}
if (!owner.getInventory().destroyItemByObjectId(getControlItemObjId(), 1L))
{
return;
}
Connection con = null;
PreparedStatement statement = null;
try
{
con = DatabaseFactory.getInstance().getConnection();
statement = con.prepareStatement("DELETE FROM pets WHERE item_obj_id=?");
statement.setInt(1, getControlItemObjId());
statement.execute();
}
catch (Exception e)
{
_log.warn("could not delete pet:" + e);
}
finally
{
DbUtils.closeQuietly(con, statement);
}
}
/**
* Method onDeath.
* @param killer Creature
*/
@Override
protected void onDeath(Creature killer)
{
super.onDeath(killer);
Player owner = getPlayer();
owner.sendPacket(Msg.THE_PET_HAS_BEEN_KILLED_IF_YOU_DO_NOT_RESURRECT_IT_WITHIN_24_HOURS_THE_PETS_BODY_WILL_DISAPPEAR_ALONG_WITH_ALL_THE_PETS_ITEMS);
startDecay(86400000L);
if (PetDataTable.isVitaminPet(getNpcId()))
{
return;
}
stopFeed();
deathPenalty();
}
/**
* Method doPickupItem.
* @param object GameObject
*/
@Override
public void doPickupItem(GameObject object)
{
Player owner = getPlayer();
stopMove();
if (!object.isItem())
{
return;
}
ItemInstance item = (ItemInstance) object;
if (item.isCursed())
{
owner.sendPacket(new SystemMessage(SystemMessage.YOU_HAVE_FAILED_TO_PICK_UP_S1).addItemName(item.getItemId()));
return;
}
synchronized (item)
{
if (!item.isVisible())
{
return;
}
if (item.isHerb())
{
Skill[] skills = item.getTemplate().getAttachedSkills();
if (skills.length > 0)
{
for (Skill skill : skills)
{
altUseSkill(skill, this);
}
}
item.deleteMe();
return;
}
if (!getInventory().validateWeight(item))
{
sendPacket(Msg.EXCEEDED_PET_INVENTORYS_WEIGHT_LIMIT);
return;
}
if (!getInventory().validateCapacity(item))
{
sendPacket(Msg.DUE_TO_THE_VOLUME_LIMIT_OF_THE_PETS_INVENTORY_NO_MORE_ITEMS_CAN_BE_PLACED_THERE);
return;
}
if (!item.getTemplate().getHandler().pickupItem(this, item))
{
return;
}
FlagItemAttachment attachment = item.getAttachment() instanceof FlagItemAttachment ? (FlagItemAttachment) item.getAttachment() : null;
if (attachment != null)
{
return;
}
item.pickupMe();
}
if ((owner.getParty() == null) || (owner.getParty().getLootDistribution() == Party.ITEM_LOOTER))
{
getInventory().addItem(item);
sendChanges();
}
else
{
owner.getParty().distributeItem(owner, item, null);
}
broadcastPickUpMsg(item);
}
/**
* Method doRevive.
* @param percent double
*/
public void doRevive(double percent)
{
restoreExp(percent);
doRevive();
}
/**
* Method doRevive.
*/
@Override
public void doRevive()
{
stopDecay();
super.doRevive();
startFeed(false);
setRunning();
}
/**
* Method getAccuracy.
* @return int
*/
@Override
public int getAccuracy()
{
return (int) calcStat(Stats.ACCURACY_COMBAT, _data.getAccuracy(), null, null);
}
/**
* Method getActiveWeaponInstance.
* @return ItemInstance
*/
@Override
public ItemInstance getActiveWeaponInstance()
{
return null;
}
/**
* Method getActiveWeaponItem.
* @return WeaponTemplate
*/
@Override
public WeaponTemplate getActiveWeaponItem()
{
return null;
}
/**
* Method getControlItem.
* @return ItemInstance
*/
public ItemInstance getControlItem()
{
Player owner = getPlayer();
if (owner == null)
{
return null;
}
int item_obj_id = getControlItemObjId();
if (item_obj_id == 0)
{
return null;
}
return owner.getInventory().getItemByObjectId(item_obj_id);
}
/**
* Method getControlItemObjId.
* @return int
*/
@Override
public int getControlItemObjId()
{
return _controlItemObjId;
}
/**
* Method getCriticalHit.
* @param target Creature
* @param skill Skill
* @return int
*/
@Override
public int getCriticalHit(Creature target, Skill skill)
{
return (int) calcStat(Stats.CRITICAL_BASE, _data.getCritical(), target, skill);
}
/**
* Method getCurrentFed.
* @return int
*/
@Override
public int getCurrentFed()
{
return _curFed;
}
/**
* Method getEvasionRate.
* @param target Creature
* @return int
*/
@Override
public int getEvasionRate(Creature target)
{
return (int) calcStat(Stats.EVASION_RATE, _data.getEvasion(), target, null);
}
/**
* Method getExpForNextLevel.
* @return long
*/
@Override
public long getExpForNextLevel()
{
return PetDataTable.getInstance().getInfo(getNpcId(), _level + 1).getExp();
}
/**
* Method getExpForThisLevel.
* @return long
*/
@Override
public long getExpForThisLevel()
{
return PetDataTable.getInstance().getInfo(getNpcId(), _level).getExp();
}
/**
* Method getFoodId.
* @return int
*/
public int getFoodId()
{
return _data.getFoodId();
}
/**
* Method getAddFed.
* @return int
*/
public int getAddFed()
{
return _data.getAddFed();
}
/**
* Method getInventory.
* @return PetInventory
*/
@Override
public PetInventory getInventory()
{
return _inventory;
}
/**
* Method getWearedMask.
* @return long
*/
@Override
public long getWearedMask()
{
return _inventory.getWearedMask();
}
/**
* Method getLevel.
* @return int
*/
@Override
public final int getLevel()
{
return _level;
}
/**
* Method setLevel.
* @param level int
*/
public void setLevel(int level)
{
_level = level;
}
/**
* Method getLevelMod.
* @return double
*/
@Override
public double getLevelMod()
{
return (89. + getLevel()) / 100.0;
}
/**
* Method getMinLevel.
* @return int
*/
public int getMinLevel()
{
return _data.getMinLevel();
}
/**
* Method getMaxExp.
* @return long
*/
public long getMaxExp()
{
return PetDataTable.getInstance().getInfo(getNpcId(), Experience.getMaxLevel()).getExp();
}
/**
* Method getMaxFed.
* @return int
*/
@Override
public int getMaxFed()
{
return _data.getFeedMax();
}
/**
* Method getMaxLoad.
* @return int
*/
@Override
public int getMaxLoad()
{
return (int) calcStat(Stats.MAX_LOAD, _data.getMaxLoad(), null, null);
}
/**
* Method getInventoryLimit.
* @return int
*/
@Override
public int getInventoryLimit()
{
return Config.ALT_PET_INVENTORY_LIMIT;
}
/**
* Method getMaxHp.
* @return int
*/
@Override
public int getMaxHp()
{
return (int) calcStat(Stats.MAX_HP, _data.getHP(), null, null);
}
/**
* Method getMaxMp.
* @return int
*/
@Override
public int getMaxMp()
{
return (int) calcStat(Stats.MAX_MP, _data.getMP(), null, null);
}
/**
* Method getPAtk.
* @param target Creature
* @return int
*/
@Override
public int getPAtk(Creature target)
{
double mod = BaseStats.STR.calcBonus(this) * getLevelMod();
return (int) calcStat(Stats.POWER_ATTACK, _data.getPAtk() / mod, target, null);
}
/**
* Method getPDef.
* @param target Creature
* @return int
*/
@Override
public int getPDef(Creature target)
{
double mod = getLevelMod();
return (int) calcStat(Stats.POWER_DEFENCE, _data.getPDef() / mod, target, null);
}
/**
* Method getMAtk.
* @param target Creature
* @param skill Skill
* @return int
*/
@Override
public int getMAtk(Creature target, Skill skill)
{
double ib = BaseStats.INT.calcBonus(this);
double lvlb = getLevelMod();
double mod = lvlb * lvlb * ib * ib;
return (int) calcStat(Stats.MAGIC_ATTACK, _data.getMAtk() / mod, target, skill);
}
/**
* Method getMDef.
* @param target Creature
* @param skill Skill
* @return int
*/
@Override
public int getMDef(Creature target, Skill skill)
{
double mod = BaseStats.MEN.calcBonus(this) * getLevelMod();
return (int) calcStat(Stats.MAGIC_DEFENCE, _data.getMDef() / mod, target, skill);
}
/**
* Method getPAtkSpd.
* @return int
*/
@Override
public int getPAtkSpd()
{
return (int) calcStat(Stats.POWER_ATTACK_SPEED, calcStat(Stats.ATK_BASE, _data.getAtkSpeed(), null, null), null, null);
}
/**
* Method getMAtkSpd.
* @return int
*/
@Override
public int getMAtkSpd()
{
return (int) calcStat(Stats.MAGIC_ATTACK_SPEED, _data.getCastSpeed(), null, null);
}
/**
* Method getRunSpeed.
* @return int
*/
@Override
public int getRunSpeed()
{
return getSpeed(_data.getSpeed());
}
/**
* Method getSoulshotConsumeCount.
* @return int
*/
@Override
public int getSoulshotConsumeCount()
{
return PetDataTable.getSoulshots(getNpcId());
}
/**
* Method getSpiritshotConsumeCount.
* @return int
*/
@Override
public int getSpiritshotConsumeCount()
{
return PetDataTable.getSpiritshots(getNpcId());
}
/**
* Method getSecondaryWeaponInstance.
* @return ItemInstance
*/
@Override
public ItemInstance getSecondaryWeaponInstance()
{
return null;
}
/**
* Method getSecondaryWeaponItem.
* @return WeaponTemplate
*/
@Override
public WeaponTemplate getSecondaryWeaponItem()
{
return null;
}
/**
* Method getSkillLevel.
* @param skillId int
* @return int
*/
public int getSkillLevel(int skillId)
{
if ((_skills == null) || (_skills.get(skillId) == null))
{
return -1;
}
int lvl = getLevel();
return lvl > 70 ? 7 + ((lvl - 70) / 5) : lvl / 10;
}
/**
* Method getSummonType.
* @return int
*/
@Override
public int getSummonType()
{
return 2;
}
/**
* Method getTemplate.
* @return NpcTemplate
*/
@Override
public NpcTemplate getTemplate()
{
return (NpcTemplate) _template;
}
/**
* Method isMountable.
* @return boolean
*/
@Override
public boolean isMountable()
{
return _data.isMountable();
}
/**
* Method isRespawned.
* @return boolean
*/
public boolean isRespawned()
{
return _respawned;
}
/**
* Method restoreExp.
* @param percent double
*/
public void restoreExp(double percent)
{
if (lostExp != 0)
{
addExpAndSp((long) ((lostExp * percent) / 100.), 0);
lostExp = 0;
}
}
/**
* Method setCurrentFed.
* @param num int
*/
public void setCurrentFed(int num)
{
_curFed = Math.min(getMaxFed(), Math.max(0, num));
}
/**
* Method setRespawned.
* @param respawned boolean
*/
public void setRespawned(boolean respawned)
{
_respawned = respawned;
}
/**
* Method setSp.
* @param sp int
*/
@Override
public void setSp(int sp)
{
_sp = sp;
}
/**
* Method startFeed.
* @param battleFeed boolean
*/
public void startFeed(boolean battleFeed)
{
boolean first = _feedTask == null;
stopFeed();
if (!isDead())
{
int feedTime;
if (PetDataTable.isVitaminPet(getNpcId()))
{
feedTime = 10000;
}
else
{
feedTime = Math.max(first ? 15000 : 1000, 60000 / (battleFeed ? _data.getFeedBattle() : _data.getFeedNormal()));
}
_feedTask = ThreadPoolManager.getInstance().schedule(new FeedTask(), feedTime);
}
}
/**
* Method stopFeed.
*/
private void stopFeed()
{
if (_feedTask != null)
{
_feedTask.cancel(false);
_feedTask = null;
}
}
/**
* Method store.
*/
public void store()
{
if ((getControlItemObjId() == 0) || (_exp == 0))
{
return;
}
Connection con = null;
PreparedStatement statement = null;
try
{
con = DatabaseFactory.getInstance().getConnection();
String req;
if (!isRespawned())
{
req = "INSERT INTO pets (name,level,curHp,curMp,exp,sp,fed,objId,item_obj_id) VALUES (?,?,?,?,?,?,?,?,?)";
}
else
{
req = "UPDATE pets SET name=?,level=?,curHp=?,curMp=?,exp=?,sp=?,fed=?,objId=? WHERE item_obj_id = ?";
}
statement = con.prepareStatement(req);
statement.setString(1, getName().equalsIgnoreCase(getTemplate().name) ? "" : getName());
statement.setInt(2, _level);
statement.setDouble(3, getCurrentHp());
statement.setDouble(4, getCurrentMp());
statement.setLong(5, _exp);
statement.setLong(6, _sp);
statement.setInt(7, _curFed);
statement.setInt(8, getObjectId());
statement.setInt(9, _controlItemObjId);
statement.executeUpdate();
}
catch (Exception e)
{
_log.error("Could not store pet data!", e);
}
finally
{
DbUtils.closeQuietly(con, statement);
}
_respawned = true;
}
/**
* Method onDelete.
*/
@Override
protected void onDelete()
{
super.onDelete();
}
/**
* Method onDecay.
*/
@Override
protected void onDecay()
{
getInventory().store();
destroyControlItem();
super.onDecay();
}
/**
* Method unSummon.
*/
@Override
public void unSummon()
{
stopFeed();
getInventory().store();
store();
super.unSummon();
}
/**
* Method getSummonPoint.
* @return int
*/
@Override
public int getSummonPoint()
{
return 0;
}
/**
* Method updateControlItem.
*/
public void updateControlItem()
{
ItemInstance controlItem = getControlItem();
if (controlItem == null)
{
return;
}
controlItem.setEnchantLevel(_level);
controlItem.setCustomType2(isDefaultName() ? 0 : 1);
controlItem.setJdbcState(JdbcEntityState.UPDATED);
controlItem.update();
Player owner = getPlayer();
owner.sendPacket(new InventoryUpdate().addModifiedItem(controlItem));
}
/**
* Method updateData.
*/
private void updateData()
{
_data = PetDataTable.getInstance().getInfo(getTemplate().npcId, _level);
}
/**
* Method getExpPenalty.
* @return double
*/
@Override
public double getExpPenalty()
{
return PetDataTable.getExpPenalty(getTemplate().npcId);
}
/**
* Method displayGiveDamageMessage.
* @param target Creature
* @param damage int
* @param crit boolean
* @param miss boolean
* @param shld boolean
* @param magic boolean
*/
@Override
public void displayGiveDamageMessage(Creature target, int damage, boolean crit, boolean miss, boolean shld, boolean magic)
{
Player owner = getPlayer();
if (crit)
{
owner.sendPacket(SystemMsg.SUMMONED_MONSTERS_CRITICAL_HIT);
}
if (miss)
{
owner.sendPacket(new SystemMessage(SystemMessage.C1S_ATTACK_WENT_ASTRAY).addName(this));
}
else
{
owner.sendPacket(new SystemMessage(SystemMessage.THE_PET_GAVE_DAMAGE_OF_S1).addNumber(damage));
}
}
/**
* Method displayReceiveDamageMessage.
* @param attacker Creature
* @param damage int
*/
@Override
public void displayReceiveDamageMessage(Creature attacker, int damage)
{
Player owner = getPlayer();
if (!isDead())
{
SystemMessage sm = new SystemMessage(SystemMessage.THE_PET_RECEIVED_DAMAGE_OF_S2_CAUSED_BY_S1);
if (attacker.isNpc())
{
sm.addNpcName(((NpcInstance) attacker).getTemplate().npcId);
}
else
{
sm.addString(attacker.getName());
}
sm.addNumber((long) damage);
owner.sendPacket(sm);
}
}
/**
* Method getFormId.
* @return int
*/
@Override
public int getFormId()
{
switch (getNpcId())
{
case PetDataTable.GREAT_WOLF_ID:
case PetDataTable.WGREAT_WOLF_ID:
case PetDataTable.FENRIR_WOLF_ID:
case PetDataTable.WFENRIR_WOLF_ID:
if (getLevel() >= 70)
{
return 3;
}
else if (getLevel() >= 65)
{
return 2;
}
else if (getLevel() >= 60)
{
return 1;
}
break;
}
return 0;
}
/**
* Method isPet.
* @return boolean
*/
@Override
public boolean isPet()
{
return true;
}
/**
* Method isDefaultName.
* @return boolean
*/
public boolean isDefaultName()
{
return StringUtils.isEmpty(_name) || getName().equalsIgnoreCase(getTemplate().name);
}
/**
* Method getSummonSkillId.
* @return int
*/
@Override
public int getSummonSkillId()
{
return 0;
}
/**
* Method getSummonSkillLvl.
* @return int
*/
@Override
public int getSummonSkillLvl()
{
return 0;
}
}