📄 l1attack.java
字号:
_targetY));
_pc.broadcastPacket(new S_UseArrowSkill(_pc, 0, 66,
_targetX, _targetY));
_pc.getInventory().removeItem(_arrow, 1);
} else if (_weaponId == 190) { // 矢が無くてサイハの場合
_pc.sendPackets(new S_UseArrowSkill(_pc, 0, 2349, _targetX,
_targetY));
_pc.broadcastPacket(new S_UseArrowSkill(_pc, 0, 2349,
_targetX, _targetY));
}
} else if (_weaponType == 62 && _sting != null) { // ガントレット
calcOrbit(_pc.getX(), _pc.getY(), _pc.getHeading()); // 軌道を計算
_pc.sendPackets(new S_UseArrowSkill(_pc, 0, 2989, _targetX,
_targetY));
_pc.broadcastPacket(new S_UseArrowSkill(_pc, 0, 2989, _targetX,
_targetY));
_pc.getInventory().removeItem(_sting, 1);
} else {
if (_targetId > 0) {
_pc.sendPackets(new S_AttackMissPacket(_pc, _targetId));
_pc.broadcastPacket(new S_AttackMissPacket(_pc, _targetId));
} else {
_pc.sendPackets(new S_AttackStatus(_pc, 0,
ActionCodes.ACTION_Attack));
_pc.broadcastPacket(new S_AttackStatus(_pc, 0,
ActionCodes.ACTION_Attack));
}
}
}
}
// ●●●● NPCの攻撃モーション送信 ●●●●
private void actionNpc() {
int _npcObjectId = _npc.getId();
int bowActId = 0;
int actId = 0;
_npc.setHeading(_npc.targetDirection(_targetX, _targetY)); // 向きのセット
// ターゲットとの距離が2以上あれば遠距離攻撃
boolean isLongRange = (_npc.getLocation().getTileLineDistance(
new Point(_targetX, _targetY)) > 1);
bowActId = _npc.getNpcTemplate().getBowActId();
if (getActId() > 0) {
actId = getActId();
} else {
actId = ActionCodes.ACTION_Attack;
}
if (_isHit) {
// 距離が2以上、攻撃者の弓のアクションIDがある場合は遠攻撃
if (isLongRange && bowActId > 0) {
_npc.broadcastPacket(new S_UseArrowSkill(_npc, _targetId,
bowActId, _targetX, _targetY));
} else {
if (getGfxId() > 0) {
_npc
.broadcastPacket(new S_UseAttackSkill(_target,
_npcObjectId, getGfxId(), _targetX,
_targetY, actId));
_target.broadcastPacketExceptTargetSight(new S_DoActionGFX(
_targetId, ActionCodes.ACTION_Damage), _npc);
} else {
_npc.broadcastPacket(new S_AttackPacket(_target,
_npcObjectId, actId));
_target.broadcastPacketExceptTargetSight(new S_DoActionGFX(
_targetId, ActionCodes.ACTION_Damage), _npc);
}
}
} else {
// 距離が2以上、攻撃者の弓のアクションIDがある場合は遠攻撃
if (isLongRange && bowActId > 0) {
_npc.broadcastPacket(new S_UseArrowSkill(_npc, 0, bowActId,
_targetX, _targetY));
} else {
if (getGfxId() > 0) {
_npc.broadcastPacket(new S_UseAttackSkill(_target,
_npcObjectId, getGfxId(), _targetX, _targetY,
actId, 0));
} else {
_npc.broadcastPacket(new S_AttackMissPacket(_npc,
_targetId, actId));
}
}
}
}
// 飛び道具(矢、スティング)がミスだったときの軌道を計算
public void calcOrbit(int cx, int cy, int head) // 起点X 起点Y 今向いてる方向
{
float dis_x = Math.abs(cx - _targetX); // X方向のターゲットまでの距離
float dis_y = Math.abs(cy - _targetY); // Y方向のターゲットまでの距離
float dis = Math.max(dis_x, dis_y); // ターゲットまでの距離
float avg_x = 0;
float avg_y = 0;
if (dis == 0) { // 目標と同じ位置なら向いてる方向へ真っ直ぐ
if (head == 1) {
avg_x = 1;
avg_y = -1;
} else if (head == 2) {
avg_x = 1;
avg_y = 0;
} else if (head == 3) {
avg_x = 1;
avg_y = 1;
} else if (head == 4) {
avg_x = 0;
avg_y = 1;
} else if (head == 5) {
avg_x = -1;
avg_y = 1;
} else if (head == 6) {
avg_x = -1;
avg_y = 0;
} else if (head == 7) {
avg_x = -1;
avg_y = -1;
} else if (head == 0) {
avg_x = 0;
avg_y = -1;
}
} else {
avg_x = dis_x / dis;
avg_y = dis_y / dis;
}
int add_x = (int) Math.floor((avg_x * 15) + 0.59f); // 上下左右がちょっと優先な丸め
int add_y = (int) Math.floor((avg_y * 15) + 0.59f); // 上下左右がちょっと優先な丸め
if (cx > _targetX) {
add_x *= -1;
}
if (cy > _targetY) {
add_y *= -1;
}
_targetX = _targetX + add_x;
_targetY = _targetY + add_y;
}
/* ■■■■■■■■■■■■■■■ 計算結果反映 ■■■■■■■■■■■■■■■ */
public void commit() {
if (_isHit) {
if (_calcType == PC_PC || _calcType == NPC_PC) {
commitPc();
} else if (_calcType == PC_NPC || _calcType == NPC_NPC) {
commitNpc();
}
}
// ダメージ値及び命中率確認用メッセージ
if (!Config.ALT_ATKMSG) {
return;
}
if (Config.ALT_ATKMSG) {
if ((_calcType == PC_PC || _calcType == PC_NPC) && !_pc.isGm()) {
return;
}
if ((_calcType == PC_PC || _calcType == NPC_PC)
&& !_targetPc.isGm()) {
return;
}
}
String msg0 = "";
String msg1 = " 造成 ";
String msg2 = "";
String msg3 = "";
String msg4 = "";
if (_calcType == PC_PC || _calcType == PC_NPC) { // アタッカーがPCの場合
msg0 = _pc.getName();
} else if (_calcType == NPC_PC) { // アタッカーがNPCの場合
msg0 = _npc.getName();
}
if (_calcType == NPC_PC || _calcType == PC_PC) { // ターゲットがPCの場合
msg4 = _targetPc.getName();
msg2 = " 命中率 " + _hitRate + "% THP" + _targetPc.getCurrentHp();
} else if (_calcType == PC_NPC) { // ターゲットがNPCの場合
msg4 = _targetNpc.getName();
msg2 = " 命中率 " + _hitRate + "% 怪物目前剩餘" + _targetNpc.getCurrentHp();
}
msg3 = _isHit ? _damage + "傷害值" : "攻擊失敗";
if (_calcType == PC_PC || _calcType == PC_NPC) { // アタッカーがPCの場合
_pc.sendPackets(new S_ServerMessage(166, msg0, msg1, msg2, msg3,
msg4)); // \f1%0が%4%1%3 %2
}
if (_calcType == NPC_PC || _calcType == PC_PC) { // ターゲットがPCの場合
_targetPc.sendPackets(new S_ServerMessage(166, msg0, msg1, msg2,
msg3, msg4)); // \f1%0が%4%1%3 %2
}
}
// ●●●● プレイヤーに計算結果を反映 ●●●●
private void commitPc() {
if (_calcType == PC_PC) {
if (_drainMana > 0 && _targetPc.getCurrentMp() > 0) {
if (_drainMana > _targetPc.getCurrentMp()) {
_drainMana = _targetPc.getCurrentMp();
}
short newMp = (short) (_targetPc.getCurrentMp() - _drainMana);
_targetPc.setCurrentMp(newMp);
newMp = (short) (_pc.getCurrentMp() + _drainMana);
_pc.setCurrentMp(newMp);
}
if (_drainHp > 0) { // HP吸収による回復
short newHp = (short) (_pc.getCurrentHp() + _drainHp);
_pc.setCurrentHp(newHp);
}
damagePcWeaponDurability(); // 武器を損傷させる。
_targetPc.receiveDamage(_pc, _damage);
} else if (_calcType == NPC_PC) {
_targetPc.receiveDamage(_npc, _damage);
}
}
// ●●●● NPCに計算結果を反映 ●●●●
private void commitNpc() {
if (_calcType == PC_NPC) {
if (_drainMana > 0) {
int drainValue = _targetNpc.drainMana(_drainMana);
int newMp = _pc.getCurrentMp() + drainValue;
_pc.setCurrentMp(newMp);
if (drainValue > 0) {
int newMp2 = _targetNpc.getCurrentMp() - drainValue;
_targetNpc.setCurrentMpDirect(newMp2);
}
}
if (_drainHp > 0) { // HP吸収による回復
short newHp = (short) (_pc.getCurrentHp() + _drainHp);
_pc.setCurrentHp(newHp);
}
damageNpcWeaponDurability(); // 武器を損傷させる。
_targetNpc.receiveDamage(_pc, _damage);
} else if (_calcType == NPC_NPC) {
_targetNpc.receiveDamage(_npc, _damage);
}
}
/* ■■■■■■■■■■■■■■■ カウンターバリア ■■■■■■■■■■■■■■■ */
// ■■■■ カウンターバリア時の攻撃モーション送信 ■■■■
public void actionCounterBarrier() {
if (_calcType == PC_PC) {
_pc.setHeading(_pc.targetDirection(_targetX, _targetY)); // 向きのセット
_pc.sendPackets(new S_AttackMissPacket(_pc, _targetId));
_pc.broadcastPacket(new S_AttackMissPacket(_pc, _targetId));
_pc.sendPackets(new S_DoActionGFX(_pc.getId(),
ActionCodes.ACTION_Damage));
_pc.broadcastPacket(new S_DoActionGFX(_pc.getId(),
ActionCodes.ACTION_Damage));
} else if (_calcType == NPC_PC) {
int actId = 0;
_npc.setHeading(_npc.targetDirection(_targetX, _targetY)); // 向きのセット
if (getActId() > 0) {
actId = getActId();
} else {
actId = ActionCodes.ACTION_Attack;
}
if (getGfxId() > 0) {
_npc
.broadcastPacket(new S_UseAttackSkill(_target, _npc
.getId(), getGfxId(), _targetX, _targetY,
actId, 0));
} else {
_npc.broadcastPacket(new S_AttackMissPacket(_npc, _targetId,
actId));
}
_npc.broadcastPacket(new S_DoActionGFX(_npc.getId(),
ActionCodes.ACTION_Damage));
}
}
// ■■■■ 相手の攻撃に対してカウンターバリアが有效かを判別 ■■■■
public boolean isShortDistance() {
boolean isShortDistance = true;
if (_calcType == PC_PC) {
if (_weaponType == 20 || _weaponType == 62) { // 弓かガントレット
isShortDistance = false;
}
} else if (_calcType == NPC_PC) {
boolean isLongRange = (_npc.getLocation().getTileLineDistance(
new Point(_targetX, _targetY)) > 1);
int bowActId = _npc.getNpcTemplate().getBowActId();
// 距離が2以上、攻撃者の弓のアクションIDがある場合は遠攻撃
if (isLongRange && bowActId > 0) {
isShortDistance = false;
}
}
return isShortDistance;
}
// ■■■■ カウンターバリアのダメージを反映 ■■■■
public void commitCounterBarrier() {
int damage = calcCounterBarrierDamage();
if (damage == 0) {
return;
}
if (_calcType == PC_PC) {
_pc.receiveDamage(_targetPc, damage);
} else if (_calcType == NPC_PC) {
_npc.receiveDamage(_targetPc, damage);
}
}
// ●●●● カウンターバリアのダメージを算出 ●●●●
private int calcCounterBarrierDamage() {
int damage = 0;
L1ItemInstance weapon = null;
weapon = _targetPc.getWeapon();
if (weapon != null) {
if (weapon.getItem().getType() == 3) { // 両手剣
// (BIG最大ダメージ+強化数+追加ダメージ)*2
damage = (weapon.getItem().getDmgLarge() + weapon
.getEnchantLevel() + weapon.getItem()
.getDmgModifier()) * 2;
}
}
return damage;
}
/*
* 武器を損傷させる。 対NPCの場合、損傷確率は10%とする。祝福武器は3%とする。
*/
private void damageNpcWeaponDurability() {
int chance = 10;
int bchance = 3;
/*
* 損傷しないNPC、素手、損傷しない武器使用、SOF中の場合何もしない。
*/
if (_calcType != PC_NPC
|| _targetNpc.getNpcTemplate().is_hard() == false
|| _weaponType == 0 || weapon.getItem().get_canbedmg() == 0
|| _pc.hasSkillEffect(SOUL_OF_FLAME)) {
return;
}
// 通常の武器呪われた武器
if ((_weaponBless == 1 || _weaponBless == 2)
&& ((_random.nextInt(100) + 1) < chance)) {
// \f1あなたの%0が損傷しました。
_pc.sendPackets(new S_ServerMessage(268, weapon.getLogName()));
_pc.getInventory().receiveDamage(weapon);
}
// 祝福された武器
if (_weaponBless == 0 && ((_random.nextInt(100) + 1) < bchance)) {
// \f1あなたの%0が損傷しました。
_pc.sendPackets(new S_ServerMessage(268, weapon.getLogName()));
_pc.getInventory().receiveDamage(weapon);
}
}
/*
* バウンスアタックにより武器を損傷させる。 バウンスアタックの損傷確率は10%
*/
private void damagePcWeaponDurability() {
// PvP以外、素手、弓、ガントトレット、相手がバウンスアタック未使用、SOF中の場合何もしない
if (_calcType != PC_PC || _weaponType == 0 || _weaponType == 20
|| _weaponType == 62
|| _targetPc.hasSkillEffect(BOUNCE_ATTACK) == false
|| _pc.hasSkillEffect(SOUL_OF_FLAME)) {
return;
}
if (_random.nextInt(100) + 1 <= 10) {
// \f1あなたの%0が損傷しました。
_pc.sendPackets(new S_ServerMessage(268, weapon.getLogName()));
_pc.getInventory().receiveDamage(weapon);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -