Merged with released L2J-Unity files.

This commit is contained in:
mobiusdev
2016-06-12 01:34:09 +00:00
parent e003e87887
commit 635557f5da
18352 changed files with 3245113 additions and 2892959 deletions

View File

@@ -1,414 +1,552 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
/**
* Abnormal type enumerate.
* @author Zoey76
*/
public enum AbnormalType
{
ABNORMAL_INVINCIBILITY,
ABNORMAL_ITEM,
AB_HAWK_EYE,
ALL_ATTACK_DOWN,
ALL_REGEN_UP,
ALL_SPEED_DOWN,
ANESTHESIA,
ANTARAS_DEBUFF,
APELLA,
ARCHER_SPECIAL,
ARCHER_SPECIAL_I,
ARMOR_EARTH,
ARMOR_FIRE,
ARMOR_HOLY,
ARMOR_UNHOLY,
ARMOR_WATER,
ARMOR_WIND,
ARROW_RAIN,
ATTACK_SPEED_UP_BOW,
ATTACK_TIME_DOWN,
ATTACK_TIME_DOWN_SPECIAL,
ATTACK_TIME_UP,
ATTRIBUTE_POTION,
AVOID_DOWN,
AVOID_SKILL,
AVOID_UP,
AVOID_UP_SPECIAL,
CHANGE_BODY,
BERSERKER,
BETRAYAL_MARK,
BIG_BODY,
BIG_HEAD,
BLEEDING,
BLESS_THE_BLOOD,
BLOCK_RESURRECTION,
BLOCK_SHIELD_UP,
BLOCK_SPEED_UP,
BLOCK_TRANSFORM,
BLOOD_CONSTRACT,
BOT_PENALTY,
BR_EVENT_BUF1,
BR_EVENT_BUF10,
BR_EVENT_BUF2,
BR_EVENT_BUF3,
BR_EVENT_BUF5,
BR_EVENT_BUF6,
BR_EVENT_BUF7,
BUFF_QUEEN_OF_CAT,
BUFF_UNICORN_SERAPHIM,
CANCEL_PROB_DOWN,
CASTING_TIME_DOWN,
CASTING_TIME_UP,
CHANGE_CLASS,
CHEAP_MAGIC,
COMBINATION,
COUNTER_CRITICAL,
COUNTER_CRITICAL_TRIGGER,
COUNTER_SKILL,
CP_UP,
CRITICAL_DMG_DOWN,
CRITICAL_DMG_UP,
CRITICAL_POISON,
CRITICAL_PROB_DOWN,
CRITICAL_PROB_UP,
CURSE_LIFE_FLOW,
DAMAGE_AMPLIFY,
DANCE_DEFENCE_MOTION1,
DANCE_OF_ALIGNMENT,
DANCE_OF_AQUA_GUARD,
DANCE_OF_BERSERKER,
DANCE_OF_BLADESTORM,
DANCE_OF_CONCENTRATION,
DANCE_OF_EARTH_GUARD,
DANCE_OF_FIRE,
DANCE_OF_FURY,
DANCE_OF_INSPIRATION,
DANCE_OF_LIGHT,
DANCE_OF_MYSTIC,
DANCE_OF_PROTECTION,
DANCE_OF_SHADOW,
DANCE_OF_SIREN,
DANCE_OF_VAMPIRE,
DANCE_OF_WARRIOR,
DARK_SEED,
DD_RESIST,
DEATHWORM,
DEATH_CLACK,
DEATH_MARK,
DEATH_PENALTY,
DEBUFF_NIGHTSHADE,
DEBUFF_SHIELD,
DECREASE_WEIGHT_PENALTY,
DERANGEMENT,
DETECT_WEAKNESS,
DISARM,
DISBODY,
DITTY_BUFF,
DMG_SHIELD,
DOT_ATTR,
DOT_MP,
DRAGON_BUFF,
DRAGON_BREATH,
DUELIST_SPIRIT,
DWARF_ATTACK_BUFF,
DWARF_DEFENCE_BUFF,
ELEMENTAL_ARMOR,
ENERVATION,
ENTRY_FOR_GAME,
EVASION_BUFF,
EVENT_GAWI,
EVENT_SANTA_REWARD,
EVENT_TERRITORY,
EVENT_WIN,
EVIL_BLOOD,
EXPOSE_WEAK_POINT,
FATAL_POISON,
FINAL_SECRET,
FIRE_DOT,
FISHING_MASTERY_DOWN,
FLAME_HAWK,
FLY_AWAY,
FOCUS_DAGGER,
FORCE_MEDITATION,
FORCE_OF_DESTRUCTION,
FREEZING,
GHOST_PIERCING,
HEAL_EFFECT_DOWN,
HEAL_EFFECT_UP,
HEAL_POWER_UP,
HERO_BUFF,
HERO_DEBUFF,
HIDE,
HIT_DOWN,
HIT_UP,
HOLY_ATTACK,
HOT_GROUND,
HP_RECOVER,
HP_REGEN_DOWN,
HP_REGEN_UP,
IMPROVE_CRT_RATE_DMG_UP,
IMPROVE_HIT_DEFENCE_CRT_RATE_UP,
IMPROVE_HP_MP_UP,
IMPROVE_MA_MD_UP,
IMPROVE_PA_PD_UP,
IMPROVE_SHIELD_RATE_DEFENCE_UP,
IMPROVE_SPEED_AVOID_UP,
IMPROVE_VAMPIRIC_HASTE,
INSTINCT,
INVINCIBILITY,
IRON_SHIELD,
IRON_SHIELD_I,
KAMAEL_SPECIAL,
KNIGHT_AURA,
KNOCK_DOWN,
LIFE_FORCE_KAMAEL,
LIFE_FORCE_ORC,
LIFE_FORCE_OTHERS,
LIMIT,
MAGICAL_STANCE,
MAGIC_CRITICAL_UP,
MAJESTY,
MAXIMUM_ABILITY,
MAX_BREATH_UP,
MAX_HP_DOWN,
MAX_HP_UP,
MAX_HP_CP_UP,
MAX_MP_UP,
MA_DOWN,
MA_MD_UP,
MA_UP,
MA_UP_HERB,
MA_UP_SPECIAL,
MD_DOWN,
MD_UP,
MD_UP_ATTR,
MENTAL_IMPOVERISH,
METEOR,
MIGHT_MORTAL,
MIRAGE,
MIRAGE_TRAP,
MP_COST_DOWN,
MP_COST_UP,
MP_REGEN_UP,
MULTI_BUFF,
MULTI_BUFF_A,
MULTI_DEBUFF,
MULTI_DEBUFF_A,
MULTI_DEBUFF_B,
MULTI_DEBUFF_C,
MULTI_DEBUFF_D,
MULTI_DEBUFF_E,
MULTI_DEBUFF_F,
MULTI_DEBUFF_FIRE,
MULTI_DEBUFF_G,
MULTI_DEBUFF_HOLY,
MULTI_DEBUFF_SOUL,
MULTI_DEBUFF_UNHOLY,
MULTI_DEBUFF_WATER,
MULTI_DEBUFF_WIND,
NONE,
NORMAL_ATTACK_BLOCK,
OBLIVION,
PARALYZE,
PATIENCE,
PA_DOWN,
PA_PD_UP,
PA_UP,
PA_UP_HERB,
PA_UP_SPECIAL,
PD_DOWN,
PD_UP,
PD_UP_BOW,
PD_UP_SPECIAL,
PHYSICAL_STANCE,
PINCH,
PK_PROTECT,
POISON,
POLEARM_ATTACK,
POSSESSION,
POSSESSION_SPECIAL, // Used in High Five skills.
POTION_OF_GENESIS,
PRESERVE_ABNORMAL,
PROTECTION,
PUBLIC_SLOT,
PVP_DMG_DOWN,
PVP_WEAPON_BUFF,
PVP_WEAPON_DEBUFF,
RAGE_MIGHT,
REAL_TARGET,
RECHARGE_UP,
REDUCE_DROP_PENALTY,
REFLECT_ABNORMAL,
REFLECT_MAGIC_DD,
RESIST_BLEEDING,
RESIST_DEBUFF_DISPEL,
RESIST_DERANGEMENT,
RESIST_HOLY_UNHOLY,
RESIST_POISON,
RESIST_SHOCK,
RESIST_SPIRITLESS,
RESURRECTION_SPECIAL,
REUSE_DELAY_DOWN,
REUSE_DELAY_UP,
ROOT_MAGICALLY,
ROOT_PHYSICALLY,
SEED_OF_CRITICAL,
SEED_OF_KNIGHT,
SEIZURE_A,
SEIZURE_B,
SEIZURE_C,
SEIZURE_PENALTY,
SHIELD_DEFENCE_UP,
SHIELD_PROB_UP,
SIGNAL_A,
SIGNAL_B,
SIGNAL_C,
SIGNAL_D,
SIGNAL_E,
SILENCE,
SILENCE_ALL,
SILENCE_PHYSICAL,
SKILL_IGNORE,
SLEEP,
SNIPE,
SOA_BUFF1,
SOA_BUFF2,
SOA_BUFF3,
SONG_BATTLE_WHISPER,
SONG_OF_CHAMPION,
SONG_OF_EARTH,
SONG_OF_ELEMENTAL,
SONG_OF_FLAME_GUARD,
SONG_OF_HUNTER,
SONG_OF_INVOCATION,
SONG_OF_LIFE,
SONG_OF_MEDITATION,
SONG_OF_PURIFICATION,
SONG_OF_RENEWAL,
SONG_OF_STORM_GUARD,
SONG_OF_VENGEANCE,
SONG_OF_VITALITY,
SONG_OF_WARDING,
SONG_OF_WATER,
SONG_OF_WIND,
SONG_OF_WINDSTORM,
SPA_DISEASE_A,
SPA_DISEASE_B,
SPA_DISEASE_C,
SPA_DISEASE_D,
SPEED_DOWN,
SPEED_UP,
SPEED_UP_SPECIAL,
SPITE,
SPOIL_BOMB,
SSQ_TOWN_BLESSING,
SSQ_TOWN_CURSE,
STAR_FALL,
STEALTH,
STIGMA_A,
STIGMA_OF_SILEN,
STUN,
SUB_TRIGGER_CRT_RATE_UP,
SUB_TRIGGER_DEFENCE,
SUB_TRIGGER_HASTE,
SUB_TRIGGER_SPIRIT,
SUMMON_CONDITION,
TALISMAN,
TARGET_LOCK,
THIN_SKIN,
THRILL_FIGHT,
TIME_CHECK,
TOUCH_OF_DEATH,
TOUCH_OF_LIFE,
TRANSFER_DAMAGE,
TRANSFORM,
TRANSFORM_HANGOVER,
TRANSFORM_SCRIFICE,
TRANSFORM_SCRIFICE_P,
TURN_FLEE,
TURN_PASSIVE,
TURN_STONE,
T_CRT_DMG_DOWN,
T_CRT_DMG_UP,
T_CRT_RATE_UP,
ULTIMATE_BUFF,
ULTIMATE_DEBUFF,
VALAKAS_ITEM,
VAMPIRIC_ATTACK,
VAMPIRIC_ATTACK_SPECIAL,
VIBRATION,
VOTE,
VP_KEEP,
VP_UP,
WATCHER_GAZE,
WATER_DOT,
WEAK_CONSTITUTION,
WEAPON_MASTERY,
WILL,
WIND_DOT,
WP_CHANGE_EVENT,
HARMONY,
MELODY_HORN,
MELODY_DRUM,
MELODY_PIPE,
MELODY_GUITAR,
MELODY_HARP,
MELODY_LUTE,
PREV_SONATA,
DARING_SONATA,
REF_SONATA,
ELEMENTAL_RESISTANCE_ISS,
HOLY_ATTACK_RESISTANCE_ISS,
MENTAL_ATTACK_RESISTANCE_ISS,
SIGEL_AURA,
FEOH_STANCE,
YUL_STANCE,
RHYTHM_OF_CRITICAL,
RHYTHM_OF_MAGIC,
RHYTHM_OF_COMBAT,
RHYTHM_OF_FIGHTER,
RHYTHM_OF_REVENGE,
RHYTHM_OF_START,
RHYTHM_OF_MAGICIAN;
/**
* Get the enumerate for the given String.
* @param type the abnormal type to get
* @return the abnormal type
*/
public static AbnormalType getAbnormalType(String type)
{
try
{
return Enum.valueOf(AbnormalType.class, type);
}
catch (Exception e)
{
return NONE;
}
}
/**
* Verify if this enumerate is default.
* @return {@code true} if this enumerate is none, {@code false} otherwise
*/
public boolean isNone()
{
return this == NONE;
}
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.logging.Logger;
/**
* Abnormal type enumerate.
* @author Zoey76
*/
public enum AbnormalType
{
NONE(-1),
ABILITY_CHANGE(-1),
ABSORB(-1),
ACADEMY_UP(-1),
ANTI_SUMMON(-1),
ARCANE_PROTECTION(-1),
ARMOR_ELEMENT_ALL(-1),
ATTACK_TIME_DOWN_SPECIAL(-1),
AURA(-1),
AVOID_SKILL_SPECIAL(-1),
BARRIER(-1),
BATTLE_CRY(-1),
BATTLE_TOLERANCE(-1),
BIG_BODY_COMBINATION(-1),
BLESS_THE_BLOOD(-1),
BLOCK_ESCAPE(-1),
BLOCK_RESURRECTION(-1),
BLOCK_SHIELD_UP(-1),
BLOCK_SPEED_UP(-1),
BLOCK_TRANSFORM(-1),
BODY_DESTRUCTION(-1),
BOT_PENALTY(-1),
BR_EVENT_BUF1(-1),
BR_EVENT_BUF2(-1),
BR_EVENT_BUF3(-1),
BR_EVENT_BUF4(-1),
BR_EVENT_BUF6(-1),
BR_EVENT_BUF7(-1),
BRIGHTNESS_BLESS(-1),
BUFF_MENTEE1(-1),
BUFF_PCCAFE_EXP1(-1),
BUFF_SPECIAL_ATTACK(-1),
BUFF_SPECIAL_AURA(-1),
BUFF_SPECIAL_CLASS(-1),
BUFF_SPECIAL_CONDITION(-1),
BUFF_SPECIAL_CRITICAL(-1),
BUFF_SPECIAL_DEFENCE(-1),
BUFF_SPECIAL_HITAVOID(-1),
BUFF_SPECIAL_MOVE(-1),
BUFF_SPECIAL_MULTI(-1),
BUFF_TREE(-1),
CHANGEBODY(-1),
CLAN_ADVENT(-1),
CLAN_BOUNDARY(-1),
CLAN_FRIEND(-1),
CLAN_PRISON(-1),
CLASS_CHANGE(-1),
CONFUSION(-1),
COUNTER_CRITICAL(-1),
COUNTER_CRITICAL_TRIGGER(-1),
CRIPPLING_DANCE(-1),
CRITICAL_SPECIAL(-1),
CURIOUS_HOUSE(-1),
DAMAGE_AMPLIFY(-1),
DANCE_OF_BERSERKER(-1),
DC_MOD(-1),
DD_RESIST(-1),
DEATH_PENALTY_BLOCK(-1),
DEATH_PENALTY_GD(-1),
DEATHWORM(-1),
DEPORT(-1),
DITTY(-1),
DUAL_ATTACK_UP(-1),
DUAL_DEFENCE_UP(-1),
DUAL_DMG_SHIELD(-1),
DUAL_SKILL_UP(-1),
DWARF_ATTACK_BUFF(-1),
DWARF_DEFENCE_BUFF(-1),
ENCHANTER_MOD(-1),
ENERGY_OF_TOTEM_1(-1),
ENERGY_OF_TOTEM_2(-1),
ENERGY_OF_TOTEM_3(-1),
ENERGY_OF_TOTEM_4(-1),
EVENT_GAWI(-1),
EVENT_SANTA_REWARD(-1),
EVENT_TERRITORY(-1),
EVENT_WIN(-1),
EXP_BOTTLE(-1),
EXP_SPECIAL(-1),
FINAL_SECRET(-1),
FLAG_BUF(-1),
FLAG_DEBUF(-1),
FORCE_HP_UP(-1),
GREATER_SERVITOR_BUFF(-1),
HIDE(-1),
IMPROVE_HIT_DEFENCE_CRT_RATE_UP(-1),
INSTANT_EV_BUFF1(-1),
INSTANT_EV_BUFF6(-1),
INVINCIBILITY_SPECIAL(-1),
KALIE_BUFF(-1),
KNIGHT_AURA(-1),
KNIGHT_SHIELD(-1),
LIFE_FORCE_HEALER(-1),
LIFE_FORCE_HEALER_SELF(-1),
LUMIERE_BUFF(-1),
MARK_DEBUF_A(-1),
MARK_DEBUF_B(-1),
MARK_DEBUF_C(-1),
MARK_DEBUF_D(-1),
MARK_OF_LUMI(-1),
MARK_OF_WEAKNESS(-1),
MARK_OF_PLAGUE(-1),
MARK_OF_TRICK(-1),
MAX_HP_UP_K(-1),
MORALE_UP(-1),
MOTION_OF_DEFENCE(-1),
MOVEMENT(-1),
MP_SHIELD(-1),
MULTI_BUFF_A(-1),
MULTI_DEBUFF_A(-1),
MULTI_DEBUFF_B(-1),
MULTI_DEBUFF_C(-1),
MULTI_DEBUFF_D(-1),
MULTI_DEBUFF_E(-1),
MULTI_DEBUFF_F(-1),
MULTI_DEBUFF_G(-1),
NOCHAT(-1),
NOTICE_PORTAL(-1),
NPC_ATTACK1(-1),
NPC_ATTACK2(-1),
NPC_ATTACK3(-1),
NPC_FURY(-1),
NPC_MULTI_BUFF1(-1),
PATIENCE(-1),
PET_FURY(-1),
POSSESSION_SPECIAL(-1),
PVP_WEAPON_BUFF(-1),
PVP_WEAPON_DEBUFF(-1),
RACE_DARKELF1(-1),
RACE_DWAF1(-1),
RACE_ELF1(-1),
RACE_HUMAN1(-1),
RACE_KAMAEL1(-1),
RACE_ORC1(-1),
RACE_ORC2(-1),
REFLECT_MAGIC_DD(-1),
RESIST_DEATH(-1),
RHAPSODY(-1),
SACRIFICE(-1),
SEED_OF_CRITICAL(-1),
SEED_TALISMAN1(-1),
SHIELD_ATTACK(-1),
SHILLIEN_PROTECTION(-1),
SHOOTING_STANCE(-1),
SIGNAL_A(-1),
SIGNAL_B(-1),
SIGNAL_C(-1),
SIGNAL_D(-1),
SIGNAL_E(-1),
SKILL_IGNORE(-1),
SOA_BUFF1(-1),
SOA_BUFF2(-1),
SOA_BUFF3(-1),
SONG_OF_PURIFICATION(-1),
SONG_OF_THIEF(-1),
SONG_OF_WISDOM(-1),
SPECIAL_BERSERKER(-1),
SPECIAL_MOVE_UP(-1),
SPECIAL_RIDE(-1),
SPIRIT_SHARING(-1),
STAR_AGATHION_EXP_SP_BUFF1(-1),
STIGMA_A(-1),
STIGMA_OF_SILEN(-1),
STORM_SIGN(-1),
SUBSTITUTE_BUFF(-1),
SUMMONER_LINK(-1),
SUPER_AVOID(-1),
SUPER_BUFF(-1),
SUPER_MOVE(-1),
SYNERGY_EOLH(-1),
SYNERGY_FEOH(-1),
SYNERGY_IS(-1),
SYNERGY_LENKER(-1),
SYNERGY_OTHEL(-1),
SYNERGY_PARTY_BUF(-1),
SYNERGY_SEER(-1),
SYNERGY_SIGEL(-1),
SYNERGY_TIR(-1),
SYNERGY_WYNN(-1),
SYNERGY_YR(-1),
TIME_BOMB(-1),
TURN_CRYSTAL(-1),
VAMPIRIC_ATTACK_SPECIAL(-1),
VIBRATION(-1),
VOTE(-1),
VP_CHANGE(-1),
VP_KEEP(-1),
VP_MENTOR_RUNE(-1),
VP_UP(-1),
WEAKENED_DEATH_PENALTY(-1),
WEAPON_MASTER_SPECIAL(-1),
WISPERING_OF_BATTLE(-1),
WP_CHANGE_EVENT(-1),
CLAN_TEAMWORK(-1),
SONG_OF_ARCHERY(-1),
DANCE_OF_SAGE(-1),
AB_HAWK_EYE(0),
ALL_ATTACK_DOWN(1),
ALL_ATTACK_UP(2),
ALL_SPEED_DOWN(3),
ALL_SPEED_UP(4),
ANTARAS_DEBUFF(5),
ARMOR_EARTH(6),
ARMOR_FIRE(7),
ARMOR_HOLY(8),
ARMOR_UNHOLY(9),
ARMOR_WATER(10),
ARMOR_WIND(11),
ATTACK_SPEED_UP_BOW(12),
ATTACK_TIME_DOWN(13),
ATTACK_TIME_UP(14),
AVOID_DOWN(15),
AVOID_UP(16),
AVOID_UP_SPECIAL(17),
BERSERKER(18),
BIG_BODY(19),
BIG_HEAD(20),
BLEEDING(21),
BOW_RANGE_UP(22),
BUFF_QUEEN_OF_CAT(23),
BUFF_UNICORN_SERAPHIM(24),
CANCEL_PROB_DOWN(25),
CASTING_TIME_DOWN(26),
CASTING_TIME_UP(27),
CHEAP_MAGIC(28),
CRITICAL_DMG_DOWN(29),
CRITICAL_DMG_UP(30),
CRITICAL_PROB_DOWN(31),
CRITICAL_PROB_UP(32),
DANCE_OF_AQUA_GUARD(33),
DANCE_OF_CONCENTRATION(34),
DANCE_OF_EARTH_GUARD(35),
DANCE_OF_FIRE(36),
DANCE_OF_FURY(37),
DANCE_OF_INSPIRATION(38),
DANCE_OF_LIGHT(39),
DANCE_OF_MYSTIC(40),
DANCE_OF_PROTECTION(41),
DANCE_OF_SHADOW(42),
DANCE_OF_SIREN(43),
DANCE_OF_VAMPIRE(44),
DANCE_OF_WARRIOR(45),
DEBUFF_NIGHTSHADE(46),
DEBUFF_SHIELD(47),
DECREASE_WEIGHT_PENALTY(48),
DERANGEMENT(49),
DETECT_WEAKNESS(50),
DMG_SHIELD(51),
DOT_ATTR(52),
DOT_MP(53),
DRAGON_BREATH(54),
DUELIST_SPIRIT(55),
FATAL_POISON(56),
FISHING_MASTERY_DOWN(57),
FLY_AWAY(58),
FOCUS_DAGGER(59),
HEAL_EFFECT_DOWN(60),
HEAL_EFFECT_UP(61),
HERO_BUFF(62),
HERO_DEBUFF(63),
HIT_DOWN(64),
HIT_UP(65),
HOLY_ATTACK(66),
HP_RECOVER(67),
HP_REGEN_DOWN(68),
HP_REGEN_UP(69),
LIFE_FORCE_ORC(70),
LIFE_FORCE_OTHERS(71),
MAGIC_CRITICAL_UP(72),
MAJESTY(73),
MAX_BREATH_UP(74),
MAX_HP_DOWN(75),
MAX_HP_UP(76),
MAX_MP_UP(77),
MA_DOWN(78),
MA_UP(79),
MA_UP_HERB(80),
MD_DOWN(81),
MD_UP(82),
MD_UP_ATTR(83),
MIGHT_MORTAL(84),
MP_COST_DOWN(85),
MP_COST_UP(86),
MP_RECOVER(87),
MP_REGEN_UP(88),
MULTI_BUFF(89),
MULTI_DEBUFF(90),
PARALYZE(91),
PA_DOWN(92),
PA_PD_UP(93),
PA_UP(94),
PA_UP_HERB(95),
PA_UP_SPECIAL(96),
PD_DOWN(97),
PD_UP(98),
PD_UP_BOW(99),
PD_UP_SPECIAL(100),
PINCH(101),
POISON(102),
POLEARM_ATTACK(103),
POSSESSION(104),
PRESERVE_ABNORMAL(105),
PUBLIC_SLOT(106),
RAGE_MIGHT(107),
REDUCE_DROP_PENALTY(108),
REFLECT_ABNORMAL(109),
RESIST_BLEEDING(110),
RESIST_DEBUFF_DISPEL(111),
RESIST_DERANGEMENT(112),
RESIST_HOLY_UNHOLY(113),
RESIST_POISON(114),
RESIST_SHOCK(115),
RESIST_SPIRITLESS(116),
REUSE_DELAY_DOWN(117),
REUSE_DELAY_UP(118),
ROOT_PHYSICALLY(119),
ROOT_MAGICALLY(120),
SHIELD_DEFENCE_UP(121),
SHIELD_PROB_UP(122),
SILENCE(123),
SILENCE_ALL(124),
SILENCE_PHYSICAL(125),
SLEEP(126),
SNIPE(127),
SONG_OF_CHAMPION(128),
SONG_OF_EARTH(129),
SONG_OF_FLAME_GUARD(130),
SONG_OF_HUNTER(131),
SONG_OF_INVOCATION(132),
SONG_OF_LIFE(133),
SONG_OF_MEDITATION(134),
SONG_OF_RENEWAL(135),
SONG_OF_STORM_GUARD(136),
SONG_OF_VENGEANCE(137),
SONG_OF_VITALITY(138),
SONG_OF_WARDING(139),
SONG_OF_WATER(140),
SONG_OF_WIND(141),
SPA_DISEASE_A(142),
SPA_DISEASE_B(143),
SPA_DISEASE_C(144),
SPA_DISEASE_D(145),
SPEED_DOWN(146),
SPEED_UP(147),
SPEED_UP_SPECIAL(148),
SSQ_TOWN_BLESSING(149),
SSQ_TOWN_CURSE(150),
STEALTH(151),
STUN(152),
THRILL_FIGHT(153),
TOUCH_OF_DEATH(154),
TOUCH_OF_LIFE(155),
TURN_FLEE(156),
TURN_PASSIVE(157),
TURN_STONE(158),
ULTIMATE_BUFF(159),
ULTIMATE_DEBUFF(160),
VALAKAS_ITEM(161),
VAMPIRIC_ATTACK(162),
WATCHER_GAZE(163),
RESURRECTION_SPECIAL(164),
COUNTER_SKILL(165),
AVOID_SKILL(166),
CP_UP(167),
CP_DOWN(168),
CP_REGEN_UP(169),
CP_REGEN_DOWN(170),
INVINCIBILITY(171),
ABNORMAL_INVINCIBILITY(172),
PHYSICAL_STANCE(173),
MAGICAL_STANCE(174),
COMBINATION(175),
ANESTHESIA(176),
CRITICAL_POISON(177),
SEIZURE_PENALTY(178),
ABNORMAL_ITEM(179),
SEIZURE_A(180),
SEIZURE_B(181),
SEIZURE_C(182),
FORCE_MEDITATION(183),
MIRAGE(184),
POTION_OF_GENESIS(185),
PVP_DMG_UP(186),
PVP_DMG_DOWN(187),
IRON_SHIELD(188),
TRANSFER_DAMAGE(189),
SONG_OF_ELEMENTAL(190),
DANCE_OF_ALIGNMENT(191),
ARCHER_SPECIAL(192),
SPOIL_BOMB(193),
FIRE_DOT(194),
WATER_DOT(195),
WIND_DOT(196),
EARTH_DOT(197),
HEAL_POWER_UP(198),
RECHARGE_UP(199),
NORMAL_ATTACK_BLOCK(200),
DISARM(201),
DEATH_MARK(202),
KAMAEL_SPECIAL(203),
TRANSFORM(204),
DARK_SEED(205),
REAL_TARGET(206),
FREEZING(207),
TIME_CHECK(208),
MA_MD_UP(209),
DEATH_CLACK(210),
HOT_GROUND(211),
EVIL_BLOOD(212),
ALL_REGEN_UP(213),
ALL_REGEN_DOWN(214),
IRON_SHIELD_I(215),
ARCHER_SPECIAL_I(216),
T_CRT_RATE_UP(217),
T_CRT_RATE_DOWN(218),
T_CRT_DMG_UP(219),
T_CRT_DMG_DOWN(220),
INSTINCT(221),
OBLIVION(222),
WEAK_CONSTITUTION(223),
THIN_SKIN(224),
ENERVATION(225),
SPITE(226),
MENTAL_IMPOVERISH(227),
ATTRIBUTE_POTION(228),
TALISMAN(229),
MULTI_DEBUFF_FIRE(230),
MULTI_DEBUFF_WATER(231),
MULTI_DEBUFF_WIND(232),
MULTI_DEBUFF_EARTH(233),
MULTI_DEBUFF_HOLY(234),
MULTI_DEBUFF_UNHOLY(235),
LIFE_FORCE_KAMAEL(236),
MA_UP_SPECIAL(237),
PK_PROTECT(238),
MAXIMUM_ABILITY(239),
TARGET_LOCK(240),
PROTECTION(241),
WILL(242),
SEED_OF_KNIGHT(243),
EXPOSE_WEAK_POINT(244),
FORCE_OF_DESTRUCTION(245),
ELEMENTAL_ARMOR(246),
SUMMON_CONDITION(247),
IMPROVE_PA_PD_UP(248),
IMPROVE_MA_MD_UP(249),
IMPROVE_HP_MP_UP(250),
IMPROVE_CRT_RATE_DMG_UP(251),
IMPROVE_SHIELD_RATE_DEFENCE_UP(252),
IMPROVE_SPEED_AVOID_UP(253),
LIMIT(254),
MULTI_DEBUFF_SOUL(255),
CURSE_LIFE_FLOW(256),
BETRAYAL_MARK(257),
TRANSFORM_HANGOVER(258),
TRANSFORM_SCRIFICE(259),
SONG_OF_WINDSTORM(260),
DANCE_OF_BLADESTORM(261),
IMPROVE_VAMPIRIC_HASTE(262),
WEAPON_MASTERY(263),
APELLA(264),
TRANSFORM_SCRIFICE_P(265),
SUB_TRIGGER_HASTE(266),
SUB_TRIGGER_DEFENCE(267),
SUB_TRIGGER_CRT_RATE_UP(268),
SUB_TRIGGER_SPIRIT(269),
MIRAGE_TRAP(270),
DEATH_PENALTY(271),
ENTRY_FOR_GAME(272),
BLOOD_CONSTRACT(273),
DWARF_BUFF(274),
EVASION_BUFF(275),
SOUL_SHIELD(276),
BR_UTHANKA_BUFF(277),
FIELD_RAID_BUFF1(278),
PD_UP_DMAGIC(279),
PREMIUM_BUFF(280),
RUNWAY_ARMOR(281),
RUNWAY_WEAPON(282),
G_EV_BUFF1(283),
MAX(284),
AIRBIND(365),
KNOCKDOWN(367),
EARTHWORM_DEBUFF(424);
private int _clientId;
protected static final Logger LOGGER = Logger.getLogger(AbnormalType.class.getName());
AbnormalType(int clientId)
{
_clientId = clientId;
}
/**
* Get the enumerate for the given String.
* @param type the abnormal type to get
* @return the abnormal type
*/
public static AbnormalType getAbnormalType(String type)
{
try
{
return Enum.valueOf(AbnormalType.class, type);
}
catch (Exception e)
{
LOGGER.warning("Unknown AbnormalType requested : " + type);
return NONE;
}
}
public int getClientId()
{
return _clientId;
}
/**
* Verify if this enumerate is default.
* @return {@code true} if this enumerate is none, {@code false} otherwise
*/
public boolean isNone()
{
return this == NONE;
}
}

View File

@@ -1,218 +1,228 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
/**
* Abnormal Visual Effect enumerated.
* @author NosBit
*/
public enum AbnormalVisualEffect
{
DOT_BLEEDING(1),
DOT_POISON(2),
DOT_FIRE(3),
DOT_WATER(4),
DOT_WIND(5),
DOT_SOIL(6),
STUN(7),
SLEEP(8),
SILENCE(9),
ROOT(10),
PARALYZE(11),
FLESH_STONE(12),
DOT_MP(13),
BIG_HEAD(14),
DOT_FIRE_AREA(15),
CHANGE_TEXTURE(16),
BIG_BODY(17),
FLOATING_ROOT(18),
DANCE_ROOT(19),
GHOST_STUN(20),
STEALTH(21),
SEIZURE1(22),
SEIZURE2(23),
MAGIC_SQUARE(24),
FREEZING(25),
SHAKE(26),
ULTIMATE_DEFENCE(28),
VP_UP(29),
REAL_TARGET(30),
DEATH_MARK(31),
TURN_FLEE(32),
INVINCIBILITY(33),
AIR_BATTLE_SLOW(34),
AIR_BATTLE_ROOT(35),
CHANGE_WEAPON(36),
CHANGE_GOLD_AFRO(37),
CHANGE_PINK_AFRO(38),
CHANGE_BLACK_AFRO(39),
STIGMA_OF_SILEN(41),
SPEED_DOWN(42),
FROZEN_PILLAR(43),
CHANGE_VESPER_S(44),
CHANGE_VESPER_C(45),
CHANGE_VESPER_D(46),
TIME_BOMB(47),
MP_SHIELD(48),
AIR_BIND(49),
CHANGE_BODY(50),
KNOCK_DOWN(51),
NAVIT_ADVENT(52),
KNOCK_BACK(53),
CHANGE_7TH_ANNIVERSARY(54),
ON_SPOT_MOVEMENT(55),
DEPORT(56),
AURA_BUFF(57),
AURA_BUFF_SELF(58),
AURA_DEBUFF(59),
AURA_DEBUFF_SELF(60),
HURRICANE(61),
HURRICANE_SELF(62),
BLACK_MARK(63),
SOUL_AVATAR(64),
CHANGE_8TH_ANNIVERSARY(65),
NO_CHAT(68),
HERB_OF_POWER(69),
HERB_OF_MAGIC(70),
TALISMAN_DECO_DARK_PURPLE(71),
TALISMAN_POWER2(72), // removed?
TALISMAN_DECO_GOLD(73),
TALISMAN_DECO_ORANGE(74),
TALISMAN_DECO_BLUE(75),
TALISMAN_DECO_LIGHT_PURPLE(76),
CHANGE_CURIOUS_HOUSE(77),
CHANGE_MEMORY_N(78),
CHANGE_MEMORY_D(79),
CHANGE_MEMORY_C(80),
CHANGE_MEMORY_B(81),
CHANGE_MEMORY_A(82),
CHANGE_SWIMSUIT_A(83),
CHANGE_SWIMSUIT_B(84),
CHANGE_XMAS(85),
CARD_PC_DECO(86),
CHANGE_DINOS(87),
CHANGE_VALENTINE(88),
CHOCOLATE(89),
CANDY(90),
COOKIE(91),
STARS_0(92),
STARS_1(93),
STARS_2(94),
STARS_3(95),
STARS_4(96),
STARS_5(97),
DUELING(98),
FREEZING2(99),
CHANGE_YOGI(100),
YOGI(101),
MUSICAL_NOTE_YELLOW(102),
MUSICAL_NOTE_BLUE(103),
MUSICAL_NOTE_GREEN(104),
TENTH_ANNIVERSARY(105),
XMAS_SOCKS(106),
XMAS_TREE(107),
XMAS_SNOWMAN(108),
OTHELL_ROGUE_BLUFF(109),
HE_PROTECT(110),
SU_SUMCROSS(111),
WIND_STUN(112),
STORM_SIGN2(113),
STORM_SIGN1(114),
WIND_BLEND(115),
DECEPTIVE_BLINK(116),
WIND_HIDE(117),
PSY_POWER(118),
SQUALL(119),
WIND_ILLUSION(120),
SAYHA_FURY(121),
HIDE4(123),
PMENTAL_TRAIL(124),
HOLD_LIGHTING(125),
GRAVITY_SPACE_3(126),
SPACEREF(127),
HE_ASPECT(128),
PALADIN_DEF(141),
GUARDIAN_DEF(142),
REALTAR2(143),
DIVINITY(144),
SHILPROTECTION(145),
EVENT_STAR_CA(146),
EVENT_STAR1_TA(147),
EVENT_STAR2_TA(148),
EVENT_STAR3_TA(149),
EVENT_STAR4_TA(150),
EVENT_STAR5_TA(151),
ABSORB_SHIELD(152),
KN_PHOENIX_AURA(153),
KN_REVENGE_AURA(154),
KN_EVAS_AURA(155),
KN_TEMPLA_AURA(156),
LONGBOW(157),
WIDESWORD(158),
BIGFIST(159),
SHADOWSTEP(160),
TORNADO(161),
SNOW_SLOW(162),
SNOW_HOLD(163),
TORNADO_SLOW(165),
ASTATINE_WATER(166),
BIGBD_CAT_NPC(167),
BIGBD_UNICORN_NPC(168),
BIGBD_DEMON_NPC(169),
BIGBD_CAT_PC(170),
BIGBD_UNICORN_PC(171),
BIGBD_DEMON_PC(172),
DRAGON_ULTIMATE(181),
INFINITE_SHIELD1(183),
INFINITE_SHIELD2(184),
INFINITE_SHIELD3(185),
INFINITE_SHIELD4(186),
ABSORB2_SHIELD(187);
private final int _clientId;
private AbnormalVisualEffect(int clientId)
{
_clientId = clientId;
}
/**
* Gets the client id.
* @return the client id
*/
public int getClientId()
{
return _clientId;
}
/**
* Finds abnormal visual effect by name.
* @param name the name
* @return The abnormal visual effect if its found, {@code null} otherwise
*/
public static AbnormalVisualEffect findByName(String name)
{
for (AbnormalVisualEffect abnormalVisualEffect : values())
{
if (abnormalVisualEffect.name().equalsIgnoreCase(name))
{
return abnormalVisualEffect;
}
}
return null;
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
/**
* Abnormal Visual Effect enumerated.
* @author NosBit
*/
public enum AbnormalVisualEffect
{
DOT_BLEEDING(1),
DOT_POISON(2),
DOT_FIRE(3),
DOT_WATER(4),
DOT_WIND(5),
DOT_SOIL(6),
STUN(7),
SLEEP(8),
SILENCE(9),
ROOT(10),
PARALYZE(11),
FLESH_STONE(12),
DOT_MP(13),
BIG_HEAD(14),
DOT_FIRE_AREA(15),
CHANGE_TEXTURE(16),
BIG_BODY(17),
FLOATING_ROOT(18),
DANCE_ROOT(19),
GHOST_STUN(20),
STEALTH(21),
SEIZURE1(22),
SEIZURE2(23),
MAGIC_SQUARE(24),
FREEZING(25),
SHAKE(26),
ULTIMATE_DEFENCE(28),
VP_UP(29),
VP_KEEP(29), // TODO: Unknown ClientID
REAL_TARGET(30),
DEATH_MARK(31),
TURN_FLEE(32),
INVINCIBILITY(33),
AIR_BATTLE_SLOW(34),
AIR_BATTLE_ROOT(35),
CHANGE_WP(36),
CHANGE_HAIR_G(37), // Gold Afro
CHANGE_HAIR_P(38), // Pink Afro
CHANGE_HAIR_B(39), // Black Afro
UNKNOWN_40(40),
STIGMA_OF_SILEN(41),
SPEED_DOWN(42),
FROZEN_PILLAR(43),
CHANGE_VES_S(44),
CHANGE_VES_C(45),
CHANGE_VES_D(46),
TIME_BOMB(47),
MP_SHIELD(48),
AIRBIND(49),
CHANGEBODY(50),
KNOCKDOWN(51),
NAVIT_ADVENT(52),
KNOCKBACK(53),
CHANGE_7ANNIVERSARY(54),
ON_SPOT_MOVEMENT(55),
DEPORT(56),
AURA_BUFF(57),
AURA_BUFF_SELF(58),
AURA_DEBUFF(59),
AURA_DEBUFF_SELF(60),
HURRICANE(61),
HURRICANE_SELF(62),
BLACK_MARK(63),
BR_SOUL_AVATAR(64),
CHANGE_GRADE_B(65),
BR_BEAM_SWORD_ONEHAND(66),
BR_BEAM_SWORD_DUAL(67),
NO_CHAT(68),
HERB_PA_UP(69),
HERB_MA_UP(70),
SEED_TALISMAN1(71),
SEED_TALISMAN2(72),
SEED_TALISMAN3(73),
SEED_TALISMAN4(74),
SEED_TALISMAN5(75),
SEED_TALISMAN6(76),
CURIOUS_HOUSE(77),
NGRADE_CHANGE(78),
DGRADE_CHANGE(79),
CGRADE_CHANGE(80),
BGRADE_CHANGE(81),
AGRADE_CHANGE(82),
SWEET_ICE_FLAKES(83),
FANTASY_ICE_FLAKES(84),
CHANGE_XMAS(85),
CARD_PC_DECO(86),
CHANGE_DINOS(87),
CHANGE_VALENTINE(88),
CHOCOLATE(89),
CANDY(90),
COOKIE(91),
STARS_0(92),
STARS_1(93),
STARS_2(94),
STARS_3(95),
STARS_4(96),
STARS_5(97),
DUELING(98),
FREEZING2(99),
CHANGE_YOGI(100),
YOGI(101),
MUSICAL_NOTE_YELLOW(102),
MUSICAL_NOTE_BLUE(103),
MUSICAL_NOTE_GREEN(104),
TENTH_ANNIVERSARY(105),
XMAS_SOCKS(106),
XMAS_TREE(107),
XMAS_SNOWMAN(108),
OTHELL_ROGUE_BLUFF(109),
HE_PROTECT(110),
SU_SUMCROSS(111),
WIND_STUN(112),
STORM_SIGN2(113),
STORM_SIGN1(114),
WIND_BLEND(115),
DECEPTIVE_BLINK(116),
WIND_HIDE(117),
PSY_POWER(118),
SQUALL(119),
WIND_ILLUSION(120),
SAYHA_FURY(121),
HIDE4(123),
PMENTAL_TRAIL(124),
HOLD_LIGHTING(125),
GRAVITY_SPACE_3(126),
SPACEREF(127),
HE_ASPECT(128),
RUNWAY_ARMOR1(129),
RUNWAY_ARMOR2(130),
RUNWAY_ARMOR3(131),
RUNWAY_ARMOR4(132),
RUNWAY_ARMOR5(133),
RUNWAY_ARMOR6(134),
RUNWAY_WEAPON1(135),
RUNWAY_WEAPON2(136),
PALADIN_PROTECTION(141),
SENTINEL_PROTECTION(142),
REAL_TARGET_2(143),
DIVINITY(144),
SHILLIEN_PROTECTION(145),
EVENT_STARS_0(146),
EVENT_STARS_1(147),
EVENT_STARS_2(148),
EVENT_STARS_3(149),
EVENT_STARS_4(150),
EVENT_STARS_5(151),
ABSORB_SHIELD(152),
PHOENIX_AURA(153),
REVENGE_AURA(154),
EVAS_AURA(155),
TEMPLAR_AURA(156),
LONG_BLOW(157),
WIDE_SWORD(158),
BIG_FIST(159),
SHADOW_STEP(160),
TORNADO(161),
SNOW_SLOW(162),
SNOW_HOLD(163),
TORNADO_SLOW(165),
ASTATINE_WATER(166),
BIG_BODY_COMBINATION_CAT_NPC(167),
BIG_BODY_COMBINATION_UNICORN_NPC(168),
BIG_BODY_COMBINATION_DEMON_NPC(169),
BIG_BODY_COMBINATION_CAT_PC(170),
BIG_BODY_COMBINATION_UNICORN_PC(171),
BIG_BODY_COMBINATION_DEMON_PC(172),
BIG_BODY_2(173),
BIG_BODY_3(174),
DRAGON_ULTIMATE(700),
CHANGE_HALLOWEEN(1000);
private final int _clientId;
AbnormalVisualEffect(int clientId)
{
_clientId = clientId;
}
/**
* Gets the client id.
* @return the client id
*/
public int getClientId()
{
return _clientId;
}
/**
* Finds abnormal visual effect by name.
* @param name the name
* @return The abnormal visual effect if its found, {@code null} otherwise
*/
public static AbnormalVisualEffect findByName(String name)
{
for (AbnormalVisualEffect abnormalVisualEffect : values())
{
if (abnormalVisualEffect.name().equalsIgnoreCase(name))
{
return abnormalVisualEffect;
}
}
return null;
}
}

View File

@@ -1,57 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.HashMap;
import java.util.Map;
import com.l2jmobius.gameserver.model.actor.L2Character;
public class BlowSuccess
{
private static Map<String, Boolean> _success = new HashMap<>();
public static BlowSuccess getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final BlowSuccess _instance = new BlowSuccess();
}
public void remove(L2Character l2Character, Skill skill)
{
_success.remove(makeKey(l2Character, skill));
}
public boolean get(L2Character l2Character, Skill skill)
{
return _success.get(makeKey(l2Character, skill));
}
public void set(L2Character l2Character, Skill skill, boolean success)
{
_success.put(makeKey(l2Character, skill), success);
}
private String makeKey(L2Character l2Character, Skill skill)
{
return "" + l2Character.getObjectId() + ":" + skill.getId();
}
}

View File

@@ -1,407 +1,454 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.GameTimeController;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.CharEffectList;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Summon;
import com.l2jmobius.gameserver.model.effects.AbstractEffect;
import com.l2jmobius.gameserver.model.effects.EffectTaskInfo;
import com.l2jmobius.gameserver.model.effects.EffectTickTask;
import com.l2jmobius.gameserver.model.stats.Formulas;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/**
* Buff Info.<br>
* Complex DTO that holds all the information for a given buff (or debuff or dance/song) set of effects issued by an skill.
* @author Zoey76
*/
public final class BuffInfo
{
// Data
/** Data. */
private final L2Character _effector;
private final L2Character _effected;
private final Skill _skill;
/** The effects. */
private final List<AbstractEffect> _effects = new ArrayList<>(1);
// Tasks
/** Effect tasks for ticks. */
private volatile Map<AbstractEffect, EffectTaskInfo> _tasks = new ConcurrentHashMap<>();
/** Scheduled future. */
private ScheduledFuture<?> _scheduledFutureTimeTask;
// Time and ticks
/** Abnormal time. */
private int _abnormalTime;
/** The game ticks at the start of this effect. */
private final int _periodStartTicks;
// Misc
/** If {@code true} then this effect has been cancelled. */
private boolean _isRemoved = false;
/** If {@code true} then this effect is in use (or has been stop because an Herb took place). */
private boolean _isInUse = true;
/**
* Buff Info constructor.
* @param effector
* @param effected
* @param skill
*/
public BuffInfo(L2Character effector, L2Character effected, Skill skill)
{
_effector = effector;
_effected = effected;
_skill = skill;
_abnormalTime = Formulas.calcEffectAbnormalTime(effector, effected, skill);
_periodStartTicks = GameTimeController.getInstance().getGameTicks();
}
/**
* Gets the effects on this buff info.
* @return the effects
*/
public List<AbstractEffect> getEffects()
{
return _effects;
}
/**
* Adds an effect to this buff info.
* @param effect the effect to add
*/
public void addEffect(AbstractEffect effect)
{
_effects.add(effect);
}
/**
* Adds an effect task to this buff info.<br>
* @param effect the effect that owns the task
* @param effectTaskInfo the task info
*/
private void addTask(AbstractEffect effect, EffectTaskInfo effectTaskInfo)
{
_tasks.put(effect, effectTaskInfo);
}
/**
* Gets the task for the given effect.
* @param effect the effect
* @return the task
*/
private EffectTaskInfo getEffectTask(AbstractEffect effect)
{
return _tasks.get(effect);
}
/**
* Gets the skill that created this buff info.
* @return the skill
*/
public Skill getSkill()
{
return _skill;
}
/**
* Gets the calculated abnormal time.
* @return the abnormal time
*/
public int getAbnormalTime()
{
return _abnormalTime;
}
/**
* Sets the abnormal time.
* @param abnormalTime the abnormal time to set
*/
public void setAbnormalTime(int abnormalTime)
{
_abnormalTime = abnormalTime;
}
/**
* Gets the period start ticks.
* @return the period start
*/
public int getPeriodStartTicks()
{
return _periodStartTicks;
}
/**
* Get the remaining time in seconds for this buff info.
* @return the elapsed time
*/
public int getTime()
{
return _abnormalTime - ((GameTimeController.getInstance().getGameTicks() - _periodStartTicks) / GameTimeController.TICKS_PER_SECOND);
}
/**
* Verify if this buff info has been cancelled.
* @return {@code true} if this buff info has been cancelled, {@code false} otherwise
*/
public boolean isRemoved()
{
return _isRemoved;
}
/**
* Set the buff info to removed.
* @param val the value to set
*/
public void setRemoved(boolean val)
{
_isRemoved = val;
}
/**
* Verify if this buff info is in use.
* @return {@code true} if this buff info is in use, {@code false} otherwise
*/
public boolean isInUse()
{
return _isInUse;
}
/**
* Set the buff info to in use.
* @param val the value to set
*/
public void setInUse(boolean val)
{
_isInUse = val;
}
/**
* Gets the character that launched the buff.
* @return the effector
*/
public L2Character getEffector()
{
return _effector;
}
/**
* Gets the target of the skill.
* @return the effected
*/
public L2Character getEffected()
{
return _effected;
}
/**
* Stops all the effects for this buff info.<br>
* Removes effects stats.<br>
* <b>It will not remove the buff info from the effect list</b>.<br>
* Instead call {@link CharEffectList#stopSkillEffects(boolean, Skill)}
* @param removed if {@code true} the skill will be handled as removed
*/
public void stopAllEffects(boolean removed)
{
setRemoved(removed);
// Cancels the task that will end this buff info
if ((_scheduledFutureTimeTask != null) && !_scheduledFutureTimeTask.isCancelled())
{
_scheduledFutureTimeTask.cancel(true);
}
finishEffects();
}
public void initializeEffects()
{
if ((_effected == null) || (_skill == null))
{
return;
}
// When effects are initialized, the successfully landed.
if (_effected.isPlayer() && !_skill.isPassive())
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_S_EFFECT_CAN_BE_FELT);
sm.addSkillName(_skill);
_effected.sendPacket(sm);
}
// Creates a task that will stop all the effects.
if (_abnormalTime > 0)
{
_scheduledFutureTimeTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new BuffTimeTask(this), 0, 1000L);
}
// Reset abnormal visual effects.
resetAbnormalVisualEffects();
for (AbstractEffect effect : _effects)
{
if (effect.isInstant() || (_effected.isDead() && !_skill.isPassive()))
{
continue;
}
// Call on start.
effect.onStart(this);
// If it's a continuous effect, if has ticks schedule a task with period, otherwise schedule a simple task to end it.
if (effect.getTicks() > 0)
{
// The task for the effect ticks.
final EffectTickTask effectTask = new EffectTickTask(this, effect);
addTask(effect, new EffectTaskInfo(effectTask, ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(effectTask, effect.getTicks() * Config.EFFECT_TICK_RATIO, effect.getTicks() * Config.EFFECT_TICK_RATIO)));
}
// Add stats.
_effected.addStatFuncs(effect.getStatFuncs(_effector, _effected, _skill));
}
}
/**
* Called on each tick.<br>
* Verify if the effect should end and the effect task should be cancelled.
* @param effect the effect that is ticking
* @param tickCount the tick count
*/
public void onTick(AbstractEffect effect, int tickCount)
{
final boolean continueForever = _isInUse && effect.onActionTime(this);
if (continueForever || !_skill.isToggle())
{
return;
}
final EffectTaskInfo task = getEffectTask(effect);
if (task == null)
{
return;
}
task.getScheduledFuture().cancel(true); // Don't allow to finish current run.
_effected.getEffectList().stopSkillEffects(true, getSkill());
}
public void finishEffects()
{
// Cancels the ticking task.
for (EffectTaskInfo effectTask : _tasks.values())
{
effectTask.getScheduledFuture().cancel(true); // Don't allow to finish current run.
}
// Remove stats
removeStats();
// Notify on exit.
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if ((effect != null) && !effect.isInstant())
{
effect.onExit(this);
}
}
// Remove abnormal visual effects.
resetAbnormalVisualEffects();
// Set the proper system message.
if (!_effected.isSummon() || ((L2Summon) _effected).getOwner().hasSummon())
{
SystemMessageId smId = null;
if (_skill.isToggle())
{
smId = SystemMessageId.S1_HAS_BEEN_ABORTED;
}
else if (isRemoved())
{
smId = SystemMessageId.THE_EFFECT_OF_S1_HAS_BEEN_REMOVED;
}
else if (!_skill.isPassive())
{
smId = SystemMessageId.S1_HAS_WORN_OFF;
}
if (smId != null)
{
final SystemMessage sm = SystemMessage.getSystemMessage(smId);
sm.addSkillName(_skill);
_effected.sendPacket(sm);
}
}
// Remove short buff.
if (this == _effected.getEffectList().getShortBuff())
{
_effected.getEffectList().shortBuffStatusUpdate(null);
}
}
/**
* Applies all the abnormal visual effects to the effected.<br>
* Prevents multiple updates.
*/
private void resetAbnormalVisualEffects()
{
if (_skill.hasAbnormalVisualEffects())
{
_effected.resetCurrentAbnormalVisualEffects();
}
}
/**
* Adds the buff stats.
*/
public void addStats()
{
_effects.forEach(effect -> _effected.addStatFuncs(effect.getStatFuncs(_effector, _effected, _skill)));
}
/**
* Removes the buff stats.
*/
public void removeStats()
{
_effects.forEach(_effected::removeStatsOwner);
_effected.removeStatsOwner(_skill);
}
/**
* Gets the effect tick count.
* @param effect the effect
* @return the current tick count
*/
public int getTickCount(AbstractEffect effect)
{
final EffectTaskInfo effectTaskInfo = _tasks.get(effect);
if (effectTaskInfo != null)
{
return effectTaskInfo.getEffectTask().getTickCount();
}
return 0;
}
@Override
public String toString()
{
return "BuffInfo [effector=" + _effector + ", effected=" + _effected + ", skill=" + _skill + ", effects=" + _effects + ", tasks=" + _tasks + ", scheduledFutureTimeTask=" + _scheduledFutureTimeTask + ", abnormalTime=" + _abnormalTime + ", periodStartTicks=" + _periodStartTicks + ", isRemoved=" + _isRemoved + ", isInUse=" + _isInUse + "]";
}
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.GameTimeController;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.CharEffectList;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Summon;
import com.l2jmobius.gameserver.model.effects.AbstractEffect;
import com.l2jmobius.gameserver.model.effects.EffectTaskInfo;
import com.l2jmobius.gameserver.model.effects.EffectTickTask;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.options.Options;
import com.l2jmobius.gameserver.model.stats.Formulas;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
/**
* Buff Info.<br>
* Complex DTO that holds all the information for a given buff (or debuff or dance/song) set of effects issued by an skill.
* @author Zoey76
*/
public final class BuffInfo
{
// Data
/** Data. */
private final L2Character _effector;
private final L2Character _effected;
private final Skill _skill;
/** The effects. */
private final List<AbstractEffect> _effects = new ArrayList<>(1);
// Tasks
/** Effect tasks for ticks. */
private volatile Map<AbstractEffect, EffectTaskInfo> _tasks;
/** Scheduled future. */
private ScheduledFuture<?> _scheduledFutureTimeTask;
// Time and ticks
/** Abnormal time. */
private int _abnormalTime;
/** The game ticks at the start of this effect. */
private int _periodStartTicks;
// Misc
/** If {@code true} then this effect has been cancelled. */
private boolean _isRemoved = false;
/** If {@code true} then this effect is in use (or has been stop because an Herb took place). */
private boolean _isInUse = true;
private final boolean _hideStartMessage;
private final L2ItemInstance _item;
private final Options _option;
/**
* Buff Info constructor.
* @param effector the effector
* @param effected the effected
* @param skill the skill
* @param hideStartMessage hides start message
* @param item
* @param option
*/
public BuffInfo(L2Character effector, L2Character effected, Skill skill, boolean hideStartMessage, L2ItemInstance item, Options option)
{
_effector = effector;
_effected = effected;
_skill = skill;
_abnormalTime = Formulas.calcEffectAbnormalTime(effector, effected, skill);
_periodStartTicks = GameTimeController.getInstance().getGameTicks();
_hideStartMessage = hideStartMessage;
_item = item;
_option = option;
}
/**
* Gets the effects on this buff info.
* @return the effects
*/
public List<AbstractEffect> getEffects()
{
return _effects;
}
/**
* Adds an effect to this buff info.
* @param effect the effect to add
*/
public void addEffect(AbstractEffect effect)
{
_effects.add(effect);
}
/**
* Adds an effect task to this buff info.<br>
* Uses double-checked locking to initialize the map if it's necessary.
* @param effect the effect that owns the task
* @param effectTaskInfo the task info
*/
private void addTask(AbstractEffect effect, EffectTaskInfo effectTaskInfo)
{
if (_tasks == null)
{
synchronized (this)
{
if (_tasks == null)
{
_tasks = new ConcurrentHashMap<>();
}
}
}
_tasks.put(effect, effectTaskInfo);
}
/**
* Gets the task for the given effect.
* @param effect the effect
* @return the task
*/
private EffectTaskInfo getEffectTask(AbstractEffect effect)
{
return (_tasks == null) ? null : _tasks.get(effect);
}
/**
* Gets the skill that created this buff info.
* @return the skill
*/
public Skill getSkill()
{
return _skill;
}
/**
* Gets the calculated abnormal time.
* @return the abnormal time
*/
public int getAbnormalTime()
{
return _abnormalTime;
}
/**
* Sets the abnormal time.
* @param abnormalTime the abnormal time to set
*/
public void setAbnormalTime(int abnormalTime)
{
_abnormalTime = abnormalTime;
}
/**
* Gets the period start ticks.
* @return the period start
*/
public int getPeriodStartTicks()
{
return _periodStartTicks;
}
/**
* @return the item that triggered this skill
*/
public L2ItemInstance getItem()
{
return _item;
}
/**
* @return the options that issued this effect
*/
public Options getOption()
{
return _option;
}
/**
* Get the remaining time in seconds for this buff info.
* @return the elapsed time
*/
public int getTime()
{
return _abnormalTime - ((GameTimeController.getInstance().getGameTicks() - _periodStartTicks) / GameTimeController.TICKS_PER_SECOND);
}
/**
* Verify if this buff info has been cancelled.
* @return {@code true} if this buff info has been cancelled, {@code false} otherwise
*/
public boolean isRemoved()
{
return _isRemoved;
}
/**
* Set the buff info to removed.
* @param val the value to set
*/
public void setRemoved(boolean val)
{
_isRemoved = val;
}
/**
* Verify if this buff info is in use.
* @return {@code true} if this buff info is in use, {@code false} otherwise
*/
public boolean isInUse()
{
return _isInUse;
}
/**
* Set the buff info to in use.
* @param val the value to set
*/
public void setInUse(boolean val)
{
_isInUse = val;
}
/**
* Gets the character that launched the buff.
* @return the effector
*/
public L2Character getEffector()
{
return _effector;
}
/**
* Gets the target of the skill.
* @return the effected
*/
public L2Character getEffected()
{
return _effected;
}
/**
* Stops all the effects for this buff info.<br>
* Removes effects stats.<br>
* <b>It will not remove the buff info from the effect list</b>.<br>
* Instead call {@link CharEffectList#stopSkillEffects(boolean, Skill)}
* @param removed if {@code true} the skill will be handled as removed
*/
public void stopAllEffects(boolean removed)
{
setRemoved(removed);
// Cancels the task that will end this buff info
if ((_scheduledFutureTimeTask != null) && !_scheduledFutureTimeTask.isCancelled())
{
_scheduledFutureTimeTask.cancel(true);
}
finishEffects();
}
public void initializeEffects()
{
if ((_effected == null) || (_skill == null))
{
return;
}
// When effects are initialized, the successfully landed.
if (!_hideStartMessage && _effected.isPlayer() && !_skill.isPassive() && !_skill.isHidingMesseges() && !_skill.isAura())
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_S_EFFECT_CAN_BE_FELT);
sm.addSkillName(_skill);
_effected.sendPacket(sm);
}
// Creates a task that will stop all the effects.
if (_abnormalTime > 0)
{
_scheduledFutureTimeTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new BuffTimeTask(this), 0, 1000L);
}
// Reset abnormal visual effects.
resetAbnormalVisualEffects();
for (AbstractEffect effect : _effects)
{
if (effect.isInstant() || (_effected.isDead() && !_skill.isPassive()))
{
continue;
}
// Call on start.
effect.onStart(getEffector(), getEffected(), getSkill());
effect.onStart(this);
// If it's a continuous effect, if has ticks schedule a task with period, otherwise schedule a simple task to end it.
if (effect.getTicks() > 0)
{
// The task for the effect ticks.
final EffectTickTask effectTask = new EffectTickTask(this, effect);
final ScheduledFuture<?> scheduledFuture = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(effectTask, effect.getTicks() * Config.EFFECT_TICK_RATIO, effect.getTicks() * Config.EFFECT_TICK_RATIO);
// Adds the task for ticking.
addTask(effect, new EffectTaskInfo(effectTask, scheduledFuture));
}
// Recalculate all stats
_effected.getStat().recalculateStats(true);
}
}
/**
* Called on each tick.<br>
* Verify if the effect should end and the effect task should be cancelled.
* @param effect the effect that is ticking
* @param tickCount the tick count
*/
public void onTick(AbstractEffect effect, int tickCount)
{
boolean continueForever = false;
// If the effect is in use, allow it to affect the effected.
if (_isInUse)
{
// Callback for on action time event.
continueForever = effect.onActionTime(this);
}
if (!continueForever && _skill.isToggle())
{
final EffectTaskInfo task = getEffectTask(effect);
if (task != null)
{
task.getScheduledFuture().cancel(true); // Don't allow to finish current run.
_effected.getEffectList().stopSkillEffects(true, getSkill()); // Remove the buff from the effect list.
}
}
}
public void finishEffects()
{
// Cancels the ticking task.
if (_tasks != null)
{
for (EffectTaskInfo effectTask : _tasks.values())
{
effectTask.getScheduledFuture().cancel(true); // Don't allow to finish current run.
}
}
// Notify on exit.
for (AbstractEffect effect : _effects)
{
// Instant effects shouldn't call onExit(..).
if (!effect.isInstant())
{
effect.onExit(this);
}
}
// Remove abnormal visual effects.
resetAbnormalVisualEffects();
// Recalculate all stats
_effected.getStat().recalculateStats(true);
// Set the proper system message.
if ((_skill != null) && !(_effected.isSummon() && !((L2Summon) _effected).getOwner().hasSummon()) && !_skill.isHidingMesseges())
{
SystemMessageId smId = null;
if (_skill.isToggle())
{
smId = SystemMessageId.S1_HAS_BEEN_ABORTED;
}
else if (isRemoved())
{
smId = SystemMessageId.THE_EFFECT_OF_S1_HAS_BEEN_REMOVED;
}
else if (!_skill.isPassive())
{
smId = SystemMessageId.S1_HAS_WORN_OFF;
}
if (smId != null)
{
final SystemMessage sm = SystemMessage.getSystemMessage(smId);
sm.addSkillName(_skill);
_effected.sendPacket(sm);
}
}
// Remove short buff.
if (this == _effected.getEffectList().getShortBuff())
{
_effected.getEffectList().shortBuffStatusUpdate(null);
}
}
/**
* Applies all the abnormal visual effects to the effected.<br>
* Prevents multiple updates.
*/
private void resetAbnormalVisualEffects()
{
if ((_skill != null) && _skill.hasAbnormalVisualEffects())
{
_effected.resetCurrentAbnormalVisualEffects();
}
}
/**
* Gets the effect tick count.
* @param effect the effect
* @return the current tick count
*/
public int getTickCount(AbstractEffect effect)
{
if (_tasks != null)
{
final EffectTaskInfo effectTaskInfo = _tasks.get(effect);
if (effectTaskInfo != null)
{
return effectTaskInfo.getEffectTask().getTickCount();
}
}
return 0;
}
public void resetAbnormalTime(int abnormalTime)
{
if (_abnormalTime > 0)
{
_periodStartTicks = GameTimeController.getInstance().getGameTicks();
_abnormalTime = abnormalTime;
if ((_scheduledFutureTimeTask != null) && !_scheduledFutureTimeTask.isCancelled())
{
_scheduledFutureTimeTask.cancel(true);
}
_scheduledFutureTimeTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new BuffTimeTask(this), 0, 1000L);
}
}
}

