/** * License * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR * COPYRIGHT LAW IS PROHIBITED. * * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE * MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. * */ package l1j.server.server.model; import l1j.server.server.utils.Random; import java.util.TimerTask; import java.util.concurrent.ScheduledFuture; import java.util.logging.Level; import java.util.logging.Logger; import l1j.server.server.ActionCodes; import l1j.server.server.GeneralThreadPool; import l1j.server.server.model.L1Character; import l1j.server.server.model.Instance.L1NpcInstance; import l1j.server.server.model.Instance.L1PcInstance; import l1j.server.server.serverpackets.S_DoActionGFX; import l1j.server.server.serverpackets.S_EffectLocation; import static l1j.server.server.model.skill.L1SkillId.*; public class L1Chaser extends TimerTask { private static Logger _log = Logger.getLogger(L1Chaser.class.getName()); private ScheduledFuture<?> _future = null; private int _timeCounter = 0; private final int _attr; private final int _gfxid; private final L1PcInstance _pc; private final L1Character _cha; public L1Chaser(L1PcInstance pc, L1Character cha, int attr, int gfxid) { _cha = cha; _pc = pc; _attr = attr; _gfxid = gfxid; } @Override public void run() { try { if (_cha == null || _cha.isDead()) { stop(); return; } attack(); _timeCounter++; if (_timeCounter >= 3) { stop(); return; } } catch (Throwable e) { _log.log(Level.WARNING, e.getLocalizedMessage(), e); } } public void begin() { // 効果時間が8秒のため、4秒毎のスキルの場合処理時間を考慮すると実際には1回しか効果が現れない // よって開始時間を0.9秒後に設定しておく _future = GeneralThreadPool.getInstance().scheduleAtFixedRate(this, 0, 1000); } public void stop() { if (_future != null) { _future.cancel(false); } } public void attack() { double damage = getDamage(_pc, _cha); if (_cha.getCurrentHp() - (int) damage <= 0 && _cha.getCurrentHp() != 1) { damage = _cha.getCurrentHp() - 1; } else if (_cha.getCurrentHp() == 1) { damage = 0; } S_EffectLocation packet = new S_EffectLocation(_cha.getX(), _cha.getY(), _gfxid); if (_pc.getWeapon() == null) { // 修正空手會出錯的問題 damage = 0; } else if (_pc.getWeapon().getItem().getItemId() == 265 || _pc.getWeapon().getItem().getItemId() == 266 || _pc.getWeapon().getItem().getItemId() == 267 || _pc.getWeapon().getItem().getItemId() == 268) { packet = new S_EffectLocation(_cha.getX(), _cha.getY(), 7025); } else if (_pc.getWeapon().getItem().getItemId() == 276 || _pc.getWeapon().getItem().getItemId() == 277) { packet = new S_EffectLocation(_cha.getX(), _cha.getY(), 7224); } else if (_pc.getWeapon().getItem().getItemId() == 304 || _pc.getWeapon().getItem().getItemId() == 307 || _pc.getWeapon().getItem().getItemId() == 308) { packet = new S_EffectLocation(_cha.getX(), _cha.getY(), 8150); } else if (_pc.getWeapon().getItem().getItemId() == 305 || _pc.getWeapon().getItem().getItemId() == 306 || _pc.getWeapon().getItem().getItemId() == 309) { packet = new S_EffectLocation(_cha.getX(), _cha.getY(), 8152); } else { // 更換為其他武器 附加特效傷害歸零 damage = 0; } _pc.sendPackets(packet); _pc.broadcastPacket(packet); if (_cha instanceof L1PcInstance) { L1PcInstance pc = (L1PcInstance) _cha; pc.sendPackets(new S_DoActionGFX(pc.getId(), ActionCodes.ACTION_Damage)); pc.broadcastPacket(new S_DoActionGFX(pc.getId(), ActionCodes.ACTION_Damage)); pc.receiveDamage(_pc, damage, false); } else if (_cha instanceof L1NpcInstance) { L1NpcInstance npc = (L1NpcInstance) _cha; npc.broadcastPacket(new S_DoActionGFX(npc.getId(), ActionCodes.ACTION_Damage)); npc.receiveDamage(_pc, (int) damage); } } public double getDamage(L1PcInstance pc, L1Character cha) { double dmg = 0; int spByItem = pc.getSp() - pc.getTrueSp(); int intel = pc.getInt(); int charaIntelligence = pc.getInt() + spByItem - 12; double coefficientA = 1.0 + 3.0 / 32.0 * charaIntelligence; if (coefficientA < 1) { coefficientA = 1.0; } double coefficientB = 0; if (intel > 18) { coefficientB = (intel + 2.0) / intel; } else if (intel <= 12) { coefficientB = 12.0 * 0.065; } else { coefficientB = intel * 0.065; } double coefficientC = 0; if (intel <= 12) { coefficientC = 12; } else { coefficientC = intel; } dmg = (Random.nextInt(6) + 1 + 7) * coefficientA * coefficientB / 10.5 * coefficientC * 2.0; dmg = L1WeaponSkill.calcDamageReduction(pc, cha, dmg, _attr); if (cha.hasSkillEffect(IMMUNE_TO_HARM)) { dmg /= 2.0; } return dmg; } }