-Implemented new cubics & cubic skills.

-Fixed some visual bugs (character see removed cubic, not see seed talisman aura until re-equip talisman).
-Removed unused packet ExGetBossRecord (I forgot remove this in my raid points patch).

Contributed by NviX.
This commit is contained in:
MobiusDev
2015-07-07 12:50:33 +00:00
parent f25a32b9f7
commit 71fd68697b
11 changed files with 551 additions and 235 deletions

View File

@ -35,6 +35,7 @@ import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicAction;
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicBuff;
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicDisappear;
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicHeal;
import com.l2jserver.gameserver.model.effects.L2EffectType;
@ -67,6 +68,14 @@ public final class L2CubicInstance implements IIdentifiable
public static final int SMART_CUBIC_ARCANALORD = 12;
public static final int SMART_CUBIC_ELEMENTALMASTER = 13;
public static final int SMART_CUBIC_SPECTRALMASTER = 14;
public static final int AVENGING_CUBIC = 15;
public static final int KNIGHT_CUBIC = 16;
public static final int FAIRY_CUBIC = 17;
public static final int BUFF_CUBIC = 18;
public static final int MIND_CUBIC = 19; // NOT USED
public static final int PHANTOM_CUBIC = 20;
public static final int HEX_CUBIC = 21;
public static final int GUARDIAN_CUBIC = 22;
// Max range of cubic skills
// TODO: Check/fix the max range
@ -75,6 +84,14 @@ public final class L2CubicInstance implements IIdentifiable
// Cubic skills
public static final int SKILL_CUBIC_HEAL = 4051;
public static final int SKILL_CUBIC_CURE = 5579;
public static final int SKILL_CUBIC_HEALER = 11807;
public static final int SKILL_BUFF_CUBIC_HEAL = 10083;
public static final int SKILL_MIND_CUBIC_RECHARGE = 10084;
public static final int SKILL_BUFF_CUBIC_GREAT_HEAL = 10082;
public static final int SKILL_MIND_CUBIC_GREAT_RECHARGE = 10089;
public static final int SKILL_AVENGING_CUBIC_CLEANCE = 11292;
public static final int SKILL_KNIGHT_CUBIC = 10056;
public static final int SKILL_GUARDIAN_CUBIC = 10093;
private final L2PcInstance _owner;
private L2Character _target;
@ -156,6 +173,41 @@ public final class L2CubicInstance implements IIdentifiable
_skills.add(SkillData.getInstance().getSkill(4049, 8));
_skills.add(SkillData.getInstance().getSkill(5115, 4));
break;
case AVENGING_CUBIC:
_skills.add(SkillData.getInstance().getSkill(11292, level));
_skills.add(SkillData.getInstance().getSkill(11293, level));
_skills.add(SkillData.getInstance().getSkill(11294, level));
break;
case KNIGHT_CUBIC:
_skills.add(SkillData.getInstance().getSkill(10056, level));
doAction();
break;
case FAIRY_CUBIC:
_skills.add(SkillData.getInstance().getSkill(11807, level));
doAction();
break;
case BUFF_CUBIC:
_skills.add(SkillData.getInstance().getSkill(10082, level));
_skills.add(SkillData.getInstance().getSkill(10083, level));
_skills.add(SkillData.getInstance().getSkill(10084, level));
_skills.add(SkillData.getInstance().getSkill(10089, level));
doAction();
break;
case MIND_CUBIC: // NOT USED
_skills.add(SkillData.getInstance().getSkill(10084, level));
_skills.add(SkillData.getInstance().getSkill(10089, level));
doAction();
break;
case PHANTOM_CUBIC:
_skills.add(SkillData.getInstance().getSkill(10085, level));
break;
case HEX_CUBIC:
_skills.add(SkillData.getInstance().getSkill(10086, level));
break;
case GUARDIAN_CUBIC:
_skills.add(SkillData.getInstance().getSkill(10093, level));
doAction();
break;
}
_disappearTask = ThreadPoolManager.getInstance().scheduleGeneral(new CubicDisappear(this), cubicDuration * 1000); // disappear
}
@ -183,11 +235,21 @@ public final class L2CubicInstance implements IIdentifiable
case SMART_CUBIC_SPECTRALMASTER:
case SMART_CUBIC_EVATEMPLAR:
case SMART_CUBIC_SHILLIENTEMPLAR:
case AVENGING_CUBIC:
case PHANTOM_CUBIC:
case HEX_CUBIC:
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CubicAction(this, _cubicSkillChance), 0, _cubicDelay);
break;
case LIFE_CUBIC:
case FAIRY_CUBIC:
case BUFF_CUBIC:
case MIND_CUBIC:
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CubicHeal(this), 0, _cubicDelay);
break;
case KNIGHT_CUBIC:
case GUARDIAN_CUBIC:
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CubicBuff(this, _cubicSkillChance), 0, _cubicDelay);
break;
}
}

View File

@ -98,7 +98,7 @@ public final class CubicAction implements Runnable
// Smart Cubic debuff cancel is 100%
boolean useCubicCure = false;
if ((_cubic.getId() >= L2CubicInstance.SMART_CUBIC_EVATEMPLAR) && (_cubic.getId() <= L2CubicInstance.SMART_CUBIC_SPECTRALMASTER))
if (((_cubic.getId() >= L2CubicInstance.SMART_CUBIC_EVATEMPLAR) && (_cubic.getId() <= L2CubicInstance.SMART_CUBIC_SPECTRALMASTER)) || (_cubic.getId() == L2CubicInstance.AVENGING_CUBIC))
{
for (BuffInfo info : _cubic.getOwner().getEffectList().getDebuffs())
{
@ -113,11 +113,20 @@ public final class CubicAction implements Runnable
if (useCubicCure)
{
// Smart Cubic debuff cancel is needed, no other skill is used in this activation period
MagicSkillUse msu = new MagicSkillUse(_cubic.getOwner(), _cubic.getOwner(), L2CubicInstance.SKILL_CUBIC_CURE, 1, 0, 0);
_cubic.getOwner().broadcastPacket(msu);
// The cubic has done an action, increase the current count
_currentCount.incrementAndGet();
if ((_cubic.getId() >= L2CubicInstance.SMART_CUBIC_EVATEMPLAR) && (_cubic.getId() <= L2CubicInstance.SMART_CUBIC_SPECTRALMASTER))
{
MagicSkillUse msu = new MagicSkillUse(_cubic.getOwner(), _cubic.getOwner(), L2CubicInstance.SKILL_CUBIC_CURE, 1, 0, 0);
_cubic.getOwner().broadcastPacket(msu);
// The cubic has done an action, increase the current count
_currentCount.incrementAndGet();
}
else
{
MagicSkillUse msu = new MagicSkillUse(_cubic.getOwner(), _cubic.getOwner(), L2CubicInstance.SKILL_AVENGING_CUBIC_CLEANCE, 1, 0, 0);
_cubic.getOwner().broadcastPacket(msu);
// The cubic has done an action, increase the current count
_currentCount.incrementAndGet();
}
}
else if (Rnd.get(1, 100) < _chance)
{

View File

@ -0,0 +1,124 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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 com.l2jserver.gameserver.model.actor.tasks.cubics;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2CubicInstance;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jserver.gameserver.taskmanager.AttackStanceTaskManager;
import com.l2jserver.util.Rnd;
/**
* @author NviX
*/
public final class CubicBuff implements Runnable
{
private static final Logger _log = Logger.getLogger(CubicBuff.class.getName());
private final L2CubicInstance _cubic;
private final AtomicInteger _currentCount = new AtomicInteger();
private final int _chance;
public CubicBuff(L2CubicInstance cubic, int chance)
{
_cubic = cubic;
_chance = chance;
}
@Override
public void run()
{
if (_cubic == null)
{
return;
}
if (_cubic.getOwner().isDead() || !_cubic.getOwner().isOnline())
{
_cubic.stopAction();
_cubic.getOwner().getCubics().remove(_cubic.getId());
_cubic.getOwner().broadcastUserInfo();
_cubic.cancelDisappear();
return;
}
// The cubic has already reached its limit and it will stay idle until its duration ends.
if ((_cubic.getCubicMaxCount() > -1) && (_currentCount.get() >= _cubic.getCubicMaxCount()))
{
_cubic.stopAction();
return;
}
try
{
if (!AttackStanceTaskManager.getInstance().hasAttackStanceTask(_cubic.getOwner()))
{
if (_cubic.getOwner().hasSummon())
{
for (L2Summon servitor : _cubic.getOwner().getServitors().values())
{
if (!AttackStanceTaskManager.getInstance().hasAttackStanceTask(servitor))
{
_cubic.stopAction();
return;
}
}
}
else
{
_cubic.stopAction();
return;
}
}
if (Rnd.get(1, 100) < _chance)
{
Skill skill = null;
for (Skill sk : _cubic.getSkills())
{
if ((sk.getId() == L2CubicInstance.SKILL_KNIGHT_CUBIC) || (sk.getId() == L2CubicInstance.SKILL_GUARDIAN_CUBIC))
{
skill = sk;
break;
}
}
final L2Character owner = _cubic.getOwner();
if (skill != null)
{
skill.activateSkill(owner, owner);
owner.broadcastPacket(new MagicSkillUse(owner, owner, skill.getId(), skill.getLevel(), 0, 0));
// The cubic has done an action, increase the current count
_currentCount.incrementAndGet();
}
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "", e);
}
}
}

View File

@ -18,6 +18,7 @@
*/
package com.l2jserver.gameserver.model.actor.tasks.cubics;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -25,6 +26,7 @@ import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2CubicInstance;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jserver.util.Rnd;
/**
* Cubic heal task.
@ -34,6 +36,7 @@ public class CubicHeal implements Runnable
{
private static final Logger _log = Logger.getLogger(CubicHeal.class.getName());
private final L2CubicInstance _cubic;
private final AtomicInteger _currentCount = new AtomicInteger();
public CubicHeal(L2CubicInstance cubic)
{
@ -57,23 +60,104 @@ public class CubicHeal implements Runnable
return;
}
// The cubic has already reached its limit and it will stay idle until its duration ends.
if ((_cubic.getCubicMaxCount() > -1) && (_currentCount.get() >= _cubic.getCubicMaxCount()))
{
_cubic.stopAction();
return;
}
try
{
final Skill skill = _cubic.getSkills().stream().filter(s -> s.getId() == L2CubicInstance.SKILL_CUBIC_HEAL).findFirst().orElse(null);
if (skill == null)
Skill skill = null;
// Base chance 10% to use great skill
double chance = Rnd.get();
for (Skill sk : _cubic.getSkills())
{
return;
switch (sk.getId())
{
case L2CubicInstance.SKILL_CUBIC_HEAL:
case L2CubicInstance.SKILL_CUBIC_HEALER:
skill = sk;
break;
case L2CubicInstance.SKILL_BUFF_CUBIC_HEAL:
if (chance > 0.6)
{
skill = sk;
}
break;
case L2CubicInstance.SKILL_MIND_CUBIC_RECHARGE:
if ((chance > 0.2) && (chance <= 0.6))
{
skill = sk;
}
break;
case L2CubicInstance.SKILL_BUFF_CUBIC_GREAT_HEAL:
if ((chance > 0.1) && (chance <= 0.2))
{
skill = sk;
}
break;
case L2CubicInstance.SKILL_MIND_CUBIC_GREAT_RECHARGE:
if (chance <= 0.1)
{
skill = sk;
}
break;
}
if (skill != null)
{
break;
}
}
_cubic.cubicTargetForHeal();
final L2Character target = _cubic.getTarget();
if ((target != null) && !target.isDead())
if (skill != null)
{
if ((target.getMaxHp() - target.getCurrentHp()) > skill.getPower())
switch (skill.getId())
{
skill.activateSkill(_cubic, target);
_cubic.getOwner().broadcastPacket(new MagicSkillUse(_cubic.getOwner(), target, skill.getId(), skill.getLevel(), 0, 0));
case L2CubicInstance.SKILL_CUBIC_HEAL:
_cubic.cubicTargetForHeal();
final L2Character target = _cubic.getTarget();
if ((target != null) && !target.isDead())
{
if ((target.getMaxHp() - target.getCurrentHp()) > skill.getPower())
{
skill.activateSkill(_cubic.getOwner(), target);
_cubic.getOwner().broadcastPacket(new MagicSkillUse(_cubic.getOwner(), target, skill.getId(), skill.getLevel(), 0, 0));
// The cubic has done an action, increase the current count
_currentCount.incrementAndGet();
}
}
break;
case L2CubicInstance.SKILL_MIND_CUBIC_RECHARGE:
case L2CubicInstance.SKILL_MIND_CUBIC_GREAT_RECHARGE:
final L2Character owner = _cubic.getOwner();
if ((owner != null) && !owner.isDead())
{
if ((owner.getMaxMp() - owner.getCurrentMp()) > skill.getPower())
{
skill.activateSkill(owner, owner);
owner.broadcastPacket(new MagicSkillUse(owner, owner, skill.getId(), skill.getLevel(), 0, 0));
// The cubic has done an action, increase the current count
_currentCount.incrementAndGet();
}
}
break;
case L2CubicInstance.SKILL_CUBIC_HEALER:
case L2CubicInstance.SKILL_BUFF_CUBIC_HEAL:
case L2CubicInstance.SKILL_BUFF_CUBIC_GREAT_HEAL:
final L2Character _owner = _cubic.getOwner();
if ((_owner != null) && !_owner.isDead())
{
if ((_owner.getMaxHp() - _owner.getCurrentHp()) > skill.getPower())
{
skill.activateSkill(_owner, _owner);
_owner.broadcastPacket(new MagicSkillUse(_owner, _owner, skill.getId(), skill.getLevel(), 0, 0));
// The cubic has done an action, increase the current count
_currentCount.incrementAndGet();
}
}
break;
}
}
}