📄 l1attack.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;
import java.util.Random;
import java.util.logging.Logger;
import l1j.server.Config;
import l1j.server.server.ActionCodes;
import l1j.server.server.WarTimeController;
import l1j.server.server.model.Instance.L1DollInstance;
import l1j.server.server.model.Instance.L1ItemInstance;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.Instance.L1PetInstance;
import l1j.server.server.model.Instance.L1SummonInstance;
import l1j.server.server.model.gametime.L1GameTimeClock;
import l1j.server.server.model.poison.L1DamagePoison;
import l1j.server.server.model.poison.L1ParalysisPoison;
import l1j.server.server.model.poison.L1SilencePoison;
import l1j.server.server.serverpackets.S_AttackMissPacket;
import l1j.server.server.serverpackets.S_AttackPacket;
import l1j.server.server.serverpackets.S_AttackStatus;
import l1j.server.server.serverpackets.S_DoActionGFX;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.serverpackets.S_SkillSound;
import l1j.server.server.serverpackets.S_UseArrowSkill;
import l1j.server.server.serverpackets.S_UseAttackSkill;
import l1j.server.server.templates.L1Skills;
import l1j.server.server.types.Point;
import static l1j.server.server.model.skill.L1SkillId.*;
public class L1Attack {
private static l1j.eric.EricLogger _log = l1j.eric.EricLogger.getLogger2(L1Attack.class.getName());
private L1PcInstance _pc = null;
private L1Character _target = null;
private L1PcInstance _targetPc = null;
private L1NpcInstance _npc = null;
private L1NpcInstance _targetNpc = null;
private final int _targetId;
private int _targetX;
private int _targetY;
private int _statusDamage = 0;
private static final Random _random = new Random();
private int _hitRate = 0;
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 boolean _isHit = false;
private int _damage = 0;
private int _drainMana = 0;
private int _drainHp = 0;
private int _attckGrfxId = 0;
private int _attckActId = 0;
// 攻撃者がプレイヤーの場合の武器情報
private L1ItemInstance weapon = null;
private int _weaponId = 0;
private int _weaponType = 0;
private int _weaponType2 = 0;
private int _weaponAddHit = 0;
private int _weaponAddDmg = 0;
private int _weaponSmall = 0;
private int _weaponLarge = 0;
private int _weaponBless = 1;
private int _weaponEnchant = 0;
private int _weaponMaterial = 0;
private int _weaponDoubleDmgChance = 0;
private L1ItemInstance _arrow = null;
private L1ItemInstance _sting = null;
private int _leverage = 10; // 1/10倍で表現する。
public void setLeverage(int i) {
_leverage = i;
}
private int getLeverage() {
return _leverage;
}
// 攻撃者がプレイヤーの場合のステータスによる補正
// private static final int[] strHit = { -2, -2, -2, -2, -2, -2, -2, -2, -2,
// -2, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9,
// 9, 10, 10, 11, 11, 12, 12, 13, 13, 14 };
// private static final int[] dexHit = { -2, -2, -2, -2, -2, -2, -2, -2, -2,
// -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
// 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14 };
/*
* private static final int[] strHit = { -2, -2, -2, -2, -2, -2, -2, // 0~7まで
* -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, // 8~26まで 7, 7, 7,
* 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, // 27~44まで 13, 13, 13,
* 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17}; // 45~59まで
*
* private static final int[] dexHit = { -2, -2, -2, -2, -2, -2, -1, -1, 0, 0, //
* 1~10まで 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, //
* 11~30まで 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, //
* 31~45まで 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46 }; //
* 46~60まで
*
* private static final int[] strDmg = new int[128];
*
* static { // STRダメージ補正 int dmg = -6; for (int str = 0; str <= 22; str++) { //
* 0~22は2毎に+1 if (str % 2 == 1) { dmg++; } strDmg[str] = dmg; } for (int str =
* 23; str <= 28; str++) { // 23~28は3毎に+1 if (str % 3 == 2) { dmg++; }
* strDmg[str] = dmg; } for (int str = 29; str <= 32; str++) { // 29~32は2毎に+1 if
* (str % 2 == 1) { dmg++; } strDmg[str] = dmg; } for (int str = 33; str <= 39;
* str++) { // 33~39は1毎に+1 dmg++; strDmg[str] = dmg; } for (int str = 40; str <=
* 46; str++) { // 40~46は1毎に+2 dmg += 2; strDmg[str] = dmg; } for (int str = 47;
* str <= 127; str++) { // 47~127は1毎に+1 dmg++; strDmg[str] = dmg; } }
*
* private static final int[] dexDmg = new int[128];
*
* static { // DEXダメージ補正 for (int dex = 0; dex <= 14; dex++) { // 0~14は0
* dexDmg[dex] = 0; } dexDmg[15] = 1; dexDmg[16] = 2; dexDmg[17] = 3; dexDmg[18] =
* 4; dexDmg[19] = 4; dexDmg[20] = 4; dexDmg[21] = 5; dexDmg[22] = 5; dexDmg[23] =
* 5; int dmg = 5; for (int dex = 24; dex <= 127; dex++) { // 24~127は1毎に+1
* dmg++; dexDmg[dex] = dmg; } }
*/
private static final int[] strHit = { -2, -2, -2, -2, -2, -2, -2, // 0~7まで
-2, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, // 8~26まで
7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, // 27~44まで
13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17}; // 45~59まで
private static final int[] dexHit = { -2, -2, -2, -2, -2, -2, -1, -1, 0, 0, // 1~10まで
1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, // 11~30まで
17, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, // 31~45まで
23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28 }; // 46~60まで
private static final int[] strDmg = new int[128];
static {
// STRダメージ補正
int dmg = -6;
for (int str = 0; str <= 22; str++) { // 0~22は2毎に+1
if (str % 2 == 1) {
dmg++;
}
strDmg[str] = dmg;
}
for (int str = 23; str <= 28; str++) { // 23~28は3毎に+1
if (str % 3 == 2) {
dmg++;
}
strDmg[str] = dmg;
}
for (int str = 29; str <= 32; str++) { // 29~32は2毎に+1
if (str % 2 == 1) {
dmg++;
}
strDmg[str] = dmg;
}
for (int str = 33; str <= 34; str++) { // 33~34は1毎に+1
dmg++;
strDmg[str] = dmg;
}
for (int str = 35; str <= 127; str++) { // 35~127は4毎に+1
if (str % 4 == 1) {
dmg++;
}
strDmg[str] = dmg;
}
}
private static final int[] dexDmg = new int[128];
static {
// DEXダメージ補正
for (int dex = 0; dex <= 14; dex++) {
// 0~14は0
dexDmg[dex] = 0;
}
dexDmg[15] = 1;
dexDmg[16] = 2;
dexDmg[17] = 3;
dexDmg[18] = 4;
dexDmg[19] = 4;
dexDmg[20] = 4;
dexDmg[21] = 5;
dexDmg[22] = 5;
dexDmg[23] = 5;
int dmg = 5;
for (int dex = 24; dex <= 35; dex++) { // 24~35は3毎に+1
if (dex % 3 == 1) {
dmg++;
}
dexDmg[dex] = dmg;
}
for (int dex = 36; dex <= 127; dex++) { // 36~127は4毎に1
if (dex % 4 == 1) {
dmg++;
}
dexDmg[dex] = dmg;
}
}
public void setActId(int actId) {
_attckActId = actId;
}
public void setGfxId(int gfxId) {
_attckGrfxId = gfxId;
}
public int getActId() {
return _attckActId;
}
public int getGfxId() {
return _attckGrfxId;
}
public L1Attack(L1Character attacker, L1Character target) {
if (attacker instanceof L1PcInstance) {
_pc = (L1PcInstance) attacker;
if (target instanceof L1PcInstance) {
_targetPc = (L1PcInstance) target;
_calcType = PC_PC;
} else if (target instanceof L1NpcInstance) {
_targetNpc = (L1NpcInstance) target;
_calcType = PC_NPC;
}
// 武器情報の取得
weapon = _pc.getWeapon();
if (weapon != null) {
_weaponId = weapon.getItem().getItemId();
_weaponType = weapon.getItem().getType1();
_weaponType2 = weapon.getItem().getType();
_weaponAddHit = weapon.getItem().getHitModifier()
+ weapon.getHitByMagic();
_weaponAddDmg = weapon.getItem().getDmgModifier()
+ weapon.getDmgByMagic();
_weaponSmall = weapon.getItem().getDmgSmall();
_weaponLarge = weapon.getItem().getDmgLarge();
_weaponBless = weapon.getItem().getBless();
if (_weaponType != 20 && _weaponType != 62) {
_weaponEnchant = weapon.getEnchantLevel()
- weapon.get_durability(); // 損傷分マイナス
} else {
_weaponEnchant = weapon.getEnchantLevel();
}
_weaponMaterial = weapon.getItem().getMaterial();
if (_weaponType == 20) { // アローの取得
_arrow = _pc.getInventory().getArrow();
if (_arrow != null) {
_weaponBless = _arrow.getItem().getBless();
_weaponMaterial = _arrow.getItem().getMaterial();
}
}
if (_weaponType == 62) { // スティングの取得
_sting = _pc.getInventory().getSting();
if (_sting != null) {
_weaponBless = _sting.getItem().getBless();
_weaponMaterial = _sting.getItem().getMaterial();
}
}
_weaponDoubleDmgChance = weapon.getItem().getDoubleDmgChance();
}
// ステータスによる追加ダメージ補正
if (_weaponType == 20) { // 弓の場合はDEX値参照
_statusDamage = dexDmg[_pc.getDex()];
} else { // それ以外はSTR値参照
_statusDamage = strDmg[_pc.getStr()];
}
} else if (attacker instanceof L1NpcInstance) {
_npc = (L1NpcInstance) attacker;
if (target instanceof L1PcInstance) {
_targetPc = (L1PcInstance) target;
_calcType = NPC_PC;
} else if (target instanceof L1NpcInstance) {
_targetNpc = (L1NpcInstance) target;
_calcType = NPC_NPC;
}
}
_target = target;
_targetId = target.getId();
_targetX = target.getX();
_targetY = target.getY();
}
/* ■■■■■■■■■■■■■■■■ 命中判定 ■■■■■■■■■■■■■■■■ */
public boolean calcHit() {
if (_calcType == PC_PC || _calcType == PC_NPC) {
if (_weaponType == 20 && _weaponId != 190 && _arrow == null) {
_isHit = false; // 矢がない場合はミス
} else if (_weaponType == 62 && _sting == null) {
_isHit = false; // スティングがない場合はミス
} else if (!_pc.glanceCheck(_targetX, _targetY)) {
_isHit = false; // 攻撃者がプレイヤーの場合は障害物判定
} else if (_weaponId == 247 || _weaponId == 248
|| _weaponId == 249) {
_isHit = false; // 試練の剣B~C 攻撃無效
} else if (_calcType == PC_PC) {
_isHit = calcPcPcHit();
} else if (_calcType == PC_NPC) {
_isHit = calcPcNpcHit();
}
} else if (_calcType == NPC_PC) {
_isHit = calcNpcPcHit();
} else if (_calcType == NPC_NPC) {
_isHit = calcNpcNpcHit();
}
return _isHit;
}
// ●●●● プレイヤー から プレイヤー への命中判定 ●●●●
/*
* PCへの命中率 =(PCのLv+クラス補正+STR補正+DEX補正+武器補正+DAIの枚数/2+魔法補正)×0.68-10
* これで算出された数値は自分が最大命中(95%)を与える事のできる相手側PCのAC そこから相手側PCのACが1良くなる毎に自命中率から1引いていく
* 最小命中率5% 最大命中率95%
*/
private boolean calcPcPcHit() {
final int MIN_HITRATE = 5;
_hitRate = _pc.getLevel();
if (_pc.getStr() > 39) {
_hitRate += strHit[39];
} else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -