📄 l1mobskilluse.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.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import l1j.server.server.ActionCodes;
import l1j.server.server.IdFactory;
import l1j.server.server.datatables.MobSkillTable;
import l1j.server.server.datatables.NpcTable;
import l1j.server.server.datatables.SkillsTable;
import l1j.server.server.model.L1Attack;
import l1j.server.server.model.Instance.L1MonsterInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.Instance.L1PetInstance;
import l1j.server.server.model.Instance.L1SummonInstance;
import l1j.server.server.model.skill.L1SkillUse;
import l1j.server.server.serverpackets.S_DoActionGFX;
import l1j.server.server.serverpackets.S_NPCPack;
import l1j.server.server.serverpackets.S_SkillSound;
import l1j.server.server.templates.L1MobSkill;
import l1j.server.server.templates.L1Npc;
import l1j.server.server.templates.L1Skills;
public class L1MobSkillUse {
private static Logger _log = Logger
.getLogger(L1MobSkillUse.class.getName());
private L1MobSkill _mobSkillTemplate = null;
private L1NpcInstance _attacker = null;
private L1Character _target = null;
private Random _rnd = new Random();
private int _sleepTime = 0;
private int _skillUseCount[];
public L1MobSkillUse(L1NpcInstance npc) {
_sleepTime = 0;
_mobSkillTemplate = MobSkillTable.getInstance().getTemplate(
npc.getNpcTemplate().get_npcId());
if (_mobSkillTemplate == null) {
return;
}
_attacker = npc;
_skillUseCount = new int[getMobSkillTemplate().getSkillSize()];
}
private int getSkillUseCount(int idx) {
return _skillUseCount[idx];
}
private void skillUseCountUp(int idx) {
_skillUseCount[idx]++;
}
public void resetAllSkillUseCount() {
if (getMobSkillTemplate() == null) {
return;
}
for (int i = 0; i < getMobSkillTemplate().getSkillSize(); i++) {
_skillUseCount[i] = 0;
}
}
public int getSleepTime() {
return _sleepTime;
}
public void setSleepTime(int i) {
_sleepTime = i;
}
public L1MobSkill getMobSkillTemplate() {
return _mobSkillTemplate;
}
/*
* スキル攻撃 スキル攻撃可能ならばtrueを返す。 攻撃できなければ、falseを返し、通常攻撃を行う。
*/
public boolean skillUse(L1Character tg) {
if (_mobSkillTemplate == null) {
return false;
}
_target = tg;
int type;
type = getMobSkillTemplate().getType(0);
if (type == L1MobSkill.TYPE_NONE) {
return false;
}
int i = 0;
for (i = 0; i < getMobSkillTemplate().getSkillSize()
&& getMobSkillTemplate().getType(i) != L1MobSkill.TYPE_NONE; i++) {
// changeTargetが設定されている場合、ターゲットの入れ替え
int changeType = getMobSkillTemplate().getChangeTarget(i);
if (changeType > 0) {
_target = changeTarget(changeType, i);
} else {
// 設定されてない場合は本来のターゲットにする
_target = tg;
}
if (isSkillUseble(i) == false) {
continue;
}
type = getMobSkillTemplate().getType(i);
if (type == L1MobSkill.TYPE_PHYSICAL_ATTACK) {
// 物理攻撃
if (physicalAttack(i) == true) {
skillUseCountUp(i);
return true;
}
} else if (type == L1MobSkill.TYPE_MAGIC_ATTACK) {
// 魔法攻撃
if (magicAttack(i) == true) {
skillUseCountUp(i);
return true;
}
} else if (type == L1MobSkill.TYPE_SUMMON) {
// サモンする
if (summon(i) == true) {
skillUseCountUp(i);
return true;
}
} else if (type == L1MobSkill.TYPE_POLY) {
// 強制変身させる
if (poly(i) == true) {
skillUseCountUp(i);
return true;
}
}
}
return false;
}
private boolean summon(int idx) {
int summonId = getMobSkillTemplate().getSummon(idx);
int min = getMobSkillTemplate().getSummonMin(idx);
int max = getMobSkillTemplate().getSummonMax(idx);
int count = 0;
if (summonId == 0) {
return false;
}
count = _rnd.nextInt(max) + min;
mobspawn(summonId, count);
// 魔方陣の表示
_attacker.broadcastPacket(new S_SkillSound(_attacker.getId(), 761));
// 魔法を使う動作のエフェクト
S_DoActionGFX gfx = new S_DoActionGFX(_attacker.getId(),
ActionCodes.ACTION_SkillBuff);
_attacker.broadcastPacket(gfx);
_sleepTime = _attacker.getNpcTemplate().getSubMagicSpeed();
return true;
}
/*
* 15セル以内で射線が通るPCを指定したモンスターに強制変身させる。 対PCしか使えない。
*/
private boolean poly(int idx) {
int polyId = getMobSkillTemplate().getPolyId(idx);
boolean usePoly = false;
if (polyId == 0) {
return false;
}
for (L1PcInstance pc : L1World.getInstance()
.getVisiblePlayer(_attacker)) {
if (pc.isDead()) { // 死亡している
continue;
}
if (pc.isGhost()) {
continue;
}
if (pc.isGmInvis()) {
continue;
}
if (_attacker.glanceCheck(pc.getX(), pc.getY()) == false) {
continue; // 射線が通らない
}
int npcId = _attacker.getNpcTemplate().get_npcId();
switch (npcId) {
case 81082: // ヤヒの場合
pc.getInventory().takeoffEquip(945); // 牛のpolyIdで装備を全部外す。
break;
default:
break;
}
L1PolyMorph.doPoly(pc, polyId, 1800, L1PolyMorph.MORPH_BY_NPC);
usePoly = true;
}
if (usePoly) {
// 変身させた場合、オレンジの柱を表示する。
for (L1PcInstance pc : L1World.getInstance()
.getVisiblePlayer(_attacker)) {
pc.sendPackets(new S_SkillSound(pc.getId(), 230));
pc.broadcastPacket(new S_SkillSound(pc.getId(), 230));
break;
}
// 魔法を使う動作のエフェクト
S_DoActionGFX gfx = new S_DoActionGFX(_attacker.getId(),
ActionCodes.ACTION_SkillBuff);
_attacker.broadcastPacket(gfx);
_sleepTime = _attacker.getNpcTemplate().getSubMagicSpeed();
}
return usePoly;
}
private boolean magicAttack(int idx) {
L1SkillUse skillUse = new L1SkillUse();
int skillid = getMobSkillTemplate().getSkillId(idx);
boolean canUseSkill = false;
if (skillid > 0) {
canUseSkill = skillUse.checkUseSkill(null, skillid,
_target.getId(), _target.getX(), _target.getY(), null, 0,
L1SkillUse.TYPE_NORMAL, _attacker);
}
if (canUseSkill == true) {
if (getMobSkillTemplate().getLeverage(idx) > 0) {
skillUse.setLeverage(getMobSkillTemplate().getLeverage(idx));
}
skillUse.handleCommands(null, skillid, _target.getId(), _target
.getX(), _target.getX(), null, 0, L1SkillUse.TYPE_NORMAL,
_attacker);
// 使用スキルによるsleepTimeの設定
L1Skills skill = SkillsTable.getInstance().getTemplate(skillid);
if (skill.getTarget().equals("attack") && skillid != 18) { // 有方向魔法
_sleepTime = _attacker.getNpcTemplate().getAtkMagicSpeed();
} else { // 無方向魔法
_sleepTime = _attacker.getNpcTemplate().getSubMagicSpeed();
}
return true;
}
return false;
}
/*
* 物理攻撃
*/
private boolean physicalAttack(int idx) {
Map<Integer, Integer> targetList = new ConcurrentHashMap<Integer, Integer>();
int areaWidth = getMobSkillTemplate().getAreaWidth(idx);
int areaHeight = getMobSkillTemplate().getAreaHeight(idx);
int range = getMobSkillTemplate().getRange(idx);
int actId = getMobSkillTemplate().getActid(idx);
int gfxId = getMobSkillTemplate().getGfxid(idx);
// レンジ外
if (_attacker.getLocation().getTileLineDistance(_target.getLocation()) > range) {
return false;
}
// 障害物がある場合攻撃不可能
if (!_attacker.glanceCheck(_target.getX(), _target.getY())) {
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -