/* * 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 2, 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * [URL]http://www.gnu.org/copyleft/gpl.html[/URL] */package net.sf.l2j.gameserver.model.actor.instance;import javolution.util.FastList;import net.sf.l2j.gameserver.ThreadPoolManager;import net.sf.l2j.gameserver.datatables.SkillTable;import net.sf.l2j.gameserver.handler.ISkillHandler;import net.sf.l2j.gameserver.handler.SkillHandler;import net.sf.l2j.gameserver.lib.Rnd;import net.sf.l2j.gameserver.model.L2Character;import net.sf.l2j.gameserver.model.L2Party;import net.sf.l2j.gameserver.model.L2Skill;import net.sf.l2j.gameserver.serverpackets.MagicSkillUser;import net.sf.l2j.gameserver.taskmanager.AttackStanceTaskManager;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;public class L2CubicInstance{ private static Log _log = LogFactory.getLog(L2CubicInstance.class.getName()); public static final int STORM_CUBIC = 1; public static final int VAMPIRIC_CUBIC = 2; public static final int LIFE_CUBIC = 3; public static final int VIPER_CUBIC = 4; public static final int POLTERGEIST_CUBIC = 5; public static final int BINDING_CUBIC = 6; public static final int AQUA_CUBIC = 7; public static final int SPARK_CUBIC = 8; public static final int ATTRACT_CUBIC = 9; private L2PcInstance _owner; private L2Character _target; private int _id; private int _level = 1; private int _skillId; private FastList<Integer> _skills = new FastList<Integer>(); private ThreadPoolManager.TTask _disappearTask; private ThreadPoolManager.TTask _actionTask; public L2CubicInstance(L2PcInstance owner, int id, int level, int skillId) { _owner = owner; _id = id; _level = level; _skillId = skillId; switch (_id) { case STORM_CUBIC: _skills.add(4049); break; case VAMPIRIC_CUBIC: _skills.add(4050); break; case LIFE_CUBIC: _skills.add(4051); _disappearTask = ThreadPoolManager.getInstance().scheduleGeneral(new Disappear(), 3600000); // disappear in 60 mins doAction(_owner); break; case VIPER_CUBIC: _skills.add(4052); break; case POLTERGEIST_CUBIC: _skills.add(4053); _skills.add(4054); _skills.add(4055); break; case BINDING_CUBIC: _skills.add(4164); break; case AQUA_CUBIC: _skills.add(4165); break; case SPARK_CUBIC: _skills.add(4166); break; case ATTRACT_CUBIC: _skills.add(5115); _skills.add(5116); break; } if (_disappearTask == null) _disappearTask = ThreadPoolManager.getInstance().scheduleGeneral(new Disappear(), 1200000); // disappear in 20 mins } public void doAction(L2Character target) { if (_target == target) return; stopAction(target); switch (_id) { case STORM_CUBIC: case VIPER_CUBIC: case POLTERGEIST_CUBIC: case BINDING_CUBIC: case AQUA_CUBIC: case SPARK_CUBIC: case ATTRACT_CUBIC: _actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Action(30), 4000, 8000); // 26.66 break; case VAMPIRIC_CUBIC: _actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Action(15), 4000, 8000); // 53.33 break; case LIFE_CUBIC: _actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new Heal(15), 4000, 8000); // 53.33 } } public int getId() { return _id; } private void stopAction(L2Character target) { if (_actionTask != null) { _actionTask.cancel(true); _actionTask = null; } if (target != null) _owner.sendMessage("You order your " + getCubicName()+" to attack "+target.getName()+"!"); else if (_target != null) _owner.sendMessage("Your "+getCubicName()+" stops attacking "+_target.getName()+"!"); _target = target; } private class Action implements Runnable { private int _chance; private Action(int chance) { _chance = chance; } public void run() { if (_target.isDead() || _owner.getTarget() != _target || _owner.isSitting() || !AttackStanceTaskManager.getInstance().getAttackStanceTask(_owner)) { stopAction(null); return; } if (_target != null) { if (Rnd.get(100) < _chance) { L2Skill skill = SkillTable.getInstance().getInfo(_skills.get(Rnd.get(_skills.size())), _level); if (skill != null) { int range = skill.getCastRange(); if (range < 100) range = 400; //ha hianyzik a range az xml ekbol double dist = Math.sqrt(_owner.getDistanceSq(_target)) - _target.getTemplate().getCollisionRadius(); if (dist <= range) { _owner.sendMessage("Your "+getCubicName()+" uses "+skill.getName()+" on "+_target.getName()+"."); L2Character[] targets = { _target }; ISkillHandler handler = SkillHandler.getInstance().getSkillHandler(skill.getSkillType()); if (handler != null) handler.useSkill(_owner, skill, targets); else skill.useSkill(_owner, targets); _owner.broadcastPacket(new MagicSkillUser(_owner, _target, skill.getId(), _level, 0, 0)); } } } } } } private class Heal implements Runnable { private int _chance; private Heal(int chance) { _chance = chance; } public void run() { if (Rnd.get(100) < _chance) { L2Skill skill = SkillTable.getInstance().getInfo(_skills.get(Rnd.get(_skills.size())), _level); if (skill != null) { L2Character target = null; L2Party party = _owner.getParty(); if (party != null) { double hpDiff; int range = skill.getCastRange(); if (range < 100) range = 400; //ha hianyzik a range az xml ekbol for (L2Character partyMember : party.getPartyMembers()) { if (!partyMember.isDead()) { double dist = Math.sqrt(_owner.getDistanceSq(partyMember)) - partyMember.getTemplate().getCollisionRadius(); if (dist > range) continue; // 0..range if (dist < 100) dist = 100; // 100..range int actHp = (partyMember.getMaxHp() - partyMember.getStatus().getCurrentHp()) / Math.sqrt(dist); //10..~30 if (hpDiff < actHp) { hpDiff = actHp; target = partyMember; } } } } else { if (_owner.getStatus().getCurrentHp() < _owner.getMaxHp()) target = _owner; } if (target != null) { String targetName = (target == _owner ? "yourself" : target.getName()); _owner.sendMessage("Your "+getCubicName()+" heals "+targetName+"."); L2Character[] targets = { target }; ISkillHandler handler = SkillHandler.getInstance().getSkillHandler(skill.getSkillType()); if (handler != null) handler.useSkill(_owner, skill, targets); else skill.useSkill(_owner, targets); _owner.broadcastPacket(new MagicSkillUser(_owner, target, skill.getId(), _level, 0, 0)); } } } } } private class Disappear implements Runnable { public void run() { deleteMe(); } } private String getCubicName() { switch (_id) { case STORM_CUBIC: return "Storm Cubic"; case VAMPIRIC_CUBIC: return "Vampiric Cubic"; case LIFE_CUBIC: return "Life Cubic"; case VIPER_CUBIC: return "Viper Cubic"; case POLTERGEIST_CUBIC: return "Poltergeist Cubic"; case BINDING_CUBIC: return "Binding Cubic"; case AQUA_CUBIC: return "Aqua Cubic"; case SPARK_CUBIC: return "Spark Cubic"; case ATTRACT_CUBIC: return "Attract Cubic"; default: return ""; } } public void deleteMe() { _target = null; _owner.sendMessage("Your " + getCubicName() + " disappeared!"); _owner.delCubic(_id); _owner.broadcastUserInfo(); if (_disappearTask != null) { _disappearTask.cancel(true); _disappearTask = null; } if (_actionTask != null) { _actionTask.cancel(true); _actionTask = null; } } public void shouldDisappearAtOlympiad() { if (!_owner.hasSkill(_skillId)) deleteMe(); }}