View File

@@ -1,56 +1,56 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Effect time task finish the effect when the abnormal time is reached.
* @author Zoey76
*/
public class BuffTimeTask implements Runnable
{
private final AtomicInteger _time = new AtomicInteger();
private final BuffInfo _info;
/**
* EffectTimeTask constructor.
* @param info the buff info
*/
public BuffTimeTask(BuffInfo info)
{
_info = info;
}
/**
* Gets the elapsed time.
* @return the tick count
*/
public int getElapsedTime()
{
return _time.get();
}
@Override
public void run()
{
if (_time.incrementAndGet() > _info.getAbnormalTime())
{
_info.getEffected().getEffectList().stopSkillEffects(false, _info.getSkill().getId());
}
}
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Effect time task finish the effect when the abnormal time is reached.
* @author Zoey76
*/
public class BuffTimeTask implements Runnable
{
private final AtomicInteger _time = new AtomicInteger();
private final BuffInfo _info;
/**
* EffectTimeTask constructor.
* @param info the buff info
*/
public BuffTimeTask(BuffInfo info)
{
_info = info;
}
/**
* Gets the elapsed time.
* @return the tick count
*/
public int getElapsedTime()
{
return _time.get();
}
@Override
public void run()
{
if (_time.incrementAndGet() > _info.getAbnormalTime())
{
_info.getEffected().getEffectList().stopSkillEffects(false, _info.getSkill().getId());
}
}
}

View File

@@ -1,80 +1,83 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
/**
* An Enum to hold some important references to commonly used skills
* @author DrHouse
*/
public enum CommonSkill
{
RAID_CURSE(4215, 1),
RAID_CURSE2(4515, 1),
SEAL_OF_RULER(246, 1),
BUILD_HEADQUARTERS(247, 1),
WYVERN_BREATH(4289, 1),
STRIDER_SIEGE_ASSAULT(325, 1),
FIREWORK(5965, 1),
LARGE_FIREWORK(2025, 1),
BLESSING_OF_PROTECTION(5182, 1),
VOID_BURST(3630, 1),
VOID_FLOW(3631, 1),
THE_VICTOR_OF_WAR(5074, 1),
THE_VANQUISHED_OF_WAR(5075, 1),
SPECIAL_TREE_RECOVERY_BONUS(2139, 1),
WEAPON_GRADE_PENALTY(6209, 1),
ARMOR_GRADE_PENALTY(6213, 1),
CREATE_DWARVEN(172, 1),
LUCKY(194, 1),
EXPERTISE(239, 1),
CRYSTALLIZE(248, 1),
ONYX_BEAST_TRANSFORMATION(617, 1),
CREATE_COMMON(1320, 1),
DIVINE_INSPIRATION(1405, 1),
SERVITOR_SHARE(1557, 1),
CARAVANS_SECRET_MEDICINE(2341, 1),
SHILENS_BREATH(14571, 1),
IMPRIT_OF_LIGHT(19034, 1),
IMPRIT_OF_DARKNESS(19035, 1),
ABILITY_OF_LIGHT(19032, 1),
ABILITY_OF_DARKNESS(19033, 1),
HAIR_ACCESSORY_SET(17192, 1);
private final SkillHolder _holder;
private CommonSkill(int id, int level)
{
_holder = new SkillHolder(id, level);
}
public int getId()
{
return _holder.getSkillId();
}
public int getLevel()
{
return _holder.getSkillLvl();
}
public Skill getSkill()
{
return _holder.getSkill();
}
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
/**
* An Enum to hold some important references to commonly used skills
* @author DrHouse
*/
public enum CommonSkill
{
RAID_CURSE(4215, 1),
RAID_CURSE2(4515, 1),
SEAL_OF_RULER(246, 1),
BUILD_HEADQUARTERS(247, 1),
WYVERN_BREATH(4289, 1),
STRIDER_SIEGE_ASSAULT(325, 1),
FIREWORK(5965, 1),
LARGE_FIREWORK(2025, 1),
BLESSING_OF_PROTECTION(5182, 1),
VOID_BURST(3630, 1),
VOID_FLOW(3631, 1),
THE_VICTOR_OF_WAR(5074, 1),
THE_VANQUISHED_OF_WAR(5075, 1),
SPECIAL_TREE_RECOVERY_BONUS(2139, 1),
WEAPON_GRADE_PENALTY(6209, 1),
ARMOR_GRADE_PENALTY(6213, 1),
CREATE_DWARVEN(172, 1),
LUCKY(194, 1),
EXPERTISE(239, 1),
CRYSTALLIZE(248, 1),
ONYX_BEAST_TRANSFORMATION(617, 1),
CREATE_COMMON(1320, 1),
DIVINE_INSPIRATION(1405, 1),
SERVITOR_SHARE(1557, 1),
CARAVANS_SECRET_MEDICINE(2341, 1),
SHILENS_BREATH(14571, 1),
IMPRIT_OF_LIGHT(19034, 1),
IMPRIT_OF_DARKNESS(19035, 1),
ABILITY_OF_LIGHT(19032, 1),
ABILITY_OF_DARKNESS(19033, 1),
HAIR_ACCESSORY_SET(17192, 1),
ALCHEMY_CUBE(17943, 1),
ALCHEMY_CUBE_RANDOM_SUCCESS(17966, 1),
PET_SWITCH_STANCE(6054, 1);
private final SkillHolder _holder;
CommonSkill(int id, int level)
{
_holder = new SkillHolder(id, level);
}
public int getId()
{
return _holder.getSkillId();
}
public int getLevel()
{
return _holder.getSkillLvl();
}
public Skill getSkill()
{
return _holder.getSkill();
}
}

View File

@@ -1,32 +1,59 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
/**
* @author NosBit
*/
public enum EffectScope
{
GENERAL,
START,
SELF,
PASSIVE,
CHANNELING,
PVP,
PVE,
END
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author NosBit
*/
public enum EffectScope
{
GENERAL("effects"),
START("startEffects"),
SELF("selfEffects"),
CHANNELING("channelingEffects"),
PVP("pvpEffects"),
PVE("pveEffects"),
END("endEffects");
private static final Map<String, EffectScope> XML_NODE_NAME_TO_EFFECT_SCOPE;
static
{
XML_NODE_NAME_TO_EFFECT_SCOPE = Arrays.stream(values()).collect(Collectors.toMap(e -> e.getXmlNodeName(), e -> e));
}
private final String _xmlNodeName;
EffectScope(String xmlNodeName)
{
_xmlNodeName = xmlNodeName;
}
public String getXmlNodeName()
{
return _xmlNodeName;
}
public static EffectScope findByXmlNodeName(String xmlNodeName)
{
return XML_NODE_NAME_TO_EFFECT_SCOPE.get(xmlNodeName);
}
}

View File

@@ -0,0 +1,28 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.actor.L2Character;
/**
* @author NosBit
*/
public interface ISkillCondition
{
boolean canUse(L2Character caster, Skill skill, L2Object target);
}

View File

@@ -1,33 +1,33 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
/**
* Ride state enumerated.
* @author Zoey76
*/
public enum RideState
{
/** Riding nothing. */
NONE,
/** Riding a strider. */
STRIDER,
/** Riding a wolf. */
WOLF,
/** Riding a wyvern. */
WYVERN,
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
/**
* Ride state enumerated.
* @author Zoey76
*/
public enum RideState
{
/** Riding nothing. */
NONE,
/** Riding a strider. */
STRIDER,
/** Riding a wolf. */
WOLF,
/** Riding a wyvern. */
WYVERN,
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,923 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import static com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.ai.CtrlEvent;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.data.xml.impl.ActionData;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.ItemSkillType;
import com.l2jmobius.gameserver.enums.StatusUpdateType;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.PcCondOverride;
import com.l2jmobius.gameserver.model.actor.L2Attackable;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.L2Summon;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.effects.L2EffectType;
import com.l2jmobius.gameserver.model.events.EventDispatcher;
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureSkillFinishCast;
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureSkillUse;
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcSkillSee;
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
import com.l2jmobius.gameserver.model.holders.ItemSkillHolder;
import com.l2jmobius.gameserver.model.holders.SkillUseHolder;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.items.L2Weapon;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.options.OptionsSkillHolder;
import com.l2jmobius.gameserver.model.options.OptionsSkillType;
import com.l2jmobius.gameserver.model.skills.targets.TargetType;
import com.l2jmobius.gameserver.model.stats.Formulas;
import com.l2jmobius.gameserver.model.zone.ZoneId;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.ExRotation;
import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillCanceld;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillLaunched;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jmobius.gameserver.network.serverpackets.MoveToPawn;
import com.l2jmobius.gameserver.network.serverpackets.SetupGauge;
import com.l2jmobius.gameserver.network.serverpackets.StatusUpdate;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.util.Util;
/**
* @author Nik
*/
public class SkillCaster implements Runnable
{
private static final Logger LOGGER = Logger.getLogger(SkillCaster.class.getName());
private final WeakReference<L2Character> _caster;
private final WeakReference<L2Object> _target;
private final Skill _skill;
private final L2ItemInstance _item;
private final SkillCastingType _castingType;
private final int _castTime;
private int _coolTime;
private Collection<L2Object> _targets;
private ScheduledFuture<?> _task;
private int _phase;
private SkillCaster(L2Character caster, L2Object target, Skill skill, L2ItemInstance item, SkillCastingType castingType, boolean ctrlPressed, boolean shiftPressed, int castTime)
{
Objects.requireNonNull(caster);
Objects.requireNonNull(skill);
Objects.requireNonNull(castingType);
_caster = new WeakReference<>(caster);
_target = new WeakReference<>(target);
_skill = skill;
_item = item;
_castingType = castingType;
_castTime = castTime;
}
/**
* Checks if the caster can cast the specified skill on the given target with the selected parameters.
* @param caster the creature trying to cast
* @param target the selected target for cast
* @param skill the skill being cast
* @param item the reference item which requests the skill cast
* @param castingType the type of casting
* @param ctrlPressed force casting
* @param shiftPressed dont move while casting
* @return {@code SkillCaster} object containing casting data if casting has started or {@code null} if casting was not started.
*/
public static SkillCaster castSkill(L2Character caster, L2Object target, Skill skill, L2ItemInstance item, SkillCastingType castingType, boolean ctrlPressed, boolean shiftPressed)
{
return castSkill(caster, target, skill, item, castingType, ctrlPressed, shiftPressed, -1);
}
/**
* Checks if the caster can cast the specified skill on the given target with the selected parameters.
* @param caster the creature trying to cast
* @param target the selected target for cast
* @param skill the skill being cast
* @param item the reference item which requests the skill cast
* @param castingType the type of casting
* @param ctrlPressed force casting
* @param shiftPressed dont move while casting
* @param castTime custom cast time in milliseconds or -1 for default.
* @return {@code SkillCaster} object containing casting data if casting has started or {@code null} if casting was not started.
*/
public static SkillCaster castSkill(L2Character caster, L2Object target, Skill skill, L2ItemInstance item, SkillCastingType castingType, boolean ctrlPressed, boolean shiftPressed, int castTime)
{
if ((caster == null) || (skill == null) || (castingType == null))
{
return null;
}
if (!checkUseConditions(caster, skill, castingType))
{
return null;
}
// Check true aiming target of the skill.
target = skill.getTarget(caster, target, ctrlPressed, shiftPressed, false);
if (target == null)
{
return null;
}
castTime = castTime > -1 ? castTime : Formulas.calcHitTime(caster, skill);
// Schedule a thread that will execute 500ms before casting time is over (for animation issues and retail handling).
final SkillCaster skillCaster = new SkillCaster(caster, target, skill, item, castingType, ctrlPressed, shiftPressed, castTime);
skillCaster.run();
return skillCaster;
}
@Override
public void run()
{
final boolean instantCast = (_castingType == SkillCastingType.SIMULTANEOUS) || _skill.isAbnormalInstant() || _skill.isWithoutAction() || _skill.isToggle();
// Skills with instant cast are never launched.
if (instantCast)
{
triggerCast(_caster.get(), _target.get(), _skill, _item, false);
return;
}
long nextTaskDelay = 0;
boolean hasNextPhase = false;
switch (_phase++)
{
case 0: // Start skill casting.
{
hasNextPhase = startCasting();
nextTaskDelay = _castTime;
break;
}
case 1: // Launch the skill.
{
hasNextPhase = launchSkill();
nextTaskDelay = Formulas.SKILL_LAUNCH_TIME;
break;
}
case 2: // Finish launching and apply effects.
{
hasNextPhase = finishSkill();
nextTaskDelay = _coolTime;
break;
}
}
// Reschedule next task if we have such.
if (hasNextPhase)
{
_task = ThreadPoolManager.getInstance().scheduleEffect(this, nextTaskDelay);
}
else
{
// Stop casting if there is no next phase.
stopCasting(false);
}
}
public boolean startCasting()
{
final L2Character caster = _caster.get();
final L2Object target = _target.get();
if ((caster == null) || (target == null))
{
return false;
}
_coolTime = Formulas.calcAtkSpd(caster, _skill, _skill.getCoolTime()); // TODO Get proper fomula of this.
final int displayedCastTime = _castTime + Formulas.SKILL_LAUNCH_TIME; // For client purposes, it must be displayed to player the skill casting time + launch time.
final boolean instantCast = (_castingType == SkillCastingType.SIMULTANEOUS) || _skill.isAbnormalInstant() || _skill.isWithoutAction();
// Add this SkillCaster to the creature so it can be marked as casting.
if (!instantCast)
{
caster.addSkillCaster(_castingType, this);
}
// Disable the skill during the re-use delay and create a task EnableSkill with Medium priority to enable it at the end of the re-use delay
int reuseDelay = caster.getStat().getReuseTime(_skill);
if (reuseDelay > 10)
{
if (Formulas.calcSkillMastery(caster, _skill))
{
reuseDelay = 100;
caster.sendPacket(SystemMessageId.A_SKILL_IS_READY_TO_BE_USED_AGAIN);
}
if (reuseDelay > 30000)
{
caster.addTimeStamp(_skill, reuseDelay);
}
else
{
caster.disableSkill(_skill, reuseDelay);
}
}
// Stop movement when casting. Except instant cast.
if (!instantCast)
{
caster.getAI().clientStopMoving(null);
}
// Reduce talisman mana on skill use
if ((_skill.getReferenceItemId() > 0) && (ItemTable.getInstance().getTemplate(_skill.getReferenceItemId()).getBodyPart() == L2Item.SLOT_DECO))
{
final L2ItemInstance talisman = caster.getInventory().getItems(i -> i.getId() == _skill.getReferenceItemId(), L2ItemInstance::isEquipped).stream().findAny().orElse(null);
if (talisman != null)
{
talisman.decreaseMana(false, talisman.useSkillDisTime());
}
}
if (target != caster)
{
// Face the target
caster.setHeading(Util.calculateHeadingFrom(caster, target));
caster.broadcastPacket(new ExRotation(caster.getObjectId(), caster.getHeading())); // TODO: Not sent in retail. Probably moveToPawn is enough
// Send MoveToPawn packet to trigger Blue Bubbles on target become Red, but don't do it while (double) casting, because that will screw up animation... some fucked up stuff, right?
if (caster.isPlayer() && !caster.isCastingNow() && target.isCharacter())
{
caster.sendPacket(new MoveToPawn(caster, target, (int) caster.calculateDistance(target, false, false)));
caster.sendPacket(ActionFailed.STATIC_PACKET);
}
}
// Stop effects since we started casting. It should be sent before casting bar and mana consume.
caster.stopEffectsOnAction();
// Consume skill initial MP needed for cast. Retail sends it regardless if > 0 or not.
final int initmpcons = caster.getStat().getMpInitialConsume(_skill);
if (initmpcons > 0)
{
if (initmpcons > caster.getCurrentMp())
{
caster.sendPacket(SystemMessageId.NOT_ENOUGH_MP);
return false;
}
caster.getStatus().reduceMp(initmpcons);
final StatusUpdate su = new StatusUpdate(caster);
su.addUpdate(StatusUpdateType.CUR_MP, (int) caster.getCurrentMp());
caster.sendPacket(su);
}
// Send a packet starting the casting.
final int actionId = caster.isSummon() ? ActionData.getInstance().getSkillActionId(_skill.getId()) : -1;
if (!_skill.isNotBroadcastable())
{
caster.broadcastPacket(new MagicSkillUse(caster, target, _skill.getDisplayId(), _skill.getDisplayLevel(), displayedCastTime, reuseDelay, _skill.getReuseDelayGroup(), actionId, _castingType));
}
if (caster.isPlayer() && !instantCast)
{
// Send a system message to the player.
caster.sendPacket(_skill.getId() != 2046 ? SystemMessage.getSystemMessage(SystemMessageId.YOU_USE_S1).addSkillName(_skill) : SystemMessage.getSystemMessage(SystemMessageId.SUMMONING_YOUR_PET));
// Show the gauge bar for casting.
caster.sendPacket(new SetupGauge(caster.getObjectId(), SetupGauge.BLUE, displayedCastTime));
}
// Consume the required items. Should happen after use message is displayed and SetupGauge
if ((_skill.getItemConsumeId() > 0) && (_skill.getItemConsumeCount() > 0) && !caster.destroyItemByItemId(_skill.toString(), _skill.getItemConsumeId(), _skill.getItemConsumeCount(), null, true))
{
return false;
}
// Trigger any skill cast start effects.
if (target.isCharacter())
{
_skill.applyEffectScope(EffectScope.START, new BuffInfo(caster, (L2Character) target, _skill, false, _item, null), true, false);
}
// Start channeling if skill is channeling.
if (_skill.isChanneling() && (_skill.getChannelingSkillId() > 0))
{
caster.getSkillChannelizer().startChanneling(_skill);
}
return true;
}
public boolean launchSkill()
{
final L2Character caster = _caster.get();
final L2Object target = _target.get();
if ((caster == null) || (target == null))
{
return false;
}
// Gather list of affected targets by this skill.
_targets = _skill.getTargetsAffected(caster, target);
// Finish flying by setting the target location after picking targets. Packet is sent before MagicSkillLaunched.
if (_skill.getFlyType() != null)
{
caster.broadcastPacket(new FlyToLocation(caster, target, _skill.getFlyType()));
caster.setXYZ(target.getX(), target.getY(), target.getZ());
}
// Display animation of launching skill upon targets.
if (!_skill.isNotBroadcastable())
{
caster.broadcastPacket(new MagicSkillLaunched(caster, _skill.getDisplayId(), _skill.getDisplayLevel(), _castingType, _targets));
}
return true;
}
public boolean finishSkill()
{
final L2Character caster = _caster.get();
final L2Object target = _target.get();
if ((caster == null) || (target == null))
{
return false;
}
if (_targets == null)
{
_targets = Collections.singletonList(target);
}
final StatusUpdate su = new StatusUpdate(caster);
// Consume the required MP or stop casting if not enough.
final double mpConsume = _skill.getMpConsume() > 0 ? caster.getStat().getMpConsume(_skill) : 0;
if (mpConsume > 0)
{
if (mpConsume > caster.getCurrentMp())
{
caster.sendPacket(SystemMessageId.NOT_ENOUGH_MP);
return false;
}
caster.getStatus().reduceMp(mpConsume);
su.addUpdate(StatusUpdateType.CUR_MP, (int) caster.getCurrentMp());
}
// Consume the required HP or stop casting if not enough.
final double consumeHp = _skill.getHpConsume();
if (consumeHp > 0)
{
if (consumeHp >= caster.getCurrentHp())
{
caster.sendPacket(SystemMessageId.NOT_ENOUGH_HP);
return false;
}
caster.getStatus().reduceHp(consumeHp, caster, true);
su.addUpdate(StatusUpdateType.CUR_HP, (int) caster.getCurrentHp());
}
// Send HP/MP consumption packet if any attribute is set.
if (su.hasUpdates())
{
caster.sendPacket(su);
}
// Consume Souls if necessary
if (caster.isPlayer() && (_skill.getMaxSoulConsumeCount() > 0) && !caster.getActingPlayer().decreaseSouls(_skill.getMaxSoulConsumeCount(), _skill))
{
return false;
}
// Noptify skill is casted.
EventDispatcher.getInstance().notifyEvent(new OnCreatureSkillFinishCast(caster, target, _skill, _skill.isWithoutAction()), caster);
// Call the skill's effects and AI interraction and stuff.
SkillCaster.callSkill(caster, target, _targets, _skill, _item);
// Start attack stance.
if (!_skill.isWithoutAction())
{
if (_skill.isBad() && (_skill.getTargetType() != TargetType.DOOR_TREASURE))
{
caster.getAI().clientStartAutoAttack();
}
}
// Notify DP Scripts
caster.notifyQuestEventSkillFinished(_skill, target);
// On each repeat recharge shots before cast.
caster.rechargeShots(_skill.useSoulShot(), _skill.useSpiritShot(), false);
return true;
}
public static void callSkill(L2Character caster, L2Object target, Collection<L2Object> targets, Skill skill, L2ItemInstance item)
{
// Launch the magic skill in order to calculate its effects
try
{
// Check if the toggle skill effects are already in progress on the L2Character
if (skill.isToggle() && caster.isAffectedBySkill(skill.getId()))
{
return;
}
// Initial checks
for (L2Object obj : targets)
{
if ((obj == null) || !obj.isCharacter())
{
continue;
}
final L2Character creature = (L2Character) obj;
// Check raid monster/minion attack and check buffing characters who attack raid monsters. Raid is still affected by skills.
if (!Config.RAID_DISABLE_CURSE && creature.isRaid() && creature.giveRaidCurse() && (caster.getLevel() >= (creature.getLevel() + 9)))
{
if (skill.isBad() || ((creature.getTarget() == caster) && ((L2Attackable) creature).getAggroList().containsKey(caster)))
{
// Skills such as Summon Battle Scar too can trigger magic silence.
final CommonSkill curse = skill.isBad() ? CommonSkill.RAID_CURSE2 : CommonSkill.RAID_CURSE;
final Skill curseSkill = curse.getSkill();
if (curseSkill != null)
{
curseSkill.applyEffects(creature, caster);
}
}
}
// Static skills not trigger any chance skills
if (!skill.isStatic())
{
final L2Weapon activeWeapon = caster.getActiveWeaponItem();
// Launch weapon Special ability skill effect if available
if ((activeWeapon != null) && !creature.isDead())
{
activeWeapon.applyConditionalSkills(caster, creature, skill, ItemSkillType.ON_MAGIC_SKILL);
}
if (caster.hasTriggerSkills())
{
for (OptionsSkillHolder holder : caster.getTriggerSkills().values())
{
if ((skill.isMagic() && (holder.getSkillType() == OptionsSkillType.MAGIC)) || (skill.isPhysical() && (holder.getSkillType() == OptionsSkillType.ATTACK)))
{
if (Rnd.get(100) < holder.getChance())
{
triggerCast(caster, creature, holder.getSkill(), null, false);
}
}
}
}
}
}
// Launch the magic skill and calculate its effects
skill.activateSkill(caster, item, targets.toArray(new L2Object[0]));
final L2PcInstance player = caster.getActingPlayer();
if (player != null)
{
for (L2Object obj : targets)
{
if (!(obj instanceof L2Character))
{
continue;
}
if (skill.isBad())
{
if (obj.isPlayable())
{
// Update pvpflag.
player.updatePvPStatus((L2Character) obj);
if (obj.isSummon())
{
((L2Summon) obj).updateAndBroadcastStatus(1);
}
}
else if (obj.isAttackable())
{
// Add hate to the attackable, and put it in the attack list.
((L2Attackable) obj).addDamageHate(caster, 0, -skill.getEffectPoint());
((L2Character) obj).addAttackerToAttackByList(caster);
}
// notify target AI about the attack
if (((L2Character) obj).hasAI() && !skill.hasEffectType(L2EffectType.HATE))
{
((L2Character) obj).getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, caster);
}
}
else if (obj.isMonster() || (obj.isPlayable() && ((obj.getActingPlayer().getPvpFlag() > 0) || (obj.getActingPlayer().getReputation() < 0))))
{
// Supporting players or monsters result in pvpflag.
player.updatePvPStatus();
}
}
// Mobs in range 1000 see spell
L2World.getInstance().forEachVisibleObjectInRange(player, L2Npc.class, 1000, npcMob ->
{
EventDispatcher.getInstance().notifyEventAsync(new OnNpcSkillSee(npcMob, player, skill, caster.isSummon(), targets.toArray(new L2Object[0])), npcMob);
// On Skill See logic
if (npcMob.isAttackable())
{
final L2Attackable attackable = (L2Attackable) npcMob;
if (skill.getEffectPoint() > 0)
{
if (attackable.hasAI() && (attackable.getAI().getIntention() == AI_INTENTION_ATTACK))
{
final L2Object npcTarget = attackable.getTarget();
for (L2Object skillTarget : targets)
{
if ((npcTarget == skillTarget) || (npcMob == skillTarget))
{
final L2Character originalCaster = caster.isSummon() ? caster : player;
attackable.addDamageHate(originalCaster, 0, (skill.getEffectPoint() * 150) / (attackable.getLevel() + 7));
}
}
}
}
}
});
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, caster + " callSkill() failed.", e);
}
}
/**
* Stops this casting and cleans all cast parameters.<br>
* @param aborted if {@code true}, server will send packets to the player, notifying him that the skill has been aborted.
*/
public void stopCasting(boolean aborted)
{
// Cancel the task and unset it.
if (_task != null)
{
_task.cancel(false);
_task = null;
}
final L2Character caster = _caster.get();
final L2Object target = _target.get();
if (caster == null)
{
return;
}
caster.removeSkillCaster(_castingType);
if (caster.isChanneling())
{
caster.getSkillChannelizer().stopChanneling();
}
// If aborted, broadcast casting aborted.
if (aborted)
{
caster.broadcastPacket(new MagicSkillCanceld(caster.getObjectId())); // broadcast packet to stop animations client-side
caster.sendPacket(ActionFailed.get(_castingType)); // send an "action failed" packet to the caster
}
// Notify the AI of the L2Character with EVT_FINISH_CASTING
caster.getAI().notifyEvent(CtrlEvent.EVT_FINISH_CASTING);
// If there is a queued skill, launch it and wipe the queue.
if (caster.isPlayer())
{
final L2PcInstance currPlayer = caster.getActingPlayer();
final SkillUseHolder queuedSkill = currPlayer.getQueuedSkill();
if (queuedSkill != null)
{
ThreadPoolManager.getInstance().executeGeneral(() ->
{
currPlayer.setQueuedSkill(null, null, false, false);
currPlayer.useMagic(queuedSkill.getSkill(), queuedSkill.getItem(), queuedSkill.isCtrlPressed(), queuedSkill.isShiftPressed());
});
return;
}
}
// Attack target after skill use
// TODO: This shouldnt be here. If skill condition fail, you still go autoattack. This doesn't happen if skill is in cooldown though.
if ((_skill.nextActionIsAttack()) && (target != null) && (target != caster) && target.canBeAttacked())
{
if ((caster.getAI().getNextIntention() == null) || (caster.getAI().getNextIntention().getCtrlIntention() != CtrlIntention.AI_INTENTION_MOVE_TO))
{
caster.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
}
}
}
public static void triggerCast(L2Character activeChar, L2Character target, Skill skill)
{
triggerCast(activeChar, target, skill, null, true);
}
public static void triggerCast(L2Character activeChar, L2Object target, Skill skill, L2ItemInstance item, boolean ignoreTargetType)
{
try
{
if ((activeChar == null) || (skill == null))
{
return;
}
if (skill.checkCondition(activeChar, target))
{
if (activeChar.isSkillDisabled(skill))
{
return;
}
if (skill.getReuseDelay() > 0)
{
activeChar.disableSkill(skill, skill.getReuseDelay());
}
if (!ignoreTargetType)
{
final L2Object objTarget = skill.getTarget(activeChar, false, false, false);
if (objTarget.isCharacter())
{
target = objTarget;
}
}
final L2Object[] targets = skill.getTargetsAffected(activeChar, target).toArray(new L2Object[0]);
if (!skill.isNotBroadcastable())
{
activeChar.broadcastPacket(new MagicSkillUse(activeChar, target, skill.getDisplayId(), skill.getLevel(), 0, 0));
}
// Launch the magic skill and calculate its effects
skill.activateSkill(activeChar, item, targets);
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "Failed simultaneous cast: ", e);
}
}
/**
* @return the skill that is casting.
*/
public Skill getSkill()
{
return _skill;
}
/**
* @return the creature casting the skill.
*/
public L2Character getCaster()
{
return _caster.get();
}
/**
* @return the target this skill is being cast on.
*/
public L2Object getTarget()
{
return _target.get();
}
/**
* @return the item that has been used in this casting.
*/
public L2ItemInstance getItem()
{
return _item;
}
/**
* @return {@code true} if casting can be aborted through regular means such as cast break while being attacked or while cancelling target, {@code false} otherwise.
*/
public boolean canAbortCast()
{
return _targets == null; // When targets are allocated, that means skill is already launched, therefore cannot be aborted.
}
/**
* @return the type of this caster, which also defines the casting display bar on the player.
*/
public SkillCastingType getCastingType()
{
return _castingType;
}
public boolean isNormalFirstType()
{
return _castingType == SkillCastingType.NORMAL;
}
public boolean isNormalSecondType()
{
return _castingType == SkillCastingType.NORMAL_SECOND;
}
public boolean isAnyNormalType()
{
return (_castingType == SkillCastingType.NORMAL) || (_castingType == SkillCastingType.NORMAL_SECOND);
}
@Override
public String toString()
{
return super.toString() + " [caster: " + String.valueOf(_caster.get()) + " skill: " + String.valueOf(_skill) + " target: " + String.valueOf(_target.get()) + " type: " + String.valueOf(_castingType) + "]";
}
/**
* Checks general conditions for casting a skill through the regular casting type.
* @param caster the caster checked if can cast the given skill.
* @param skill the skill to be check if it can be casted by the given caster or not.
* @return {@code true} if the caster can proceed with casting the given skill, {@code false} otherwise.
*/
public static boolean checkUseConditions(L2Character caster, Skill skill)
{
return checkUseConditions(caster, skill, SkillCastingType.NORMAL);
}
/**
* Checks general conditions for casting a skill.
* @param caster the caster checked if can cast the given skill.
* @param skill the skill to be check if it can be casted by the given caster or not.
* @param castingType used to check if caster is currently casting this type of cast.
* @return {@code true} if the caster can proceed with casting the given skill, {@code false} otherwise.
*/
public static boolean checkUseConditions(L2Character caster, Skill skill, SkillCastingType castingType)
{
if (caster == null)
{
return false;
}
if ((skill == null) || caster.isSkillDisabled(skill) || (((skill.getFlyRadius() > 0) || (skill.getFlyType() != null)) && caster.isMovementDisabled()))
{
caster.sendPacket(ActionFailed.STATIC_PACKET);
return false;
}
final TerminateReturn term = EventDispatcher.getInstance().notifyEvent(new OnCreatureSkillUse(caster, skill, skill.isWithoutAction()), caster, TerminateReturn.class);
if ((term != null) && term.terminate())
{
caster.sendPacket(ActionFailed.STATIC_PACKET);
return false;
}
// Check if creature is already casting
if ((castingType != null) && caster.isCastingNow(castingType))
{
caster.sendPacket(ActionFailed.get(castingType));
return false;
}
// Check if the caster has enough MP
if (caster.getCurrentMp() < (caster.getStat().getMpConsume(skill) + caster.getStat().getMpInitialConsume(skill)))
{
caster.sendPacket(SystemMessageId.NOT_ENOUGH_MP);
caster.sendPacket(ActionFailed.STATIC_PACKET);
return false;
}
// Check if the caster has enough HP
if (caster.getCurrentHp() <= skill.getHpConsume())
{
caster.sendPacket(SystemMessageId.NOT_ENOUGH_HP);
caster.sendPacket(ActionFailed.STATIC_PACKET);
return false;
}
// Skill mute checks.
if (!skill.isStatic())
{
// Check if the skill is a magic spell and if the L2Character is not muted
if (skill.isMagic())
{
if (caster.isMuted())
{
caster.sendPacket(ActionFailed.STATIC_PACKET);
return false;
}
}
else if (caster.isPhysicalMuted()) // Check if the skill is physical and if the L2Character is not physical_muted
{
caster.sendPacket(ActionFailed.STATIC_PACKET);
return false;
}
}
// Check if the caster's weapon is limited to use only its own skills
final L2Weapon weapon = caster.getActiveWeaponItem();
if ((weapon != null) && weapon.useWeaponSkillsOnly() && !caster.canOverrideCond(PcCondOverride.SKILL_CONDITIONS))
{
final List<ItemSkillHolder> weaponSkills = weapon.getSkills(ItemSkillType.NORMAL);
if ((weaponSkills != null) && !weaponSkills.stream().anyMatch(sh -> sh.getSkillId() == skill.getId()))
{
caster.sendPacket(SystemMessageId.THAT_WEAPON_CANNOT_USE_ANY_OTHER_SKILL_EXCEPT_THE_WEAPON_S_SKILL);
return false;
}
}
// Check if the spell consumes an Item
// TODO: combine check and consume
if ((skill.getItemConsumeId() > 0) && (skill.getItemConsumeCount() > 0) && (caster.getInventory() != null))
{
// Get the L2ItemInstance consumed by the spell
final L2ItemInstance requiredItems = caster.getInventory().getItemByItemId(skill.getItemConsumeId());
if ((requiredItems == null) || (requiredItems.getCount() < skill.getItemConsumeCount()))
{
// Checked: when a summon skill failed, server show required consume item count
if (skill.hasEffectType(L2EffectType.SUMMON))
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SUMMONING_A_SERVITOR_COSTS_S2_S1);
sm.addItemName(skill.getItemConsumeId());
sm.addInt(skill.getItemConsumeCount());
caster.sendPacket(sm);
}
else
{
caster.sendPacket(SystemMessageId.THERE_ARE_NOT_ENOUGH_NECESSARY_ITEMS_TO_USE_THE_SKILL);
}
return false;
}
}
if (caster.isPlayer())
{
final L2PcInstance player = caster.getActingPlayer();
if (player.inObserverMode())
{
return false;
}
if (player.isInOlympiadMode() && skill.isBlockedInOlympiad())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_USE_THAT_SKILL_IN_A_OLYMPIAD_MATCH);
return false;
}
if (player.isInsideZone(ZoneId.SAYUNE))
{
player.sendPacket(SystemMessageId.YOU_CANNOT_USE_SKILLS_IN_THE_CORRESPONDING_REGION);
return false;
}
// Check if not in AirShip
if (player.isInAirShip() && !skill.hasEffectType(L2EffectType.REFUEL_AIRSHIP))
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_CANNOT_BE_USED_DUE_TO_UNSUITABLE_TERMS);
sm.addSkillName(skill);
player.sendPacket(sm);
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,42 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
/**
* @author Nik
*/
public enum SkillCastingType
{
SIMULTANEOUS(-1),
NORMAL(0),
NORMAL_SECOND(1),
BLUE(2),
GREEN(3),
RED(4);
private final int _clientBarId;
SkillCastingType(int clientBarId)
{
_clientBarId = clientBarId;
}
public int getClientBarId()
{
return _clientBarId;
}
}

View File

@@ -1,75 +1,75 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.l2jmobius.gameserver.model.actor.L2Character;
/**
* @author UnAfraid
*/
public final class SkillChannelized
{
private final Map<Integer, Map<Integer, L2Character>> _channelizers = new ConcurrentHashMap<>();
public void addChannelizer(int skillId, L2Character channelizer)
{
_channelizers.computeIfAbsent(skillId, k -> new ConcurrentHashMap<>()).put(channelizer.getObjectId(), channelizer);
}
public void removeChannelizer(int skillId, L2Character channelizer)
{
getChannelizers(skillId).remove(channelizer.getObjectId());
}
public int getChannerlizersSize(int skillId)
{
return getChannelizers(skillId).size();
}
public Map<Integer, L2Character> getChannelizers(int skillId)
{
return _channelizers.getOrDefault(skillId, Collections.emptyMap());
}
public void abortChannelization()
{
for (Map<Integer, L2Character> map : _channelizers.values())
{
for (L2Character channelizer : map.values())
{
channelizer.abortCast();
}
}
_channelizers.clear();
}
public boolean isChannelized()
{
for (Map<Integer, L2Character> map : _channelizers.values())
{
if (!map.isEmpty())
{
return true;
}
}
return false;
}
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.l2jmobius.gameserver.model.actor.L2Character;
/**
* @author UnAfraid
*/
public final class SkillChannelized
{
private final Map<Integer, Map<Integer, L2Character>> _channelizers = new ConcurrentHashMap<>();
public void addChannelizer(int skillId, L2Character channelizer)
{
_channelizers.computeIfAbsent(skillId, k -> new ConcurrentHashMap<>()).put(channelizer.getObjectId(), channelizer);
}
public void removeChannelizer(int skillId, L2Character channelizer)
{
getChannelizers(skillId).remove(channelizer.getObjectId());
}
public int getChannerlizersSize(int skillId)
{
return getChannelizers(skillId).size();
}
public Map<Integer, L2Character> getChannelizers(int skillId)
{
return _channelizers.getOrDefault(skillId, Collections.emptyMap());
}
public void abortChannelization()
{
for (Map<Integer, L2Character> map : _channelizers.values())
{
for (L2Character channelizer : map.values())
{
channelizer.abortCast();
}
}
_channelizers.clear();
}
public boolean isChannelized()
{
for (Map<Integer, L2Character> map : _channelizers.values())
{
if (!map.isEmpty())
{
return true;
}
}
return false;
}
}

View File

@@ -1,232 +1,243 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.datatables.SkillData;
import com.l2jmobius.gameserver.enums.ShotType;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillLaunched;
import com.l2jmobius.gameserver.util.Util;
/**
* Skill Channelizer implementation.
* @author UnAfraid
*/
public class SkillChannelizer implements Runnable
{
private static final Logger _log = Logger.getLogger(SkillChannelizer.class.getName());
private final L2Character _channelizer;
private List<L2Character> _channelized;
private Skill _skill;
private volatile ScheduledFuture<?> _task = null;
public SkillChannelizer(L2Character channelizer)
{
_channelizer = channelizer;
}
public L2Character getChannelizer()
{
return _channelizer;
}
public List<L2Character> getChannelized()
{
return _channelized;
}
public boolean hasChannelized()
{
return _channelized != null;
}
public void startChanneling(Skill skill)
{
// Verify for same status.
if (isChanneling())
{
_log.warning("Character: " + _channelizer + " is attempting to channel skill but he already does!");
return;
}
// Start channeling.
_skill = skill;
_task = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(this, skill.getChannelingTickInitialDelay(), skill.getChannelingTickInterval());
}
public void stopChanneling()
{
// Verify for same status.
if (!isChanneling())
{
_log.warning("Character: " + _channelizer + " is attempting to stop channel skill but he does not!");
return;
}
// Cancel the task and unset it.
_task.cancel(true);
_task = null;
// Cancel target channelization and unset it.
if (_channelized != null)
{
for (L2Character chars : _channelized)
{
chars.getSkillChannelized().removeChannelizer(_skill.getChannelingSkillId(), getChannelizer());
}
_channelized = null;
}
// unset skill.
_skill = null;
}
public Skill getSkill()
{
return _skill;
}
public boolean isChanneling()
{
return _task != null;
}
@Override
public void run()
{
if (!isChanneling() || (_skill == null))
{
return;
}
try
{
if (_skill.getMpPerChanneling() > 0)
{
// Validate mana per tick.
if (_channelizer.getCurrentMp() < _skill.getMpPerChanneling())
{
if (_channelizer.isPlayer())
{
_channelizer.sendPacket(SystemMessageId.YOUR_SKILL_WAS_DEACTIVATED_DUE_TO_LACK_OF_MP);
}
_channelizer.abortCast();
return;
}
// Reduce mana per tick
_channelizer.reduceCurrentMp(_skill.getMpPerChanneling());
}
// Apply channeling skills on the targets.
if (_skill.getChannelingSkillId() > 0)
{
final Skill baseSkill = SkillData.getInstance().getSkill(_skill.getChannelingSkillId(), 1);
if (baseSkill == null)
{
_log.warning(getClass().getSimpleName() + ": skill " + _skill + " couldn't find effect id skill: " + _skill.getChannelingSkillId() + " !");
_channelizer.abortCast();
return;
}
final List<L2Character> targetList = new ArrayList<>();
for (L2Object chars : _skill.getTargetList(_channelizer))
{
if (chars.isCharacter())
{
targetList.add((L2Character) chars);
((L2Character) chars).getSkillChannelized().addChannelizer(_skill.getChannelingSkillId(), getChannelizer());
}
}
if (targetList.isEmpty())
{
return;
}
_channelized = targetList;
for (L2Character character : _channelized)
{
if (!Util.checkIfInRange(_skill.getEffectRange(), _channelizer, character, true))
{
continue;
}
else if (!GeoData.getInstance().canSeeTarget(_channelizer, character))
{
continue;
}
else
{
final int maxSkillLevel = SkillData.getInstance().getMaxLevel(_skill.getChannelingSkillId());
final int skillLevel = Math.min(character.getSkillChannelized().getChannerlizersSize(_skill.getChannelingSkillId()), maxSkillLevel);
final BuffInfo info = character.getEffectList().getBuffInfoBySkillId(_skill.getChannelingSkillId());
if ((info == null) || (info.getSkill().getLevel() < skillLevel))
{
final Skill skill = SkillData.getInstance().getSkill(_skill.getChannelingSkillId(), skillLevel);
if (skill == null)
{
_log.warning(getClass().getSimpleName() + ": Non existent channeling skill requested: " + _skill);
_channelizer.abortCast();
return;
}
// Update PvP status
if (character.isPlayable() && getChannelizer().isPlayer() && skill.isBad())
{
((L2PcInstance) getChannelizer()).updatePvPStatus(character);
}
skill.applyEffects(getChannelizer(), character);
// Reduce shots.
if (_skill.useSpiritShot())
{
_channelizer.setChargedShot(_channelizer.isChargedShot(ShotType.BLESSED_SPIRITSHOTS) ? ShotType.BLESSED_SPIRITSHOTS : ShotType.SPIRITSHOTS, false);
}
else
{
_channelizer.setChargedShot(ShotType.SOULSHOTS, false);
}
// Shots are re-charged every cast.
_channelizer.rechargeShots(_skill.useSoulShot(), _skill.useSpiritShot());
}
_channelizer.broadcastPacket(new MagicSkillLaunched(_channelizer, _skill.getId(), _skill.getLevel(), character));
}
}
}
}
catch (Exception e)
{
_log.warning("Error while channelizing skill: " + _skill + " channelizer: " + _channelizer + " channelized: " + _channelized + "; " + e.getMessage());
}
}
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.enums.ShotType;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillLaunched;
import com.l2jmobius.gameserver.util.Util;
/**
* Skill Channelizer implementation.
* @author UnAfraid
*/
public class SkillChannelizer implements Runnable
{
private static final Logger _log = Logger.getLogger(SkillChannelizer.class.getName());
private final L2Character _channelizer;
private List<L2Character> _channelized;
private Skill _skill;
private volatile ScheduledFuture<?> _task = null;
public SkillChannelizer(L2Character channelizer)
{
_channelizer = channelizer;
}
public L2Character getChannelizer()
{
return _channelizer;
}
public List<L2Character> getChannelized()
{
return _channelized;
}
public boolean hasChannelized()
{
return _channelized != null;
}
public void startChanneling(Skill skill)
{
// Verify for same status.
if (isChanneling())
{
_log.warning("Character: " + toString() + " is attempting to channel skill but he already does!");
return;
}
// Start channeling.
_skill = skill;
_task = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(this, skill.getChannelingTickInitialDelay(), skill.getChannelingTickInterval());
}
public void stopChanneling()
{
// Verify for same status.
if (!isChanneling())
{
_log.warning("Character: " + toString() + " is attempting to stop channel skill but he does not!");
return;
}
// Cancel the task and unset it.
_task.cancel(false);
_task = null;
// Cancel target channelization and unset it.
if (_channelized != null)
{
for (L2Character chars : _channelized)
{
chars.getSkillChannelized().removeChannelizer(_skill.getChannelingSkillId(), getChannelizer());
}
_channelized = null;
}
// unset skill.
_skill = null;
}
public Skill getSkill()
{
return _skill;
}
public boolean isChanneling()
{
return _task != null;
}
@Override
public void run()
{
if (!isChanneling())
{
return;
}
final Skill skill = _skill;
List<L2Character> channelized = _channelized;
try
{
if (skill.getMpPerChanneling() > 0)
{
// Validate mana per tick.
if (_channelizer.getCurrentMp() < skill.getMpPerChanneling())
{
if (_channelizer.isPlayer())
{
_channelizer.sendPacket(SystemMessageId.YOUR_SKILL_WAS_DEACTIVATED_DUE_TO_LACK_OF_MP);
}
_channelizer.abortCast();
return;
}
// Reduce mana per tick
_channelizer.reduceCurrentMp(skill.getMpPerChanneling());
}
// Apply channeling skills on the targets.
if (skill.getChannelingSkillId() > 0)
{
final Skill baseSkill = SkillData.getInstance().getSkill(skill.getChannelingSkillId(), 1);
if (baseSkill == null)
{
_log.warning(getClass().getSimpleName() + ": skill " + skill + " couldn't find effect id skill: " + skill.getChannelingSkillId() + " !");
_channelizer.abortCast();
return;
}
final List<L2Character> targetList = new ArrayList<>();
final L2Object target = skill.getTarget(_channelizer, false, false, false);
if (target != null)
{
skill.forEachTargetAffected(_channelizer, target, o ->
{
if (o.isCharacter())
{
targetList.add((L2Character) o);
((L2Character) o).getSkillChannelized().addChannelizer(skill.getChannelingSkillId(), getChannelizer());
}
});
}
if (targetList.isEmpty())
{
return;
}
channelized = targetList;
for (L2Character character : channelized)
{
if (!Util.checkIfInRange(skill.getEffectRange(), _channelizer, character, true))
{
continue;
}
else if (!GeoData.getInstance().canSeeTarget(_channelizer, character))
{
continue;
}
else
{
final int maxSkillLevel = SkillData.getInstance().getMaxLevel(skill.getChannelingSkillId());
final int skillLevel = Math.min(character.getSkillChannelized().getChannerlizersSize(skill.getChannelingSkillId()), maxSkillLevel);
final BuffInfo info = character.getEffectList().getBuffInfoBySkillId(skill.getChannelingSkillId());
if ((info == null) || (info.getSkill().getLevel() < skillLevel))
{
final Skill channeledSkill = SkillData.getInstance().getSkill(skill.getChannelingSkillId(), skillLevel);
if (channeledSkill == null)
{
_log.warning(getClass().getSimpleName() + ": Non existent channeling skill requested: " + skill);
_channelizer.abortCast();
return;
}
// Update PvP status
if (character.isPlayable() && getChannelizer().isPlayer())
{
((L2PcInstance) getChannelizer()).updatePvPStatus(character);
}
// Be warned, this method has the possibility to call doDie->abortCast->stopChanneling method. Variable cache above try"+ +" is used in this case to avoid NPEs.
channeledSkill.applyEffects(getChannelizer(), character);
// Reduce shots.
if (skill.useSpiritShot())
{
_channelizer.setChargedShot(_channelizer.isChargedShot(ShotType.BLESSED_SPIRITSHOTS) ? ShotType.BLESSED_SPIRITSHOTS : ShotType.SPIRITSHOTS, false);
}
else
{
_channelizer.setChargedShot(ShotType.SOULSHOTS, false);
}
// Shots are re-charged every cast.
_channelizer.rechargeShots(skill.useSoulShot(), skill.useSpiritShot(), false);
}
if (!skill.isToggle())
{
_channelizer.broadcastPacket(new MagicSkillLaunched(_channelizer, skill.getId(), skill.getLevel(), SkillCastingType.NORMAL, character));
}
}
}
}
}
catch (Exception e)
{
_log.log(Level.WARNING, "Error while channelizing skill: " + skill + " channelizer: " + _channelizer + " channelized: " + channelized, e);
}
}
}

View File

@@ -0,0 +1,55 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author NosBit
*/
public enum SkillConditionScope
{
GENERAL("conditions"),
TARGET("targetConditions"),
PASSIVE("passiveConditions");
private static final Map<String, SkillConditionScope> XML_NODE_NAME_TO_SKILL_CONDITION_SCOPE;
static
{
XML_NODE_NAME_TO_SKILL_CONDITION_SCOPE = Arrays.stream(values()).collect(Collectors.toMap(e -> e.getXmlNodeName(), e -> e));
}
private final String _xmlNodeName;
SkillConditionScope(String xmlNodeName)
{
_xmlNodeName = xmlNodeName;
}
public String getXmlNodeName()
{
return _xmlNodeName;
}
public static SkillConditionScope findByXmlNodeName(String xmlNodeName)
{
return XML_NODE_NAME_TO_SKILL_CONDITION_SCOPE.get(xmlNodeName);
}
}

View File

@@ -1,180 +1,237 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
/**
* This enum class holds the skill operative types:
* <ul>
* <li>ACTIVE_INSTANT</li>
* <li>ACTIVE_CONTINUOUS</li>
* <li>ACTIVE_WITH_TRIGGER</li>
* <li>SPECIAL_HERB</li>
* <li>CHANNELING_INSTANT</li>
* <li>CHANNELING_CONTINUOUS</li>
* <li>DIRECTIONAL_INSTANT</li>
* <li>DIRECTIONAL_CONTINUOUS</li>
* <li>PASSIVE</li>
* <li>TOGGLE</li>
* </ul>
* @author Zoey76
*/
public enum SkillOperateType
{
/**
* Active Skill with "Instant Effect" (for example damage skills heal/pdam/mdam/cpdam skills).
*/
ACTIVE_INSTANT,
/**
* Active Skill with "Continuous effect + Instant effect" (for example buff/debuff or damage/heal over time skills).
*/
ACTIVE_CONTINUOUS,
/**
* Active Skill with "Instant effect + Continuous effect"
*/
ACTIVE_WITH_TRIGGER,
/**
* Active Skill with "Instant effect + ?" used for special event herb (itemId 20903, skillId 22158).
*/
SPECIAL_HERB,
/**
* Continuous Active Skill with "instant effect" (instant effect casted by ticks).
*/
CHANNELING_INSTANT,
/**
* Continuous Active Skill with "continuous effect" (continuous effect casted by ticks).
*/
CHANNELING_CONTINUOUS,
/**
* Directional Active Skill with "Charge/Rush instant effect".
*/
DIRECTIONAL_INSTANT,
/**
* Directional Active Skill with "Charge/Rush Continuous effect".
*/
DIRECTIONAL_CONTINUOUS,
/**
* Passive Skill.
*/
PASSIVE,
/**
* Toggle Skill.
*/
TOGGLE;
/**
* Verifies if the operative type correspond to an active skill.
* @return {@code true} if the operative skill type is active, {@code false} otherwise
*/
public boolean isActive()
{
switch (this)
{
case ACTIVE_INSTANT:
case ACTIVE_CONTINUOUS:
case ACTIVE_WITH_TRIGGER:
case CHANNELING_INSTANT:
case CHANNELING_CONTINUOUS:
case DIRECTIONAL_INSTANT:
case DIRECTIONAL_CONTINUOUS:
case SPECIAL_HERB:
{
return true;
}
default:
{
return false;
}
}
}
/**
* Verifies if the operative type correspond to a continuous skill.
* @return {@code true} if the operative skill type is continuous, {@code false} otherwise
*/
public boolean isContinuous()
{
switch (this)
{
case ACTIVE_CONTINUOUS:
case DIRECTIONAL_CONTINUOUS:
case SPECIAL_HERB:
{
return true;
}
default:
{
return false;
}
}
}
/**
* Verifies if the operative type correspond to a continuous skill.
* @return {@code true} if the operative skill type is continuous, {@code false} otherwise
*/
public boolean isSelfContinuous()
{
return this == ACTIVE_WITH_TRIGGER;
}
/**
* Verifies if the operative type correspond to a passive skill.
* @return {@code true} if the operative skill type is passive, {@code false} otherwise
*/
public boolean isPassive()
{
return this == PASSIVE;
}
/**
* Verifies if the operative type correspond to a toggle skill.
* @return {@code true} if the operative skill type is toggle, {@code false} otherwise
*/
public boolean isToggle()
{
return this == TOGGLE;
}
/**
* Verifies if the operative type correspond to a channeling skill.
* @return {@code true} if the operative skill type is channeling, {@code false} otherwise
*/
public boolean isChanneling()
{
switch (this)
{
case CHANNELING_INSTANT:
case CHANNELING_CONTINUOUS:
{
return true;
}
default:
{
return false;
}
}
}
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills;
/**
* This enum class holds the skill operative types:
* <ul>
* <li>A1</li>
* <li>A2</li>
* <li>A3</li>
* <li>A4</li>
* <li>CA1</li>
* <li>CA5</li>
* <li>DA1</li>
* <li>DA2</li>
* <li>P</li>
* <li>T</li>
* </ul>
* @author Zoey76
*/
public enum SkillOperateType
{
/**
* Active Skill with "Instant Effect" (for example damage skills heal/pdam/mdam/cpdam skills).
*/
A1,
/**
* Active Skill with "Continuous effect + Instant effect" (for example buff/debuff or damage/heal over time skills).
*/
A2,
/**
* Active Skill with "Instant effect + Continuous effect"
*/
A3,
/**
* Active Skill with "Instant effect + ?" used for special event herb.
*/
A4,
/**
* Aura Active Skill
*/
A5,
/**
* Synergy Active Skill
*/
A6,
/**
* Continuous Active Skill with "instant effect" (instant effect casted by ticks).
*/
CA1,
/**
* ?
*/
CA2,
/**
* Continuous Active Skill with "continuous effect" (continuous effect casted by ticks).
*/
CA5,
/**
* Directional Active Skill with "Charge/Rush instant effect".
*/
DA1,
/**
* Directional Active Skill with "Charge/Rush Continuous effect".
*/
DA2,
/**
* Directional Active Skill with Blink effect
*/
DA3,
/**
* Passive Skill.
*/
P,
/**
* Toggle Skill.
*/
T,
/**
* Toggle Skill with Group.
*/
TG,
/**
* Aura Skill.
*/
AU;
/**
* Verifies if the operative type correspond to an active skill.
* @return {@code true} if the operative skill type is active, {@code false} otherwise
*/
public boolean isActive()
{
switch (this)
{
case A1:
case A2:
case A3:
case A4:
case A5:
case A6:
case CA1:
case CA5:
case DA1:
case DA2:
return true;
default:
return false;
}
}
/**
* Verifies if the operative type correspond to a continuous skill.
* @return {@code true} if the operative skill type is continuous, {@code false} otherwise
*/
public boolean isContinuous()
{
switch (this)
{
case A2:
case A4:
case A5:
case A6:
case DA2:
return true;
default:
return false;
}
}
/**
* Verifies if the operative type correspond to a continuous skill.
* @return {@code true} if the operative skill type is continuous, {@code false} otherwise
*/
public boolean isSelfContinuous()
{
return (this == A3);
}
/**
* Verifies if the operative type correspond to a passive skill.
* @return {@code true} if the operative skill type is passive, {@code false} otherwise
*/
public boolean isPassive()
{
return (this == P);
}
/**
* Verifies if the operative type correspond to a toggle skill.
* @return {@code true} if the operative skill type is toggle, {@code false} otherwise
*/
public boolean isToggle()
{
return (this == T) || (this == TG) || (this == AU);
}
/**
* Verifies if the operative type correspond to a active aura skill.
* @return {@code true} if the operative skill type is active aura, {@code false} otherwise
*/
public boolean isAura()
{
return (this == A5) || (this == A6) || (this == AU);
}
/**
* @return {@code true} if the operate type skill type should not send messeges for start/finish, {@code false} otherwise
*/
public boolean isHidingMesseges()
{
return (this == A5) || (this == A6) || (this == TG);
}
/**
* @return {@code true} if the operate type skill type should not be broadcasted as MagicSkillUse, MagicSkillLaunched, {@code false} otherwise
*/
public boolean isNotBroadcastable()
{
return (this == A5) || (this == A6) || (this == AU) || (this == TG);
}
/**
* Verifies if the operative type correspond to a channeling skill.
* @return {@code true} if the operative skill type is channeling, {@code false} otherwise
*/
public boolean isChanneling()
{
switch (this)
{
case CA1:
case CA2:
case CA5:
return true;
default:
return false;
}
}
/**
* Verifies if the operative type correspond to a synergy skill.
* @return {@code true} if the operative skill type is synergy, {@code false} otherwise
*/
public boolean isSynergy()
{
return (this == A6);
}
}

View File

@@ -1,35 +1,37 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills.targets;
/**
* Affect object enumerated.
* @author Zoey76
*/
public enum AffectObject
{
ALL,
CLAN,
FRIEND,
HIDDEN_PLACE,
INVISIBLE,
NOE,
NOT_FRIEND,
OBJECT_DEAD_NPC_BODY,
UNDEAD_REAL_ENEMY,
WYVERN_OBJECT
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills.targets;
/**
* Affect object enumerated.
* @author Zoey76
*/
public enum AffectObject
{
ALL,
CLAN,
FRIEND,
FRIEND_PC,
HIDDEN_PLACE,
INVISIBLE,
NOE,
NOT_FRIEND,
NOT_FRIEND_PC,
OBJECT_DEAD_NPC_BODY,
UNDEAD_REAL_ENEMY,
WYVERN_OBJECT
}

View File

@@ -1,55 +1,67 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills.targets;
/**
* Affect scope enumerated.
* @author Zoey76
*/
public enum AffectScope
{
/** Affects Valakas. */
BALAKAS_SCOPE,
/** Affects dead clan mates. */
DEAD_PLEDGE,
/** Affects fan area. */
FAN,
/** Affects nothing. */
NONE,
/** Affects party members. */
PARTY,
/** Affects party and clan mates. */
PARTY_PLEDGE,
/** Affects clan mates. */
PLEDGE,
/** Affects point blank targets, using caster as point of origin. */
POINT_BLANK,
/** Affects ranged targets, using selected target as point of origin. */
RANGE,
/** Affects ranged targets, using selected target as point of origin. */
RING_RANGE,
/** Affects a single target. */
SINGLE,
/** Affects targets inside an square area, using selected target as point of origin. */
SQUARE,
/** Affects targets inside an square area, using caster as point of origin. */
SQUARE_PB,
/** Affects static object targets. */
STATIC_OBJECT_SCOPE,
/** Affects wyverns. */
WYVERN_SCOPE
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills.targets;
/**
* Affect scope enumerated.
* @author Zoey76
*/
public enum AffectScope
{
/** Affects Valakas. */
BALAKAS_SCOPE,
/** Affects dead clan mates. */
DEAD_PLEDGE,
/** Affects dead union (Command Channel?) members. */
DEAD_UNION,
/** Affects fan area. */
FAN,
/** Affects fan area, using caster as point of origin.. */
FAN_PB,
/** Affects nothing. */
NONE,
/** Affects party members. */
PARTY,
/** Affects dead party members. */
DEAD_PARTY,
/** Affects party and clan mates. */
PARTY_PLEDGE,
/** Affects dead party and clan members. */
DEAD_PARTY_PLEDGE,
/** Affects clan mates. */
PLEDGE,
/** Affects point blank targets, using caster as point of origin. */
POINT_BLANK,
/** Affects ranged targets, using selected target as point of origin. */
RANGE,
/** Affects ranged targets, using selected target as point of origin sorted by lowest to highest HP. */
RANGE_SORT_BY_HP,
/** Affects targets in donut shaped area, using caster as point of origin. */
RING_RANGE,
/** Affects a single target. */
SINGLE,
/** Affects targets inside an square area, using selected target as point of origin. */
SQUARE,
/** Affects targets inside an square area, using caster as point of origin. */
SQUARE_PB,
/** Affects static object targets. */
STATIC_OBJECT_SCOPE,
/** Affects all summons except master. */
SUMMON_EXCEPT_MASTER,
/** Affects wyverns. */
WYVERN_SCOPE
}

View File

@@ -1,63 +1,65 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills.targets;
/**
* @author Zoey76
*/
public enum L2TargetType
{
AREA,
AREA_CORPSE_MOB,
AREA_FRIENDLY,
AREA_SUMMON,
AREA_UNDEAD,
AURA,
AURA_CORPSE_MOB,
AURA_FRIENDLY,
BEHIND_AREA,
BEHIND_AURA,
CLAN,
CLAN_MEMBER,
COMMAND_CHANNEL,
CORPSE,
CORPSE_CLAN,
CORPSE_MOB,
ENEMY_SUMMON,
FLAGPOLE,
FRONT_AREA,
FRONT_AURA,
GROUND,
HOLY,
NONE,
ONE,
ONE_FRIENDLY,
OWNER_PET,
PARTY,
PARTY_CLAN,
PARTY_MEMBER,
PARTY_NOTME,
PARTY_OTHER,
PC_BODY,
PET,
SELF,
SERVITOR,
SUMMON,
TARGET_PARTY,
UNDEAD,
UNLOCKABLE
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills.targets;
/**
* @author Zoey76
*/
public enum L2TargetType
{
AREA,
AREA_CORPSE_MOB,
AREA_FRIENDLY,
AREA_SUMMON,
AREA_UNDEAD,
AURA,
AURA_CORPSE_MOB,
AURA_FRIENDLY,
BEHIND_AREA,
BEHIND_AURA,
CLAN,
CLAN_MEMBER,
COMMAND_CHANNEL,
CORPSE,
CORPSE_CLAN,
CORPSE_PARTY,
CORPSE_PARTY_CLAN,
CORPSE_MOB,
ENEMY_SUMMON,
FLAGPOLE,
FRONT_AREA,
FRONT_AURA,
GROUND,
HOLY,
NONE,
ONE,
ONE_FRIENDLY,
OWNER_PET,
PARTY,
PARTY_CLAN,
PARTY_MEMBER,
PARTY_NOTME,
PARTY_OTHER,
PC_BODY,
PET,
SELF,
SERVITOR,
SUMMON,
TARGET_PARTY,
UNDEAD,
UNLOCKABLE
}

View File

@@ -1,61 +1,65 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills.targets;
/**
* Target type enumerated.
* @author Zoey76
*/
public enum TargetType
{
/** Advance Head Quarters (Outposts). */
ADVANCE_BASE,
/** Enemies in high terrain or protected by castle walls and doors. */
ARTILLERY,
/** Doors or treasure chests. */
DOOR_TREASURE,
/** Any enemies (included allies). */
ENEMY,
/** Friendly. */
ENEMY_NOT,
/** Only enemies (not included allies). */
ENEMY_ONLY,
/** Fortress's Flagpole. */
FORTRESS_FLAGPOLE,
/** Ground. */
GROUND,
/** Holy Artifacts from sieges. */
HOLYTHING,
/** Items. */
ITEM,
/** Nothing. */
NONE,
/** NPC corpses. */
NPC_BODY,
/** Others, except caster. */
OTHERS,
/** Player corpses. */
PC_BODY,
/** Self. */
SELF,
/** Servitor, not pet. */
SUMMON,
/** Anything targetable. */
TARGET,
/** Wyverns. */
WYVERN_TARGET;
}
/*
* This file is part of the L2J Mobius project.
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.skills.targets;
/**
* Target type enumerated.
* @author Zoey76
*/
public enum TargetType
{
/** Advance Head Quarters (Outposts). */
ADVANCE_BASE,
/** Enemies in high terrain or protected by castle walls and doors. */
ARTILLERY,
/** Doors or treasure chests. */
DOOR_TREASURE,
/** Any enemies (included allies). */
ENEMY,
/** Friendly. */
ENEMY_NOT,
/** Only enemies (not included allies). */
ENEMY_ONLY,
/** Fortress's Flagpole. */
FORTRESS_FLAGPOLE,
/** Ground. */
GROUND,
/** Holy Artifacts from sieges. */
HOLYTHING,
/** Items. */
ITEM,
/** Nothing. */
NONE,
/** NPC corpses. */
NPC_BODY,
/** Others, except caster. */
OTHERS,
/** Player corpses. */
PC_BODY,
/** Self. */
SELF,
/** Servitor or pet. */
SUMMON,
/** Anything targetable. */
TARGET,
/** Wyverns. */
WYVERN_TARGET,
/** Mentee's Mentor. */
MY_MENTOR,
/** Me or my party (if any). Seen in aura skills. */
MY_PARTY,
}