📄 l1skilluse.java
字号:
int targetid = _target.getId();
if (_user instanceof L1MerchantInstance) {
_user.broadcastPacket(new S_SkillSound(targetid, castgfx));
return;
}
if (_targetList.size() == 0 && !(_skill.getTarget()
.equals("none"))) {
// ターゲット数が0で対象を指定するスキルの場合、魔法使用エフェクトだけ表示して終了
S_DoActionGFX gfx = new S_DoActionGFX(_user.getId(), _skill
.getActionId());
_user.broadcastPacket(gfx);
return;
}
if (_skill.getTarget().equals("attack") && _skillId != 18) {
if (_skill.getArea() == 0) { // 単体攻撃魔法
_user.broadcastPacket(new S_UseAttackSkill(_user, targetid,
castgfx, _targetX, _targetY, actionId));
_target.broadcastPacketExceptTargetSight(new S_DoActionGFX(
targetid, ActionCodes.ACTION_Damage), _user);
} else { // 有方向範囲攻撃魔法
L1Character[] cha = new L1Character[_targetList.size()];
int i = 0;
for (TargetStatus ts : _targetList) {
cha[i] = ts.getTarget();
cha[i].broadcastPacketExceptTargetSight(
new S_DoActionGFX(cha[i].getId(), ActionCodes
.ACTION_Damage), _user);
i++;
}
_user.broadcastPacket(new S_RangeSkill(_user, cha,
castgfx, actionId, S_RangeSkill.TYPE_DIR));
}
} else if (_skill.getTarget().equals("none") && _skill.getType() ==
L1Skills.TYPE_ATTACK) { // 無方向範囲攻撃魔法
L1Character[] cha = new L1Character[_targetList.size()];
int i = 0;
for (TargetStatus ts : _targetList) {
cha[i] = ts.getTarget();
i++;
}
_user.broadcastPacket(new S_RangeSkill(_user, cha, castgfx,
actionId, S_RangeSkill.TYPE_NODIR));
} else { // 補助魔法
// テレポート、マステレ、テレポートトゥマザー以外
if (_skillId != 5 && _skillId != 69 && _skillId != 131) {
// 魔法を使う動作のエフェクトは使用者だけ
S_DoActionGFX gfx = new S_DoActionGFX(_user.getId(), _skill
.getActionId());
_user.broadcastPacket(gfx);
_user.broadcastPacket(new S_SkillSound(targetid, castgfx));
}
}
}
}
// 重複できないスキルの削除
// 例:ファイア ウェポンとバーニングウェポンなど
private void deleteRepeatedSkills(L1Character cha) {
final int[][] repeatedSkills = {
// ホーリー ウェポン、エンチャント ウェポン、ブレス ウェポン, シャドウ ファング
// これらはL1ItemInstanceで管理
// { HOLY_WEAPON, ENCHANT_WEAPON, BLESS_WEAPON, SHADOW_FANG },
// ファイアー ウェポン、ウィンド ショット、ファイアー ブレス、ストーム アイ、バーニング ウェポン、ストーム ショット
{ FIRE_WEAPON, WIND_SHOT, FIRE_BLESS, STORM_EYE,
BURNING_WEAPON, STORM_SHOT },
// シールド、シャドウ アーマー、アース スキン、アースブレス、アイアン スキン
{ SHIELD, SHADOW_ARMOR, EARTH_SKIN, EARTH_BLESS, IRON_SKIN },
// ホーリー ウォーク、ムービング アクセレーション、ウィンド ウォーク、BP
{ HOLY_WALK, MOVING_ACCELERATION, WIND_WALK, STATUS_BRAVE,
STATUS_ELFBRAVE, STATUS_RIBRAVE },
// ヘイスト、グレーター ヘイスト、GP
{ HASTE, GREATER_HASTE, STATUS_HASTE },
// フィジカル エンチャント:DEX、ドレス デクスタリティー
{ PHYSICAL_ENCHANT_DEX, DRESS_DEXTERITY },
// フィジカル エンチャント:STR、ドレス マイティー
{ PHYSICAL_ENCHANT_STR, DRESS_MIGHTY },
// グローウィングオーラ、シャイニングオーラ
{ GLOWING_AURA, SHINING_AURA } };
for (int[] skills : repeatedSkills) {
for (int id : skills) {
if (id == _skillId) {
stopSkillList(cha, skills);
}
}
}
}
// 重複しているスキルを一旦すべて削除
private void stopSkillList(L1Character cha, int[] repeat_skill) {
for (int skillId : repeat_skill) {
if (skillId != _skillId) {
cha.removeSkillEffect(skillId);
}
}
}
// ディレイの設定
private void setDelay() {
if (_skill.getReuseDelay() > 0) {
L1SkillDelay.onSkillUse(_user, _skill.getReuseDelay());
}
}
private void runSkill() {
switch(_skillId){
case LIFE_STREAM:
L1EffectSpawn.getInstance().spawnEffect(81169,
_skill.getBuffDuration() * 1000,
_targetX, _targetY, _user.getMapId());
return;
case CUBE_IGNITION:
L1EffectSpawn.getInstance().spawnEffect(80149,
_skill.getBuffDuration() * 1000,
_targetX, _targetY, _user.getMapId(),
(L1PcInstance) _user, _skillId);
return;
case CUBE_QUAKE:
L1EffectSpawn.getInstance().spawnEffect(80150,
_skill.getBuffDuration() * 1000,
_targetX, _targetY, _user.getMapId(),
(L1PcInstance) _user, _skillId);
return;
case CUBE_SHOCK:
L1EffectSpawn.getInstance().spawnEffect(80151,
_skill.getBuffDuration() * 1000,
_targetX, _targetY, _user.getMapId(),
(L1PcInstance) _user, _skillId);
return;
case CUBE_BALANCE:
L1EffectSpawn.getInstance().spawnEffect(80152,
_skill.getBuffDuration() * 1000,
_targetX, _targetY, _user.getMapId(),
(L1PcInstance) _user, _skillId);
return;
}
if (_skillId == FIRE_WALL) { // ファイアーウォール
L1EffectSpawn.getInstance()
.doSpawnFireWall(_user, _targetX, _targetY);
return;
}
// カウンターマジック有/無效の設定
for (int skillId : EXCEPT_COUNTER_MAGIC) {
if (_skillId == skillId) {
_isCounterMagic = false; // カウンターマジック無效
break;
}
}
// NPCにショックスタンを使用させるとonActionでNullPointerExceptionが発生するため
// とりあえずPCが使用した時のみ
if (_skillId == SHOCK_STUN && _user instanceof L1PcInstance) {
_target.onAction(_player);
}
if (!isTargetCalc(_target)) {
return;
}
try {
TargetStatus ts = null;
L1Character cha = null;
int dmg = 0;
int drainMana = 0;
int heal = 0;
boolean isSuccess = false;
int undeadType = 0;
for (Iterator<TargetStatus> iter = _targetList.iterator(); iter
.hasNext();) {
ts = null;
cha = null;
dmg = 0;
heal = 0;
isSuccess = false;
undeadType = 0;
ts = iter.next();
cha = ts.getTarget();
if (!ts.isCalc() || !isTargetCalc(cha)) {
continue; // 計算する必要がない。
}
L1Magic _magic = new L1Magic(_user, cha);
_magic.setLeverage(getLeverage());
if (cha instanceof L1MonsterInstance) { // アンデットの判定
undeadType = ((L1MonsterInstance) cha).getNpcTemplate()
.get_undead();
}
// 確率系スキルで失敗が確定している場合
if ((_skill.getType() == L1Skills.TYPE_CURSE || _skill
.getType() == L1Skills.TYPE_PROBABILITY)
&& isTargetFailure(cha)) {
iter.remove();
continue;
}
if (cha instanceof L1PcInstance) { // ターゲットがPCの場合のみアイコンは送信する。
if (_skillTime == 0) {
_getBuffIconDuration = _skill.getBuffDuration(); // 效果時間
} else {
_getBuffIconDuration = _skillTime; // パラメータのtimeが0以外なら、效果時間として設定する
}
}
deleteRepeatedSkills(cha); // 重複したスキルの削除
if (_skill.getType() == L1Skills.TYPE_ATTACK
&& _user.getId() != cha.getId()) { // 攻撃系スキル&ターゲットが使用者以外であること。
if (isUseCounterMagic(cha)) { // カウンターマジックが発動した場合、リストから削除
iter.remove();
continue;
}
dmg = _magic.calcMagicDamage(_skillId);
cha.removeSkillEffect(ERASE_MAGIC); // イレースマジック中なら、攻撃魔法で解除
} else if (_skill.getType() == L1Skills.TYPE_CURSE
|| _skill.getType() == L1Skills.TYPE_PROBABILITY) { // 確率系スキル
isSuccess = _magic.calcProbabilityMagic(_skillId);
if (_skillId != ERASE_MAGIC) {
cha.removeSkillEffect(ERASE_MAGIC); // イレースマジック中なら、確率魔法で解除
}
if (_skillId != FOG_OF_SLEEPING) {
cha.removeSkillEffect(FOG_OF_SLEEPING); // フォグオブスリーピング中なら、確率魔法で解除
}
if (isSuccess) { // 成功したがカウンターマジックが発動した場合、リストから削除
if (isUseCounterMagic(cha)) { // カウンターマジックが発動したか
iter.remove();
continue;
}
} else { // 失敗した場合、リストから削除
if (_skillId == FOG_OF_SLEEPING
&& cha instanceof L1PcInstance) {
L1PcInstance pc = (L1PcInstance) cha;
pc.sendPackets(new S_ServerMessage(297)); // 軽いめまいを覚えました。
}
iter.remove();
continue;
}
} else if (_skill.getType() == L1Skills.TYPE_HEAL) { // 回復系スキル
// 回復量はマイナスダメージで表現
dmg = -1 * _magic.calcHealing(_skillId);
if (cha.hasSkillEffect(WATER_LIFE)) { // ウォーターライフ中は回復量2倍
dmg *= 2;
}
if (cha.hasSkillEffect(POLLUTE_WATER)) { // ポルートウォーター中は回復量1/2倍
dmg /= 2;
}
}
// ■■■■ 個別処理のあるスキルのみ書いてください。 ■■■■
// すでにスキルを使用済みの場合なにもしない
// ただしショックスタンは重ねがけ出来るため例外
if (cha.hasSkillEffect(_skillId) && _skillId != SHOCK_STUN) {
addMagicList(cha, true); // ターゲットに魔法の效果時間を上書き
if (_skillId != SHAPE_CHANGE) { // シェイプ チェンジは変身を上書き出来るため例外
continue;
}
}
// ●●●● PC、NPC両方效果のあるスキル ●●●●
if (_skillId == HASTE) { // ヘイスト
if (cha.getMoveSpeed() != 2) { // スロー中以外
if (cha instanceof L1PcInstance) {
L1PcInstance pc = (L1PcInstance) cha;
if (pc.getHasteItemEquipped() > 0) {
continue;
}
pc.setDrink(false);
pc.sendPackets(new S_SkillHaste(pc.getId(), 1,
_getBuffIconDuration));
}
cha.broadcastPacket(new S_SkillHaste(cha.getId(),
1, 0));
cha.setMoveSpeed(1);
} else { // スロー中
int skillNum = 0;
if (cha.hasSkillEffect(SLOW)) {
skillNum = SLOW;
} else if (cha.hasSkillEffect(MASS_SLOW)) {
skillNum = MASS_SLOW;
} else if (cha.hasSkillEffect(ENTANGLE)) {
skillNum = ENTANGLE;
}
if (skillNum != 0) {
cha.removeSkillEffect(skillNum);
cha.removeSkillEffect(HASTE);
cha.setMoveSpeed(0);
continue;
}
}
} else if (_skillId == CURE_POISON) {
cha.curePoison();
} else if (_skillId == REMOVE_CURSE) {
//防止玩家使用外掛在木乃尹,冰茅,衝暈,沉霧狀態底下的施法補血跟聖光 by thettt999
if (cha.hasSkillEffect(STATUS_CURSE_PARALYZED) //木乃尹狀態
||cha.hasSkillEffect(SHOCK_STUN) //衝暈
||cha.hasSkillEffect(FOG_OF_SLEEPING) //沉睡之霧
||cha.hasSkillEffect(ICE_LANCE)){ //冰茅
_player.sendPackets(new S_ServerMessage(285));//285 : \f1在此狀態下無法使用魔法。
return;
}
//~防止玩家使用外掛在木乃尹,冰茅,衝暈,沉霧狀態底下的施法補血跟聖光 by thettt999
cha.curePoison();
if (cha.hasSkillEffect(STATUS_CURSE_PARALYZING)
|| cha.hasSkillEffect(STATUS_CURSE_PARALYZED)) {
cha.cureParalaysis();
}
} else if (_skillId == RESURRECTION
|| _skillId == GREATER_RESURRECTION) { // リザレクション、グレーターリザレクション
if (cha instanceof L1PcInstance) {
L1PcInstance pc = (L1PcInstance) cha;
if (_player.getId() != pc.getId()) {
if (L1World.getInstance().getVisiblePlayer(pc,
0).size() > 0) {
for (L1PcInstance visiblePc : L1World
.getInstance().getVisiblePlayer(pc,
0)) {
if (!visiblePc.isDead()) {
// \f1その場所に他の人が立っているので復活させることができません。
_player.sendPackets(new S_ServerMessage(
592));
return;
}
}
}
if (pc.getCurrentHp() == 0 && pc.isDead()) {
if (pc.getMap().isUseResurrection()) {
if (_skillId == RESURRECTION) {
pc.setGres(false);
} else if (_skillId == GREATER_RESURRECTION) {
pc.setGres(true);
}
pc.setTempID(_player.getId());
pc.sendPackets(new S_Message_YN(322, "")); // また復活したいですか?(Y/N)
}
}
}
}
if (cha instanceof L1NpcInstance) {
if (!(cha instanceof L1TowerInstance)) {
L1NpcInstance npc = (L1NpcInstance) cha;
if (npc.getNpcTemplate().isCantResurrect()) {
return;
}
if (npc instanceof L1P
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -