📄 l1skilluse.java
字号:
/*
* 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.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package l1j.server.server.model.skill;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import l1j.server.Config;
import l1j.server.server.ActionCodes;
import l1j.server.server.datatables.NpcTable;
import l1j.server.server.datatables.PolyTable;
import l1j.server.server.datatables.SkillsTable;
import l1j.server.server.model.L1Awake;
import l1j.server.server.model.L1CastleLocation;
import l1j.server.server.model.L1Character;
import l1j.server.server.model.L1CurseParalysis;
import l1j.server.server.model.L1EffectSpawn;
import l1j.server.server.model.L1Location;
import l1j.server.server.model.L1Magic;
import l1j.server.server.model.L1Object;
import l1j.server.server.model.L1PcInventory;
import l1j.server.server.model.L1PinkName;
import l1j.server.server.model.L1PolyMorph;
import l1j.server.server.model.L1Teleport;
import l1j.server.server.model.L1War;
import l1j.server.server.model.L1World;
import l1j.server.server.model.Instance.*;
import l1j.server.server.model.poison.L1DamagePoison;
import l1j.server.server.model.trap.L1WorldTraps;
import l1j.server.server.serverpackets.S_ChangeHeading;
import l1j.server.server.serverpackets.S_ChangeName;
import l1j.server.server.serverpackets.S_ChangeShape;
import l1j.server.server.serverpackets.S_CharVisualUpdate;
import l1j.server.server.serverpackets.S_ChatPacket;
import l1j.server.server.serverpackets.S_CurseBlind;
import l1j.server.server.serverpackets.S_RemoveObject;
import l1j.server.server.serverpackets.S_Dexup;
import l1j.server.server.serverpackets.S_DoActionGFX;
import l1j.server.server.serverpackets.S_DoActionShop;
import l1j.server.server.serverpackets.S_HPUpdate;
import l1j.server.server.serverpackets.S_Invis;
import l1j.server.server.serverpackets.S_MPUpdate;
import l1j.server.server.serverpackets.S_Message_YN;
import l1j.server.server.serverpackets.S_NpcChatPacket;
import l1j.server.server.serverpackets.S_OwnCharAttrDef;
import l1j.server.server.serverpackets.S_OwnCharStatus;
import l1j.server.server.serverpackets.S_Paralysis;
import l1j.server.server.serverpackets.S_Poison;
import l1j.server.server.serverpackets.S_RangeSkill;
import l1j.server.server.serverpackets.S_SPMR;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.serverpackets.S_ShowPolyList;
import l1j.server.server.serverpackets.S_ShowSummonList;
import l1j.server.server.serverpackets.S_SkillBrave;
import l1j.server.server.serverpackets.S_SkillHaste;
import l1j.server.server.serverpackets.S_SkillIconAura;
import l1j.server.server.serverpackets.S_SkillIconGFX;
import l1j.server.server.serverpackets.S_SkillIconShield;
import l1j.server.server.serverpackets.S_SkillIconWindShackle;
import l1j.server.server.serverpackets.S_SkillSound;
import l1j.server.server.serverpackets.S_Sound;
import l1j.server.server.serverpackets.S_Strup;
import l1j.server.server.serverpackets.S_TrueTarget;
import l1j.server.server.serverpackets.S_UseAttackSkill;
import l1j.server.server.templates.L1BookMark;
import l1j.server.server.templates.L1Npc;
import l1j.server.server.templates.L1Skills;
import static l1j.server.server.model.skill.L1SkillId.*;
public class L1SkillUse {
public static final int TYPE_NORMAL = 0;
public static final int TYPE_LOGIN = 1;
public static final int TYPE_SPELLSC = 2;
public static final int TYPE_NPCBUFF = 3;
public static final int TYPE_GMBUFF = 4;
private L1Skills _skill;
private int _skillId;
private int _getBuffDuration;
private int _shockStunDuration;
private int _getBuffIconDuration;
private int _targetID;
private int _mpConsume = 0;
private int _hpConsume = 0;
private int _targetX = 0;
private int _targetY = 0;
private String _message = null;
private int _skillTime = 0;
private int _type = 0;
private boolean _isPK = false;
private int _bookmarkId = 0;
private int _itemobjid = 0;
private boolean _checkedUseSkill = false; // 事前チェック済みか
private int _leverage = 10; // 1/10倍なので10で1倍
private boolean _isFreeze = false;
private boolean _isCounterMagic = true;
private L1Character _user = null;
private L1Character _target = null;
private L1PcInstance _player = null;
private L1NpcInstance _npc = null;
private L1NpcInstance _targetNpc = null;
private int _calcType;
private static final int PC_PC = 1;
private static final int PC_NPC = 2;
private static final int NPC_PC = 3;
private static final int NPC_NPC = 4;
private ArrayList<TargetStatus> _targetList;
private static l1j.eric.EricLogger _log = l1j.eric.EricLogger.getLogger2(L1SkillUse.class.getName());
private static final int[] CAST_WITH_INVIS = { 1, 2, 3, 5, 8, 9, 12, 13,
14, 19, 21, 26, 31, 32, 35, 37, 42, 43, 44, 48, 49, 52, 54, 55, 57,
60, 61, 63, 67, 68, 69, 72, 73, 75, 78, 79, REDUCTION_ARMOR,
BOUNCE_ATTACK, SOLID_CARRIAGE, COUNTER_BARRIER, 97, 98, 99, 100,
101, 102, 104, 105, 106, 107, 109, 110, 111, 113, 114, 115, 116,
117, 118, 129, 130, 131, 133, 134, 137, 138, 146, 147, 148, 149,
150, 151, 155, 156, 158, 159, 163, 164, 165, 166, 168, 169, 170,
171, SOUL_OF_FLAME, ADDITIONAL_FIRE, DRAGON_SKIN, AWAKEN_ANTHARAS,
AWAKEN_FAFURION, AWAKEN_VALAKAS, MIRROR_IMAGE, ILLUSION_OGRE,
ILLUSION_LICH, PATIENCE, ILLUSION_DIA_GOLEM, INSIGHT,
ILLUSION_AVATAR };
private static final int[] EXCEPT_COUNTER_MAGIC = { 1, 2, 3, 5, 8, 9, 12,
13, 14, 19, 21, 26, 31, 32, 35, 37, 42, 43, 44, 48, 49, 52, 54, 55,
57, 60, 61, 63, 67, 68, 69, 72, 73, 75, 78, 79, SHOCK_STUN,
REDUCTION_ARMOR, BOUNCE_ATTACK, SOLID_CARRIAGE, COUNTER_BARRIER,
97, 98, 99, 100, 101, 102, 104, 105, 106, 107, 109, 110, 111, 113,
114, 115, 116, 117, 118, 129, 130, 131, 132, 134, 137, 138, 146,
147, 148, 149, 150, 151, 155, 156, 158, 159, 161, 163, 164, 165,
166, 168, 169, 170, 171, SOUL_OF_FLAME, ADDITIONAL_FIRE,
DRAGON_SKIN, AWAKEN_ANTHARAS, AWAKEN_FAFURION, AWAKEN_VALAKAS,
MIRROR_IMAGE, ILLUSION_OGRE, ILLUSION_LICH, PATIENCE, 10026, 10027,
ILLUSION_DIA_GOLEM, INSIGHT, ILLUSION_AVATAR, 10028, 10029 };
public L1SkillUse() {
}
private static class TargetStatus {
private L1Character _target = null;
private boolean _isAction = false; // ダメージモーションが発生するか?
private boolean _isSendStatus = false; // キャラクターステータスを送信するか?(ヒール、スローなど状態が変わるとき送る)
private boolean _isCalc = true; // ダメージや確率魔法の計算をする必要があるか?
public TargetStatus(L1Character _cha) {
_target = _cha;
}
public TargetStatus(L1Character _cha, boolean _flg) {
_isCalc = _flg;
}
public L1Character getTarget() {
return _target;
}
public boolean isCalc() {
return _isCalc;
}
public void isAction(boolean _flg) {
_isAction = _flg;
}
public boolean isAction() {
return _isAction;
}
public void isSendStatus(boolean _flg) {
_isSendStatus = _flg;
}
public boolean isSendStatus() {
return _isSendStatus;
}
}
/*
* 1/10倍で表現する。
*/
public void setLeverage(int i) {
_leverage = i;
}
public int getLeverage() {
return _leverage;
}
private boolean isCheckedUseSkill() {
return _checkedUseSkill;
}
private void setCheckedUseSkill(boolean flg) {
_checkedUseSkill = flg;
}
public boolean checkUseSkill(L1PcInstance player, int skillid,
int target_id, int x, int y, String message, int time, int type,
L1Character attacker) {
// 初期設定ここから
setCheckedUseSkill(true);
_targetList = new ArrayList<TargetStatus>(); // ターゲットリストの初期化
_skill = SkillsTable.getInstance().getTemplate(skillid);
_skillId = skillid;
_targetX = x;
_targetY = y;
_message = message;
_skillTime = time;
_type = type;
boolean checkedResult = true;
if (attacker == null) {
// pc
_player = player;
_user = _player;
} else {
// npc
_npc = (L1NpcInstance) attacker;
_user = _npc;
}
if (_skill.getTarget().equals("none")) {
_targetID = _user.getId();
_targetX = _user.getX();
_targetY = _user.getY();
} else {
_targetID = target_id;
}
if (type == TYPE_NORMAL) { // 通常の魔法使用時
checkedResult = isNormalSkillUsable();
} else if (type == TYPE_SPELLSC) { // スペルスクロール使用時
checkedResult = isSpellScrollUsable();
} else if (type == TYPE_NPCBUFF) {
checkedResult = true;
}
if (!checkedResult) {
return false;
}
// ファイアーウォール、ライフストリームは詠唱対象が座標
// キューブは詠唱者の座標に配置されるため例外
if (_skillId == FIRE_WALL || _skillId == LIFE_STREAM) {
return true;
}
L1Object l1object = L1World.getInstance().findObject(_targetID);
if (l1object instanceof L1ItemInstance) {
_log.fine("skill target item name: "
+ ((L1ItemInstance) l1object).getViewName());
// スキルターゲットが精霊の石になることがある。
// Linux環境で確認(Windowsでは未確認)
// 2008.5.4追記:地面のアイテムに魔法を使うとなる。継続してもエラーになるだけなのでreturn
return false;
}
if (_user instanceof L1PcInstance) {
if (l1object instanceof L1PcInstance) {
_calcType = PC_PC;
} else {
_calcType = PC_NPC;
_targetNpc = (L1NpcInstance) l1object;
}
} else if (_user instanceof L1NpcInstance) {
if (l1object instanceof L1PcInstance) {
_calcType = NPC_PC;
} else if (_skill.getTarget().equals("none")) {
_calcType = NPC_PC;
} else {
_calcType = NPC_NPC;
_targetNpc = (L1NpcInstance) l1object;
}
}
// テレポート、マステレポートは対象がブックマークID
if (_skillId == TELEPORT || _skillId == MASS_TELEPORT) {
_bookmarkId = target_id;
}
// 対象がアイテムのスキル
if (_skillId == CREATE_MAGICAL_WEAPON || _skillId == BRING_STONE
|| _skillId == BLESSED_ARMOR || _skillId == ENCHANT_WEAPON
|| _skillId == SHADOW_FANG) {
_itemobjid = target_id;
}
_target = (L1Character) l1object;
if (!(_target instanceof L1MonsterInstance)
&& _skill.getTarget().equals("attack")
&& _user.getId() != target_id) {
_isPK = true; // ターゲットがモンスター以外で攻撃系スキルで、自分以外の場合PKモードとする。
}
// 初期設定ここまで
// 事前チェック
if (!(l1object instanceof L1Character)) { // ターゲットがキャラクター以外の場合何もしない。
checkedResult = false;
}
makeTargetList(); // ターゲットの一覧を作成
if (_targetList.size() == 0 && (_user instanceof L1NpcInstance)) {
checkedResult = false;
}
// 事前チェックここまで
return checkedResult;
}
/**
* 通常のスキル使用時に使用者の状態からスキルが使用可能であるか判断する
*
* @return false スキルが使用不可能な状態である場合
*/
private boolean isNormalSkillUsable() {
// スキル使用者がPCの場合のチェック
if (_user instanceof L1PcInstance) {
L1PcInstance pc = (L1PcInstance) _user;
if (pc.isParalyzed()) { // 麻痺凍結状態か
return false;
}
if ((pc.isInvisble() || pc.isInvisDelay()) && !isInvisUsableSkill()) { // インビジ中に使用不可のスキル
return false;
}
if (pc.getInventory().getWeight240() >= 192) { // 重量オーバーならスキルを使用できない
pc.sendPackets(new S_ServerMessage(316));
return false;
}
int polyId = pc.getTempCharGfx();
L1PolyMorph poly = PolyTable.getInstance().getTemplate(polyId);
// 魔法が使えない変身
if (poly != null && !poly.canUseSkill()) {
pc.sendPackets(new S_ServerMessage(285)); // \f1その状態では魔法を使えません。
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -